OpenID-Federation-WK-Binding September 2026
Hardt Standards Track [Page]
Workgroup:
OpenID Connect
Published:
Author:
D. Hardt
Hellō

OpenID Federation Well-Known Binding 1.0

Abstract

This specification binds an OpenID Federation 1.1 Entity to the documents it publishes at well-known URIs, and to the JSON Web Key Sets those documents reference. The Entity signs digests of these documents in its own Entity Configuration. A verifier that validates the Entity's Trust Chain can then authenticate them, including the protocol keys in the JSON Web Key Sets, without relying only on DNS or the Web PKI. The documents are served unchanged, and only the Entity re-signs when they change. For a JWK Set, this is an alternative to signed_jwks_uri that leaves the JWK Set as plain JSON. The mechanism applies to any well-known URI, with no per-protocol profile.

Optionally, a well-known document that is a JSON object can also state which of the Entity's Trust Marks apply to the role it describes, and which Trust Marks the Entity requires of its counterparties.

Notices

[OpenID Foundation copyright and IPR notices, per OIDF specification boilerplate.]

▲

Table of Contents

1. Introduction

Many protocols have a server publish metadata at a well-known URI [RFC8615]. Examples are OAuth 2.0 Authorization Server Metadata [RFC8414], OAuth 2.0 Protected Resource Metadata [RFC9728], and the AAuth Protocol [I-D.hardt-oauth-aauth-protocol]. The metadata's jwks_uri member locates the JSON Web Key Set (JWK Set) that holds the server's protocol keys, such as the keys it signs tokens with. Some protocols publish the JWK Set itself at a well-known URI, such as the HTTP Message Signatures Directory of Web Bot Auth [I-D.ietf-webbotauth-httpsig-protocol]. Both documents are fetched over HTTPS, so the binding between the server's identifier and its protocol keys rests on DNS and the Web PKI: whoever can answer for the origin can publish keys for it.

That is sufficient for many deployments. It is not sufficient where the Web PKI is not an acceptable root of trust for protocol keys, or where a party needs to know more than "this origin published these keys", for example that the origin belongs to an accredited payment institution.

OpenID Federation 1.1 [OpenID.Federation] binds an Entity's Federation Entity Keys to its Entity Identifier through a Trust Chain, independently of the Web PKI. It expresses accreditation of an Entity by a third party as Trust Marks. It binds a JWK Set inline as jwks, or as a signed JWT at signed_jwks_uri ([OpenID.Federation], Section 5.2.1). For OpenID Connect, OpenID Federation for OpenID Connect 1.1 [OpenID.Federation.Connect] defines a different binding for metadata: OpenID Provider and Relying Party metadata is carried in Entity Statements, and metadata policies cascade down the Trust Chain to produce the metadata a verifier uses ([OpenID.Federation], Section 6.1). Neither authenticates documents that a protocol publishes at its own well-known URI, or a JWK Set served as plain JSON.

This specification provides that binding. An Entity lists, in a well_known_bindings claim in its Entity Configuration, digests of its well-known documents and of the JWK Sets they reference by jwks_uri. The Entity signs these digests with its Federation Entity Key, which the Trust Chain binds to its Entity Identifier. A verifier that validates the Trust Chain and checks the digests has authenticated the Entity's protocol metadata and protocol keys. It relies on DNS and the Web PKI only for transport and as a redundant check.

The binding needs no Trust Marks. As an optional addition, this specification defines two members with which a well-known document that is a JSON object states which of the Entity's Trust Marks apply to the role it describes, and which Trust Marks the Entity requires of the Entities it deals with (Section 8). The document's digest authenticates these statements.

1.1. Non-Goals

  • Not a change to OpenID Federation. This specification defines one Entity Configuration claim, well_known_bindings, and nothing else inside Entity Statements.

  • Not a change to the protocols whose documents are bound. Documents are served unchanged at their existing locations, and each protocol processes them as before, including its checks on identifier members such as issuer. A verifier adds the checks in Section 6, and takes any member that Resolved Metadata carries from Resolved Metadata rather than from the document (Section 6.2). The only additions to documents are the two optional Trust Mark members.

  • Not Trust Mark issuance. Which parties issue which Trust Marks, what a Trust Mark certifies, and how an Entity obtains one are properties of each federation. OpenID Federation already expresses which issuers are recognized for which types (trust_mark_issuers, trust_mark_owners).

  • Not mandatory. A verifier decides by its own policy whether to require federation verification of a given peer.

2. Conventions and Definitions

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

3. Terminology

Terms defined in [OpenID.Federation] are used with the same meaning, in particular Entity, Entity Identifier, Entity Type, Entity Statement, Entity Configuration, Subordinate Statement, Trust Anchor, Trust Chain, Trust Mark, Trust Mark Issuer, Federation Entity Keys, and Resolved Metadata.

This specification also uses:

4. Overview

OpenID Federation defines how a verifier resolves and validates the Entity's Trust Chain ([OpenID.Federation], Section 10). The figure shows that as one step. The verifier fetches the covered document and the Entity Configuration together, and dereferences jwks_uri only after the covered document's digest matches and, where its policy requires federation verification, after the Trust Chain is validated (Section 6).

Verifier                               Entity
                                   entity.example
   |                                      |
   | GET /.well-known/<suffix>            |
   |------------------------------------->|
   | GET /.well-known/openid-federation   |
   |------------------------------------->|
   |  covered document                    |
   |<-------------------------------------|
   |  Entity Configuration                |
   |<-------------------------------------|
   |                                      |
   +- check covered document digest       |
   +- validate Trust Chain                |
   |                                      |
   | GET jwks_uri                         |
   |------------------------------------->|
   |  JWK Set                             |
   |<-------------------------------------|
   |                                      |
   +- check JWK Set digest                |
   +- check Trust Marks (optional)        |
Figure 1: Verifying a covered document and its JWK Set
Table 1
Statement or document Signed by Binds
Trust Chain Superiors, up to the Trust Anchor Entity Identifier to the Entity's Federation Entity Keys
Entity Configuration Entity's Federation Entity Key Digests of covered documents and JWK Sets
Covered document Bound by digest Protocol metadata, including jwks_uri
JWK Set at jwks_uri Bound by digest Protocol keys

The Entity signs the digests itself. Updating a covered document or rotating a protocol key therefore requires only that the Entity re-sign its own Entity Configuration. No Superior is involved.

5. Well-Known Bindings Claim

An Entity that uses this specification includes the following claim in its Entity Configuration. Like the claims in [OpenID.Federation], Section 3.1.2, it does not appear in Subordinate Statements, and a verifier ignores it there.

Implementations MUST support sha-256.

A covered document or JWK Set matches if its digest equals any element of its array, digests or jwks_digests. An array has more than one element only while that covered document or JWK Set is being replaced (Section 7).

Other specifications MAY define additional members of a well_known_bindings member value, for example digests of the image at a covered document's logo_uri. A member holding the digests of the document at a URL-valued member of the covered document is named for that member, with a trailing _uri removed and _digests appended: jwks_uri gives jwks_digests, and logo_uri gives logo_digests. A verifier ignores members it does not understand.

The Entity SHOULD NOT list well_known_bindings in the crit claim ([OpenID.Federation], Section 3.1.1), so that verifiers that do not implement this specification can still use its Entity Configuration.

The Entity Configuration still declares the Entity's Entity Types in its metadata claim, and every Entity has at least one ([OpenID.Federation], Sections 1.2 and 3.1.1). An Entity whose protocol has no Entity Type, such as an AAuth server or a Web Bot Auth agent, can declare federation_entity ([OpenID.Federation], Section 5.1.1).

An Entity that covers a document under this specification MAY declare Entity Type metadata that omits the members the covered document carries, including members its protocol's own metadata specification makes REQUIRED, and MAY declare an empty Entity Type metadata object. The covered document is where a verifier under this specification reads those members. A verifier MUST NOT reject an Entity Configuration because its Entity Type metadata omits such a member (Section 6.2).

This does not change how metadata_policy applies ([OpenID.Federation], Section 6.1). Where a metadata_policy in the Trust Chain marks a member essential ([OpenID.Federation], Section 6.1.3.1.7), the Entity MUST carry that member in its Entity Type metadata, and Resolved Metadata governs it (Section 6.2). The permission to omit, and the verifier's MUST NOT, cover only members that no metadata policy in the Trust Chain requires.

Example, for the authorization server in Appendix A.1:

"well_known_bindings": {
  "oauth-authorization-server": {
    "digests": [
      "O-YmLY31Z3ljOBWYLt1JjjI0xbOMNA2HVuGDeHwYJAo"
    ],
    "jwks_digests": [
      "HRb-DHuBwopK4jeYA9XkP7OPK_u7kxeth9NSptaj8r4"
    ]
  }
}

Appendix A has examples for other well-known documents.

5.1. Digest Computation

A digest is computed over the content of the HTTP response that delivered the document, after removing any content codings ([RFC9110], Section 8.4). The input is the exact octets, with no parsing, canonicalization, or re-serialization. The hash algorithm is the entry's digest_alg. The digest is the base64url encoding of the hash output without padding ([RFC7515], Section 2).

While a digest is listed, the Entity MUST serve the document with the same octets on every request, whatever the requester or the result of content negotiation. An intermediary that transforms content, for example by minification or re-serialization, causes verification to fail. The Entity SHOULD serve covered documents and JWK Sets with Cache-Control: no-transform ([RFC9111], Section 5.2.2.6).

6. Verification

A verifier performs the following steps when it discovers a peer's covered document. They are in addition to the checks defined by the peer's protocol. Step 1 is a fetch the protocol already makes.

  1. Fetch the covered document from the location its protocol defines. Do not act on its content until step 4 succeeds (Section 9.6).

  2. Fetch the Entity Configuration for the Entity Identifier of the peer (Section 6.1, Section 6.4). Validate it per [OpenID.Federation], Section 3.2. The verifier MAY make this fetch in parallel with step 1.

  3. In its well_known_bindings claim, take the member named by the covered document's well-known suffix. If it is absent, verification fails.

  4. Compute the covered document's digest (Section 5.1) and compare it to digests. If no element matches, verification fails.

  5. Resolve and validate a Trust Chain from the Entity Configuration to one of the verifier's configured Trust Anchors, including the signature on each Entity Statement in it ([OpenID.Federation], Section 10). The verifier SHOULD perform this step, and MUST if its policy requires federation verification of the peer. If it fails, verification fails.

  6. If the covered document has a jwks_uri member, and Resolved Metadata carries neither jwks nor signed_jwks_uri (Section 6.2), fetch the JWK Set at the jwks_uri that applies: the one in Resolved Metadata if it carries one, otherwise the covered document's. Compute its digest and compare it to jwks_digests. If jwks_digests is absent, or no element matches, verification fails. A verifier whose policy requires federation verification of the peer makes this fetch after step 5 succeeds. Any other verifier MAY make it as soon as step 4 succeeds, in parallel with step 5.

  7. The verifier MAY check the Trust Marks it needs among those the covered document lists in trust_mark_types (Section 8.3). This step requires step 5.

Without step 5, verification relies on DNS and the Web PKI (Section 9.7). The verifier uses the covered document, and the protocol keys in the JWK Set, only after the steps it performs succeed.

The jwks_uri fetch is in step 6, after the covered document is authenticated, so that the verifier never dereferences a URL taken from an unauthenticated document (Section 9.6). Steps 1 and 2 fetch locations derived from the peer's identifier, which the verifier already has.

6.1. Peer Identifiers

The Entity Identifier of the peer is the identifier the protocol uses for it, where that identifier is an https URL: issuer in [RFC8414], resource in [RFC9728]. The Entity Identifier MUST equal that identifier.

A protocol whose peer identifier is not such a URL, for example a bare domain name, defines the mapping from its identifier to an Entity Identifier. Absent such a mapping, the protocol's documents cannot be covered by this specification.

6.2. Metadata Precedence

Entity Type metadata in the Entity Configuration, and the Resolved Metadata that results from applying metadata_policy to it ([OpenID.Federation], Section 6.1), can carry members that also appear in the covered document, such as issuer, jwks, or jwks_uri. Resolved Metadata governs every member it carries: the verifier uses the value from Resolved Metadata and ignores the covered document's value for that member. The covered document supplies the members Resolved Metadata does not carry.

An Entity SHOULD NOT carry the same member in both, except a member whose value must equal the Entity Identifier, such as issuer (Section 6.1). Carrying such a member in both places cannot introduce a disagreement, and lets Entity Type metadata meet the protocol's own metadata specification. An Entity cannot prevent a Superior from supplying a member through metadata_policy, which is why Resolved Metadata governs rather than the two being required to agree.

If Resolved Metadata carries jwks or signed_jwks_uri ([OpenID.Federation], Section 5.2.1), that is the only source of the Entity's protocol keys. Step 6 of Section 6 does not run, and the JWK Set that jwks_digests binds is not used. An Entity that publishes its protocol keys this way does not need this specification for them, and its covered document has no jwks_uri to bind.

If Resolved Metadata carries jwks_uri, step 6 fetches the JWK Set at that URL and still checks it against jwks_digests. The digest binds the JWK Set's octets, not its location, so a jwks_uri supplied by a Superior verifies only if it serves the JWK Set the Entity signed. Where the covered document has no jwks_uri, there is no jwks_digests, and a jwks_uri in Resolved Metadata is authenticated by DNS and the Web PKI alone.

6.3. Verification Outcomes

Verification either succeeds or fails; there is no partial result. A verifier whose policy requires federation verification of a peer MUST fail closed when verification fails, and MUST NOT fall back to Web PKI trust in the covered document (Section 9.10).

Failures are of two kinds, and they differ in how a verifier retries and caches:

  • Transient: the covered document, the Entity Configuration, a Subordinate Statement, or the JWK Set could not be fetched, other than as listed under authoritative. The verifier MAY retry. It MAY cache the failure for a short period, to bound its retries (Section 9.12), and MUST NOT treat a cached transient failure as success or as non-participation.

  • Authoritative: the fetch of the Entity Configuration returns 404 or 410, the Entity Configuration is invalid, well_known_bindings has no member for the well-known suffix, jwks_digests is absent where it is required, a digest does not match, or the Trust Chain does not validate. Retrying the same fetches does not change the result. A 404 or 410 means the peer does not participate, and the verifier MAY cache it as HTTP caching permits ([RFC9111]).

A verifier whose policy does not require federation verification of the peer MAY proceed without it after a failure. Section 9.7 states what that verifier does and does not detect.

On a digest mismatch, the verifier MAY re-fetch the Entity Configuration once, in case the Entity replaced a document without sequencing the update (Section 7), and compare the digests again. It MUST rate-limit such re-fetches per Entity, and MUST NOT extend the lifetime of a cached Entity Configuration past its exp on account of one.

6.4. Identifiers with a Path

[RFC8414] and [RFC9728] allow an identifier with a path component. The Entity Identifier is the same string, path included (Section 6.1), so the Entity Configuration is at the identifier with /.well-known/openid-federation appended ([OpenID.Federation], Section 9). The protocol can place its own document differently: [RFC8414], Section 3.1 and [RFC9728], Section 3.1 insert the well-known path between the host and the path. The verifier fetches each document where its own specification places it (Appendix A.6).

6.5. Caching

A verifier MAY cache the outcome of verification, but not beyond the Entity Configuration's exp, nor beyond the expiration time of the Trust Chain if it resolved one ([OpenID.Federation], Section 10.4). Within that period, a verifier can re-fetch a covered document or JWK Set, for example on a protocol key with an unknown kid. It checks the new content against the digests in its cached Entity Configuration.

7. Document Updates

Replacing a covered document or JWK Set changes its digest. The Entity overlaps the old and new digests, so that no verifier holding a valid cached Entity Configuration sees a document it cannot match:

  1. Issue an Entity Configuration whose digest array contains both the current digest and the digest of the replacement document.

  2. Wait until every Entity Configuration that lists only the current digest has expired, per its exp claim.

  3. Replace the document.

  4. Issue Entity Configurations whose digest array contains only the new digest.

Step 4 can happen at the Entity Configuration's next routine re-issue. The Entity Configuration lifetime bounds the wait in step 2. An Entity that updates its documents often SHOULD use a short exp. Rotating a protocol key is a replacement of the JWK Set, done the same way.

This sequence is for a planned replacement. An Entity replacing a document or key because the old one is compromised skips the overlap (Section 9.4).

8. Trust Marks in Well-Known Documents

This section is OPTIONAL to implement. The binding in the preceding sections does not depend on it.

An Entity's Trust Marks are in the trust_marks claim of its Entity Configuration ([OpenID.Federation], Section 3.1.2). This specification does not carry Trust Marks anywhere else, and does not alter them. A Trust Mark says nothing about covered documents or protocol keys, and is unaffected when they change.

A covered document that is a JSON object MAY contain the two members defined below. The document makes these statements for the role it describes, and its digest authenticates them. When one origin serves several roles, each role's document makes its own statements.

[RFC8414], Section 2 permits additional metadata parameters, and [RFC9728], Section 3.2 requires consumers to ignore parameters they do not understand. Adding these members therefore does not affect existing consumers.

8.1. trust_mark_types

  • trust_mark_types (OPTIONAL): JSON array of strings. Each element is a trust_mark_type that the Entity presents as relevant to the role this document describes.

An Entity Configuration can hold Trust Marks for many purposes, and trust_mark_types selects those that apply to one role. An Entity holds a Trust Mark type in a role when all of the following are true:

  1. Its covered document for that role lists the type in trust_mark_types.

  2. Its Entity Configuration contains a Trust Mark of that type that is valid per [OpenID.Federation], Section 7.3.

  3. If the Trust Anchor's trust_mark_issuers claim lists issuers for that type, the Trust Mark's issuer is one of them.

A verifier evaluating the Entity in a role considers only the types the Entity holds in that role.

8.2. trust_mark_types_required

  • trust_mark_types_required (OPTIONAL): JSON object. Each member name is the well-known suffix of the covered document that describes a counterparty role. Each member value is a non-empty JSON array of trust_mark_type strings that an Entity in that role MUST hold (Section 8.1) for this Entity to deal with it in that role.

Example: an OAuth protected resource that accepts access tokens only from authorization servers holding a payment-institution Trust Mark. Appendix A.1 shows an authorization server that meets this requirement.

{
  "resource": "https://api.bank.example",
  "authorization_servers": ["https://as.bank.example"],
  "jwks_uri": "https://api.bank.example/jwks",
  "trust_mark_types": [
    "https://openfinance.example/account-servicing"
  ],
  "trust_mark_types_required": {
    "oauth-authorization-server": [
      "https://openfinance.example/payment-institution"
    ]
  }
}

trust_mark_types_required is for discovery. It lets a client learn before a call that the resource would refuse its authorization server, and lets an operator learn which Trust Marks it needs to obtain. The Entity enforces its requirements from its own policy, whether or not it publishes them (Section 9.10).

The well-known suffix identifies a counterparty role at the granularity of one document. A party can act in capacities that its documents do not distinguish: an authorization server serves one oauth-authorization-server document whatever the capacities it offers. A protocol that needs to require different accreditation of capacities within one document's role defines its own mechanism; trust_mark_types_required cannot express it.

8.3. Verifying Trust Marks

A verifier whose policy requires Trust Marks of a peer in a role first verifies the peer's covered document for that role, including step 5 (Section 6). It then checks that the peer holds each required type in that role (Section 8.1).

8.4. Trust Mark Requirement Errors

This specification defines an error that a protocol MAY adopt. An Entity returns it when it refuses to deal with a counterparty because the counterparty does not hold its required Trust Marks. A protocol that uses JSON error responses with an error member conveys it with these members:

  • error: trust_mark_required

  • entity (REQUIRED): The Entity Identifier of the counterparty that does not meet the requirement.

  • trust_mark_types (REQUIRED): JSON array of the required trust_mark_type values that the counterparty does not hold.

The adopting protocol defines the HTTP status code and where the error is returned. The entity can identify a party other than the requester, such as the requester's authorization server. A party that relays the error relays it unchanged.

A peer that fails verification (Section 6) has not been refused on Trust Marks. The protocol reports that as a metadata or key discovery failure.

9. Security Considerations

9.1. What the Trust Chain Attests

The Trust Chain attests only that the Entity's Federation Entity Keys belong to its Entity Identifier. The Entity itself attests the digests, and therefore its covered documents, its JWK Sets, and the Trust Mark statements in them. A verifier trusts the Entity's statements about its own documents exactly as far as it trusts the Entity's Federation Entity Keys. Only Trust Marks convey accreditation of the Entity by third parties.

9.2. DNS and Transport

Once the Trust Chain is validated and the digests match, DNS and TLS serve only as transport and as a redundant check. An attacker who can answer for the origin can withhold documents but cannot substitute them.

9.3. Federation Key Compromise

An attacker holding an Entity's Federation Entity Key can issue an Entity Configuration that lists digests of documents the attacker chooses, and so substitute the Entity's protocol keys. This lasts until the Superior removes the key from its Subordinate Statement and Trust Chains cached by verifiers expire. Entities SHOULD protect Federation Entity Keys at least as well as their protocol keys, and SHOULD NOT hold the two in the same place.

9.4. Protocol Key Compromise

An attacker who obtains a protocol key can use it until the Entity removes the key's JWK Set from jwks_digests and every Entity Configuration that listed it has expired. The overlap in Section 7 works against the Entity here: while both the old and the new digest are listed, an attacker who can answer for the origin can serve the superseded JWK Set, and a verifier accepts it. An Entity replacing a compromised key therefore skips the overlap: it issues an Entity Configuration listing only the new digest, and then serves only the new JWK Set. A verifier still holding an earlier Entity Configuration fails to verify the new JWK Set until it re-fetches the Entity Configuration (Section 6.3). That failure is the availability cost of skipping the overlap.

Verifiers holding an unexpired Entity Configuration that lists the compromised key's digest continue to accept it (Section 6.5). The residual exposure is the longest remaining lifetime among the Entity Configurations the Entity has issued, so an Entity SHOULD use an exp no longer than the exposure it is willing to carry. There is no revocation signal short of that; OpenID Federation has none for protocol keys, and this specification adds none.

The same applies to any covered document whose replacement is a revocation rather than an update.

9.5. Trust Anchor Key Rollover

The Trust Anchor's Federation Entity Keys configured in a verifier are its root of trust. The Trust Anchor publishes its next key in its Entity Configuration before signing with it ([OpenID.Federation], Section 11.2). A verifier that does not refresh the Trust Anchor's Entity Configuration within that overlap can no longer validate Trust Chains, and must be re-configured out of band. OpenID Federation defines no hold-down period comparable to [RFC5011], so a compromised current Trust Anchor key can introduce a replacement key that verifiers accept immediately.

9.6. Unauthenticated Content Before Verification

A covered document is unauthenticated until its digest matches in step 4 of Section 6, and, for a verifier whose policy requires federation verification, until the Trust Chain is validated in step 5. Before then, the verifier MUST NOT act on any member of the covered document. This includes trust_mark_types, trust_mark_types_required, and every URL-valued member: the verifier MUST NOT dereference a URL taken from a covered document before then. Step 6 is placed after these checks for that reason.

The fetches in steps 1 and 2 are to locations derived from the peer's identifier, which the verifier holds before it reads anything the peer serves. Step 1 is the fetch the peer's protocol makes without this specification.

9.7. Verification Without a Trust Chain

A verifier that skips step 5 of Section 6 has checked only that the covered document and JWK Set match an Entity Configuration served by the same origin. That detects a document changed without a matching change to the Entity Configuration. It does not detect an attacker who can answer for the origin, who can serve a matching Entity Configuration. Such a verifier relies on DNS and the Web PKI as it would without this specification.

The same holds for a verifier whose policy does not require federation verification and that proceeds without it after a failure (Section 6.3), even if it performs step 5. An attacker who can answer for the origin can serve no Entity Configuration, and the verifier proceeds. Its checks detect a covered document or JWK Set that the Entity changed without updating its Entity Configuration, and nothing more.

9.8. Metadata Policy and Covered Documents

metadata_policy operators such as one_of and subset_of ([OpenID.Federation], Section 6.1.3.1) apply to Entity Type metadata. A member that the Entity carries only in its covered document is outside every Superior's policy. A Superior that needs to constrain a member marks it essential as well. The Entity must then carry it in Entity Type metadata (Section 5), where the policy applies, and Resolved Metadata governs it (Section 6.2).

9.9. Other URLs in Covered Documents

jwks_digests authenticates only the JWK Set. For any other URL-valued member of a covered document, the URL is authenticated but the document at that URL is not. A specification that needs such a document authenticated can define a member for its digests (Section 5).

9.10. Published Requirements Are Not Enforcement

trust_mark_types_required informs counterparties; it does not bind the publisher. Whether a verifier requires federation verification or Trust Marks of a peer comes from the verifier's own configuration, never from the peer's documents. A verifier whose policy requires federation verification of a peer MUST NOT fall back to Web PKI trust because the peer's covered document omits trust_mark_types, or because the peer serves no Entity Configuration.

9.11. Trust Mark Selection

trust_mark_types narrows which Trust Marks count for a role. It cannot add one, because a listed type counts only with a valid Trust Mark (Section 8.1). Where the Trust Mark Issuer offers a Trust Mark Status endpoint ([OpenID.Federation], Section 8.4), the verifier MAY query it.

9.12. Resolution Cost

Trust Chain resolution adds fetches to metadata discovery. An attacker who can cause a verifier to discover many peers can use this to amplify load on the verifier and on Superiors' fetch endpoints. Verifiers SHOULD cache per Section 6.5, and SHOULD bound the rate of Trust Chain resolution.

10. Privacy Considerations

Resolving a peer's Trust Chain reveals to the peer's Superiors, through requests to their fetch endpoints, that the verifier is evaluating that peer ([OpenID.Federation], Section 19.3). A verifier that considers this sensitive can use a resolver it operates ([OpenID.Federation], Section 10.6), or cache Subordinate Statements for their full lifetime.

A Trust Mark in an Entity Configuration is public. An Entity MAY omit from its Entity Configuration any Trust Mark it does not want to disclose.

11. IANA Considerations

11.1. JSON Web Token Claims

This specification requests registration of the following in the "JSON Web Token Claims" registry established by [RFC7519]:

  • Claim Name: well_known_bindings

  • Claim Description: Digests binding an Entity's well-known documents and JWK Sets to its Entity Configuration

  • Change Controller: OpenID Foundation Artifact Binding Working Group - openid-specs-ab@lists.openid.net

  • Specification Document(s): Section 5 of this specification

digest_alg values are taken from the "Hash Algorithms for HTTP Digest Fields" registry established by [RFC9530].

12. Open Issues

Note: This section is to be removed before publication.

13. Document History

Note: This section is to be removed before publication.

14. Acknowledgments

TBD

15. Normative References

[RFC9110]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP Semantics", STD 97, RFC 9110, DOI 10.17487/RFC9110, , <https://www.rfc-editor.org/info/rfc9110>.
[RFC8615]
Nottingham, M., "Well-Known Uniform Resource Identifiers (URIs)", RFC 8615, DOI 10.17487/RFC8615, , <https://www.rfc-editor.org/info/rfc8615>.
[RFC8174]
Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/info/rfc8174>.
[RFC9111]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP Caching", STD 98, RFC 9111, DOI 10.17487/RFC9111, , <https://www.rfc-editor.org/info/rfc9111>.
[RFC7519]
Jones, M., Bradley, J., and N. Sakimura, "JSON Web Token (JWT)", RFC 7519, DOI 10.17487/RFC7519, , <https://www.rfc-editor.org/info/rfc7519>.
[RFC6749]
Hardt, D., Ed., "The OAuth 2.0 Authorization Framework", RFC 6749, DOI 10.17487/RFC6749, , <https://www.rfc-editor.org/info/rfc6749>.
[RFC9728]
Jones, M.B., Hunt, P., and A. Parecki, "OAuth 2.0 Protected Resource Metadata", RFC 9728, DOI 10.17487/RFC9728, , <https://www.rfc-editor.org/info/rfc9728>.
[OpenID.Federation]
Hedberg, R., Jones, M.B., Ed., De Marco, G., Solberg, A.Å., Bradley, J., and V. Dzhuvinov, "OpenID Federation 1.1", , <https://openid.net/specs/openid-federation-1_1.html>.
[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/info/rfc2119>.
[RFC9530]
Polli, R. and L. Pardue, "Digest Fields", RFC 9530, DOI 10.17487/RFC9530, , <https://www.rfc-editor.org/info/rfc9530>.
[RFC7515]
Jones, M., Bradley, J., and N. Sakimura, "JSON Web Signature (JWS)", RFC 7515, DOI 10.17487/RFC7515, , <https://www.rfc-editor.org/info/rfc7515>.
[RFC8414]
Jones, M., Sakimura, N., and J. Bradley, "OAuth 2.0 Authorization Server Metadata", RFC 8414, DOI 10.17487/RFC8414, , <https://www.rfc-editor.org/info/rfc8414>.

16. Informative References

[OpenID.Federation.Connect]
Hedberg, R., Jones, M.B., Ed., De Marco, G., Solberg, A.Å., Bradley, J., and V. Dzhuvinov, "OpenID Federation for OpenID Connect 1.1", , <https://openid.net/specs/openid-federation-connect-1_1.html>.
[RFC5011]
StJohns, M., "Automated Updates of DNS Security (DNSSEC) Trust Anchors", STD 74, RFC 5011, DOI 10.17487/RFC5011, , <https://www.rfc-editor.org/info/rfc5011>.
[I-D.hardt-oauth-aauth-protocol]
Hardt, D., "AAuth Protocol", , <https://datatracker.ietf.org/doc/draft-hardt-oauth-aauth-protocol>.
[I-D.ietf-webbotauth-httpsig-protocol]
Meunier, T. and S. Major, "HTTP Message Signatures for automated traffic", Work in Progress, Internet-Draft, draft-ietf-webbotauth-httpsig-protocol-00, , <https://datatracker.ietf.org/doc/html/draft-ietf-webbotauth-httpsig-protocol-00>.

Appendix A. Examples

Digest values are illustrative. Entity Configurations are shown as JWT Claims Sets. In each, jwks holds the Entity's Federation Entity Keys, and jwks_digests binds the JWK Set that holds its protocol keys.

A.1. OAuth Authorization Server

Entity Configuration of an authorization server, served at https://as.bank.example/.well-known/openid-federation. It holds the payment-institution Trust Mark type in its authorization server role, so it meets the requirement of the protected resource in Section 8.2.

{
  "iss": "https://as.bank.example",
  "sub": "https://as.bank.example",
  "iat": 1790236800,
  "exp": 1790323200,
  "jwks": {
    "keys": [
      {
        "kty": "EC",
        "crv": "P-256",
        "kid": "fed-2026-09",
        "x": "f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU",
        "y": "x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0"
      }
    ]
  },
  "authority_hints": ["https://ta.example"],
  "metadata": {
    "oauth_authorization_server": {}
  },
  "well_known_bindings": {
    "oauth-authorization-server": {
      "digests": [
        "O-YmLY31Z3ljOBWYLt1JjjI0xbOMNA2HVuGDeHwYJAo"
      ],
      "jwks_digests": [
        "HRb-DHuBwopK4jeYA9XkP7OPK_u7kxeth9NSptaj8r4"
      ]
    }
  },
  "trust_marks": [
    {
      "trust_mark_type":
        "https://openfinance.example/payment-institution",
      "trust_mark": "eyJ0eXAiOiJ0cnVzdC1tYXJrK2p3dCIs..."
    }
  ]
}

The oauth_authorization_server member declares the Entity Type ([OpenID.Federation.Connect], Section 5.1.3). It is empty because the authorization server's metadata is in its covered document, at https://as.bank.example/.well-known/oauth-authorization-server:

{
  "issuer": "https://as.bank.example",
  "authorization_endpoint": "https://as.bank.example/auth",
  "token_endpoint": "https://as.bank.example/token",
  "jwks_uri": "https://as.bank.example/jwks",
  "response_types_supported": ["code"],
  "trust_mark_types": [
    "https://openfinance.example/payment-institution"
  ]
}

A.2. OAuth Protected Resource

Excerpt of the Entity Configuration of the protected resource in Section 8.2, served at https://api.bank.example/.well-known/openid-federation. Its covered document lists the account-servicing type, and the Trust Mark here completes what it needs to hold that type in its protected resource role (Section 8.1).

"well_known_bindings": {
  "oauth-protected-resource": {
    "digests": [
      "xghE89DclS2ArTw7gSvMnNCdhxR94zJ6dSvAS8CSXiE"
    ],
    "jwks_digests": [
      "OpHXW1JuZaCwv6-hjpEq2A6w0HoObL6tePwr86Gs1H4"
    ]
  }
},
"trust_marks": [
  {
    "trust_mark_type":
      "https://openfinance.example/account-servicing",
    "trust_mark": "eyJ0eXAiOiJ0cnVzdC1tYXJrK2p3dCIs..."
  }
]

A.3. AAuth Person Server

Excerpt of the Entity Configuration of an AAuth Person Server, served at https://ps.example/.well-known/openid-federation, during a protocol key rotation (Section 7). AAuth defines no Entity Type, so the Entity Configuration declares federation_entity (Section 5). jwks_digests holds the digests of the current and the replacement JWK Set.

"metadata": {
  "federation_entity": {}
},
"well_known_bindings": {
  "aauth-person.json": {
    "digests": [
      "ZSfJNhovRpxSda_LXQblMBM2fNIxmV3hPcchhxE4g4I"
    ],
    "jwks_digests": [
      "pUy6FU8E5nvRlZ03W9oFI02hXALOn9p65Gmh05LtEZQ",
      "2wqEXWiqltPQ5Vr3zaudefAwhTdmRGz8yvlGrtcSVys"
    ]
  }
}

The covered document at https://ps.example/.well-known/aauth-person.json:

{
  "issuer": "https://ps.example",
  "auth_token_endpoint": "https://ps.example/token",
  "person_token_endpoint": "https://ps.example/person",
  "jwks_uri": "https://ps.example/.well-known/jwks.json"
}

A.4. Web Bot Auth Key Directory

A Web Bot Auth agent publishes its keys at https://agent.example/.well-known/http-message-signatures-directory ([I-D.ietf-webbotauth-httpsig-protocol], Section 8.1). That covered document is itself a JWK Set, so it has no jwks_uri, and its entry has only digests. The keys in it are the agent's protocol keys. Web Bot Auth defines no Entity Type, so the Entity Configuration declares federation_entity (Section 5). Excerpt of the Entity Configuration, served at https://agent.example/.well-known/openid-federation:

"metadata": {
  "federation_entity": {}
},
"well_known_bindings": {
  "http-message-signatures-directory": {
    "digests": [
      "QFsRg42H_jf5dbtcwBPOphZDx3fuDt8LsQ6gumTzOoQ"
    ]
  }
}

The covered document:

{
  "keys": [
    {
      "kty": "OKP",
      "crv": "Ed25519",
      "kid": "NFcWBst6DXG-N35nHdzMrioWntdzNZghQSkjHNMMSjw",
      "x": "JrQLj5P_89iXES9-vFgrIy29clF9CC_oPPsw3c5D0bs"
    }
  ]
}

A.5. Collocated Roles

An origin that is both an OAuth authorization server and a protected resource lists one covered document per role. Each document makes its own Trust Mark statements. Both reference the same JWK Set, so their jwks_digests are equal.

"well_known_bindings": {
  "oauth-authorization-server": {
    "digests": [
      "DzTlzOI0wxzHdCD43RS-AdGY3RB4KX4VB0T3k73D7_Q"
    ],
    "jwks_digests": [
      "tUGsanRBidFVjcN7TNR0U4GpwLNg-9JEcGgooLMMBhY"
    ]
  },
  "oauth-protected-resource": {
    "digests": [
      "xOKnpnaLGfEscsd0LtJ2KO7io1UqbfB5QnlHIlv0jL0"
    ],
    "jwks_digests": [
      "tUGsanRBidFVjcN7TNR0U4GpwLNg-9JEcGgooLMMBhY"
    ]
  }
}

A.6. Identifier with a Path

An authorization server has issuer https://idp.example/tenant-a, and its Entity Identifier is the same string. A verifier fetches:

  • the covered document at https://idp.example/.well-known/oauth-authorization-server/tenant-a ([RFC8414], Section 3.1), and

  • the Entity Configuration at https://idp.example/tenant-a/.well-known/openid-federation ([OpenID.Federation], Section 9).

The well_known_bindings member for oauth-authorization-server has the same form as for an identifier with no path.

Appendix B. Design Rationale

B.1. Why a Claim and Not Metadata

Metadata in OpenID Federation is subject to the Entity's Superiors. A Superior can supply or override metadata parameters in its Subordinate Statement and constrain them with metadata_policy, and verifiers use the resulting Resolved Metadata ([OpenID.Federation], Section 6.1). The digests are the Entity's own statements about documents only it serves. A Superior that supplied or altered them would have to coordinate every document update and key rotation with the Entity (Section 7), which is the dependency this specification removes (Appendix B.4). A Superior that constrained digest_alg would add little, since a verifier enforces the algorithms it accepts from its own policy.

A claim in the Entity Configuration is signed only by the Entity and is outside metadata policy, as jwks and trust_marks are. It also belongs to no Entity Type, so a verifier finds the entry for a document by its well-known suffix alone. No mapping from protocols to Entity Types is needed, and no per-protocol profile.

B.2. Why Keyed by Well-Known Suffix

The well-known suffix is the one identifier every covered document already has. It is registered in the IANA "Well-Known URIs" registry [RFC8615], and the verifier holds it from the discovery step it is already performing.

B.3. Why the Claim Does Not State Locations

The verifier already fetches each covered document from the location its protocol defines, and the Entity Configuration from the location OpenID Federation defines. A location in the claim would be a second source that could disagree with the first. It would also have to encode each protocol's rule for identifiers with a path.

B.4. Why the Entity Signs the Digests

The alternative is to carry digests in a Trust Mark issued by the Trust Anchor or an accreditation body. That would make every key rotation and metadata change a request to a third party. Accreditation changes rarely; keys and metadata change routinely. Putting the digests in the Entity's own Entity Configuration keeps routine changes self-service, while the Superior still controls which Federation Entity Keys speak for the Entity. Trust Marks carry accreditation only.

B.5. Why Not Sign the Documents

[RFC8414] and [RFC9728] offer signed_metadata, OpenID Federation offers signed_jwks_uri ([OpenID.Federation], Section 5.2.1), and any document could carry a detached JWS ([RFC7515], Appendix F). Each has two costs. Servers must produce and serve signed variants of documents they serve today as plain JSON. Verifiers must handle two formats, each rooted in a different key. With digests, an Entity joins a federation by publishing an Entity Configuration, and nothing it already serves changes except the optional Trust Mark members.

For a JWK Set, the three ways OpenID Federation can bind it compare as follows:

Table 2
Binding JWK Set as served On protocol key rotation
jwks in Entity Type metadata Not served separately Entity re-signs its Entity Configuration, or Superior re-issues its Subordinate Statement if the Superior supplies it
signed_jwks_uri JWT signed with a Federation Entity Key Entity re-signs the JWK Set JWT
jwks_digests Plain JSON, unchanged Entity re-signs its Entity Configuration (Section 7)

With jwks_digests, verifiers that do not use OpenID Federation fetch the same JWK Set at the same URL. The Entity keeps one JWK Set, whether or not a given verifier checks the binding.

B.6. Why Arrays of Digests

A digest pins one version of a document, and verifiers cache Entity Configurations for their lifetime. Listing old and new digests together lets the Entity pre-publish the new digest, as OpenID Federation pre-publishes a Trust Anchor's next key. The alternative is to require verifiers to re-fetch on mismatch. That shifts the cost to every verifier and creates a forced-fetch vector, so a verifier MAY re-fetch at most once per mismatch, rate-limited per Entity (Section 6.3), and the overlap is what keeps that rare.

B.7. Why digest_alg and base64url

Base64url values match other digests in JOSE documents (x5t#S256, jkt). One digest_alg per covered document, defaulting to sha-256, names the algorithm once rather than in every value, using names from the [RFC9530] registry. The cost is that changing a document's algorithm is a cutover rather than an overlap.

B.8. Why the Binding Stands Apart from Trust Marks

Binding keys to an Entity Identifier and accrediting the Entity are separate questions, answered by different parties on different schedules. The Trust Chain answers the first; Trust Marks answer the second. A deployment that wants federation-rooted protocol keys and has no accreditation scheme uses the binding alone. The Trust Mark members are defined here because their authentication depends on the binding, not because the binding depends on them.

B.9. Why the Document States Its Trust Marks

The role a Trust Mark accredits is described by the protocol's own document. Putting trust_mark_types and trust_mark_types_required in that document keeps each statement with its role, so each role on a shared origin states its own. Carrying them in the Entity Configuration instead would separate them from the role they describe.

B.10. Why JSON Objects Only

The Trust Mark members need a document that can carry named members. Documents in other formats can still be covered by digest, but cannot make Trust Mark statements.

B.11. Why Requirements Are Keyed by Well-Known Suffix

A server often deals with counterparties in several roles, and may require different accreditation of each. The counterparty's well-known suffix names the role its document describes, without another identifier. It is also the suffix of the document in which the counterparty lists its own trust_mark_types. This is role at document granularity, which is as far as the suffix reaches (Section 8.2).

Author's Address

Dick Hardt
Hellō