draft-ietf-oauth-client-id-metadata-document-03

Source files on GitHub

In one line: an OAuth client uses an HTTPS URL as its client_id, and the authorization server fetches the client's metadata document from that URL instead of requiring prior registration.

What this is

An OAuth 2.0 client normally has to register with each authorization server before use. Manual registration is impossible when the two parties have no relationship, and Dynamic Client Registration [RFC7591] can be impractical and leaves registration data to manage and clean up (Section 1). This draft lets the client publish its own registration information at a Client Identifier URL, which is the client_id (Section 3). The authorization server fetches the Client ID Metadata Document, a JSON document, from that URL (Sections 4 and 6). The document's client_id must match the URL it was fetched from, so the URL is both the identity and the place where the metadata lives. The draft says the approach suits clients with a stable, public web presence and suits development-time or short-lived clients less well (Section 1). Revision 03 is a Standards Track work item of the OAuth working group.

How it works

Diagram
sequenceDiagram
    participant C as Client
    participant U as User agent
    participant AS as Authorization server
    participant H as Client Identifier URL host
    C->>U: Redirect with client_id set to the Client Identifier URL
    U->>AS: Authorization request
    AS->>H: GET Client Identifier URL, Accept application/json, no redirects followed
    H-->>AS: 200 OK with Client ID Metadata Document
    AS->>AS: Validate client_id match, redirect URI, grant and response types, auth method
    AS->>U: Consent screen showing client hostname and client metadata
    U->>AS: User approves
    AS->>U: Authorization response including iss
    U->>C: Redirect back to the client
    C->>AS: Token request, private_key_jwt if declared
    AS->>H: Fetch jwks_uri to verify the client assertion
  1. The client sends the user to the authorization server with the Client Identifier URL as client_id. The URL must be https, have a path other than /, and carry no userinfo, dot segments or fragment (Section 3).
  2. The authorization server SHOULD fetch the document automatically, SHOULD send Accept: application/json, MUST accept only 200 OK, and MUST NOT follow redirects (Section 6).
  3. The server checks that the document's client_id equals the URL by simple string comparison (Section 4), and that the redirect URI exactly matches a registered one, with a loopback exception for ports (Section 4.2).
  4. The server MUST intersect the document's grant_types and response_types with what it supports, and MUST reject with invalid_client if either intersection is empty (Section 6).
  5. The server determines the client authentication method. If neither token_endpoint_auth_method nor token_endpoint_auth_methods_supported is present, it MUST assume none (Section 5).
  6. The server SHOULD show the client_id hostname on the consent screen, and it MUST prefetch and re-serve any logo it displays (Sections 10.6 and 10.9).
  7. The authorization response MUST include iss (Section 7).
  8. If the client declared private_key_jwt and the server supports it, the server MUST require client authentication per Section 2.2 of [RFC7523] using a key from the metadata document (Section 5).

Use cases

  • A client with a stable public web presence talks to many authorization servers it has no prior relationship with, and publishes one metadata document instead of registering at each (Section 1).
  • An enterprise identity provider pre-registers a Client Identifier URL to onboard a specific client, fetching the document at registration time and setting up client authentication (Section 9.2).
  • An authorization server that supports both CIMD clients and clients it registered itself keeps its generated client_id values from starting with https:// (Section 9.1).
  • A developer works on localhost against an authorization server that restricts redirect_uris, and uses a CIMD Service that provisions a stable Client Identifier URL (Section 10.13, Appendix A).
  • A confidential client publishes a jwks_uri and advertises ["private_key_jwt"], or advertises ["none", "private_key_jwt"] to serve servers with different capabilities (Section 5.1).

Why This Matters Now

  • Trigger: on 2 November 2026, the day -03 was posted, 11 issues were closed in the draft's GitHub repository and PR #99 "Add Client Authentication section" was merged. On 8 November, issue #131 was opened: it argues that the response_types intersection rule in Section 6 rejects clients that only use token-endpoint grants such as client credentials. The issue is open with no replies yet.
  • Source evidence: Revision 03 is dated 2 November 2026. It moves Client Authentication out of Security Considerations into a new, expanded Section 5, and adds error handling for failed fetches (Section 6.1), the grant_types and response_types intersection rule (Section 6), a mandatory iss parameter (Section 7) and several new security considerations (Section 10). The only reply so far to the -03 announcement on the OAuth list (9 November 2026) proposes further changes.
  • Expected impact: Implementers of authorization servers that accept URL client_ids need to revisit authentication defaults, fetch and cache behaviour, error responses and logo handling. Clients need to normalize their URLs and keep their documents stable and free of request-dependent content.

What Changed

  • Spec/document change summary: the revision history and the diff show these substantive changes.
    • The Client Identifier URL path may no longer be /, and clients SHOULD normalize the URL while the server MUST NOT (Section 3).
    • Loopback redirect URIs are exempt from exact port matching, per [RFC9700] (Section 4.2).
    • Credential restrictions now cover token_endpoint_auth_methods_supported, forbid jwks together with jwks_uri, and apply to software_statement content (Sections 4.1 and 4.3).
    • New Section 4.4 separates functional URIs from informative URIs, and the server MUST NOT require client_uri to share an origin with client_id or redirect_uris.
    • New Section 4.5 forbids deriving document contents from untrusted external input.
    • Client Authentication moved out of Security Considerations into Section 5. token_endpoint_auth_methods_supported is preferred, token_endpoint_auth_method is NOT RECOMMENDED, and the RFC7591 default of client_secret_basic MUST NOT be applied.
    • The server MUST intersect the document's grant_types and response_types with what it supports and MUST reject with invalid_client if either intersection is empty, and SHOULD send Accept: application/json when fetching (Section 6, explained in Section 10.7.1).
    • Discovery failures are split into transient and terminal, with refresh-token consequences and an HTTP 503 option (Section 6.1).
    • Caching: -02 said the server MAY set its own upper and lower bounds on cache lifetime. -03 says it SHOULD enforce a maximum effective duration whatever the response says, and SHOULD enforce a minimum when none is indicated. The Expires header need not be honoured, and rate limiting of re-fetches is allowed (MAY) (Section 6.2).
    • The authorization response MUST include iss (Section 7).
    • Logo prefetching and re-serving became MUST (Section 10.9).
    • New security sections cover URL confusion with issuer identifiers (Section 10.1), client presentation (Section 10.10) and resource-scoped persisted authorization state (Section 10.12).
    • The TBD note about a client_id_expires_at property was removed.
  • Compatibility or migration concerns: Sections 1 to 4.3 keep their numbers, but everything from Section 5 on was renumbered (for example, Client Information Discovery moved from Section 5 to Section 6, and Client Authentication from Section 8.2 to Section 5), so references to those -02 section numbers are stale. A document that omits both authentication properties is now treated as a public client, where RFC7591 would imply client_secret_basic. A server that did not previously require iss in the authorization response, or that linked logo_uri directly, must change. Servers that treated / as a valid path, or that required client_uri to be same-origin, must change too. token_endpoint_auth_method still works as a fallback but is NOT RECOMMENDED (Section 5).

Technical Analysis

  • Threat model implications:
    • The client controls the document, so everything in it is an assertion by the client. A client can impersonate a better-known one through its name or logo (Section 10.10), and the draft suggests showing the client_id hostname and optional domain-trust heuristics (Sections 10.6 and 10.8).
    • Fetching attacker-chosen URLs creates SSRF exposure. The server MUST NOT fetch URLs that resolve to special-use addresses [RFC6890], with a narrow loopback exception for development (Section 10.7). It SHOULD limit how much of the response it reads, and the recommended maximum is 5 kilobytes (Section 10.11).
    • The draft says a URL equal to the server's own issuer or to another trusted identifier can cause token confusion, so the server SHOULD reject it (Section 10.1).
    • Any persisted or reused authorization decision MUST be scoped at least to the pair of Client Identifier URL and resource (Section 10.12).
    • Request-dependent documents can leak who is asking or show different content to different parties, which Section 4.5 forbids and Section 11.1 explains.
  • Protocol flow implications:
    • Only 200 OK counts and redirects are not followed (Section 6). When a request fails because the document could not be retrieved or was invalid, the server MUST NOT redirect the user agent back to the client (Section 6.1).
    • A terminal failure from a client_id mismatch SHOULD invalidate outstanding refresh tokens immediately. A transient failure SHOULD NOT invalidate trust or discard cached metadata (Section 6.1).
    • Server metadata advertises support with the client_id_metadata_document_supported boolean (Section 8).
    • Client authentication relies on public keys only, via jwks or jwks_uri, and the JWT guidance points to [RFC8725] and a typ of client-authentication+jwt from rfc7523bis (Section 5).
  • Interop concerns:
    • Comparison is by simple string, so https://example.com/client and https://example.com:443/client are different clients (Section 3).
    • Servers that do not implement [OpenID.RPMetadataChoices] must still recognise token_endpoint_auth_methods_supported (Section 5).
    • A client listing ["none", "private_key_jwt"] is a public client at servers without private_key_jwt and may be rejected with invalid_client at servers that support it if it uses none (Section 5.1).
    • Cache lifetime is partly server policy, and the Expires header need not be honoured (Section 6.2). Two servers can therefore see different views of the same document.

Open Questions

  • Section 5 says the document MUST include jwks or jwks_uri and that the authorization request must return invalid_client otherwise. It sits in the paragraph on JWT-based authentication methods, and the revision history says the requirement applies "when using private_key_jwt". The text was proposed in a review comment on PR #99 (28 October 2026) as "When using private_key_jwt for client auth", to close issue #100, which asked about a document declaring private_key_jwt without keys. Whether "using" covers a document that lists ["none", "private_key_jwt"] and is then used as a public client is not stated, although the Section 5.1 examples always include a jwks_uri.
  • Section 5 carries an editorial note that invalid_client at the authorization endpoint lacks supporting text in the underlying specification (OAuth 2.1 issue 266). The error mapping is therefore unsettled.
  • Section 6 requires rejecting when the grant_types or response_types intersection is empty, but does not say what applies when the document omits these fields. RFC 7591 Section 2 defaults an omitted grant_types to authorization_code and an omitted response_types to code. Section 5 explicitly sets aside the RFC 7591 default for token_endpoint_auth_method, but Section 6 says nothing either way about these two. Issue #131 assumes the RFC 7591 default applies and shows that the rule then rejects token-endpoint-only clients at servers without an authorization endpoint. The working group has not responded yet.
  • Section 6.1 makes aborting the authorization request a SHOULD when the fetch fails, and Section 10.6 anticipates a consent screen where the fetch failed and only the client_id URL is shown. When a request does fail because the document could not be retrieved or was invalid, the server MUST NOT redirect the user agent to the client and SHOULD inform the user. The MUST to return invalid_client, or HTTP 503 for a transient failure, covers only the token and pushed authorization request endpoints. This matches issue #85, which asked that the authorization endpoint not redirect back to the client and that the token and PAR endpoints return a defined error. The two sentences therefore do not conflict.
  • Section 8 calls client_id_metadata_document_supported OPTIONAL while saying servers that publish metadata MUST include it. A reply on the OAuth list also notes that the boolean cannot express "supported only for pre-registered URLs" and proposes a client_id_metadata_document_registration_types_supported list (Section 9.2).
  • The same reply proposes a pre-fetch validation step in Section 6 and changing the query component from SHOULD NOT to MUST NOT (Section 3). It follows up on issue #112, which is still open. These proposals come from one participant: as of 11 November 2026 the thread has no other replies, so working group support is not shown.
  • Section 6.2 leaves the maximum and minimum effective cache durations to the server without recommended values.

Experiments

  • Lab 1: stand up a test authorization server that fetches a CIMD, then serve documents that vary one property each (mismatched client_id, a 301 redirect, a 500, a body over 5 kilobytes, a URL whose path is only /) and record which error each produces against Sections 4, 6 and 6.1.
  • Lab 2: publish documents with no auth properties, with only token_endpoint_auth_method, with both properties inconsistent, and with ["none", "private_key_jwt"] plus a jwks_uri. Check the authentication method the server infers and whether a client assertion sent to a none client gets invalid_client (Section 5).
  • Lab 3: add a document with a logo_uri and a client_uri on another origin, and confirm the server re-serves the logo from its own host, validates the image and does not require same-origin for client_uri (Sections 4.4 and 10.9).

Sources

Context

Trigger

The pick came from activity in the draft's GitHub repository. On 2 November 2026, the day -03 was posted, 11 issues were closed and PR #99 "Add Client Authentication section" was merged. On 8 November, issue #131 was opened about the response_types intersection rule in Section 6. The draft is at revision 03 (2 November 2026), and Datatracker lists it as Active, I-D Exists and WG Document in the oauth-wg track.

Why This Matters

The draft lets a client use an HTTPS URL as its client_id, with the authorization server fetching the metadata from it (Sections 3 and 6). Revision 03 adds or tightens a number of normative rules, such as client authentication defaults (Section 5), failure handling (Section 6.1), the mandatory iss parameter (Section 7) and logo re-serving, which was a SHOULD in -02 and is now a MUST (Section 10.9). Implementers of authorization servers and clients that rely on URL client_ids are directly affected, and every section from Section 5 on has a new number.

Open Questions

  • Does the jwks or jwks_uri requirement in Section 5 apply only when private_key_jwt is actually used, or to every document that offers it among several methods?
  • What does the server do when grant_types or response_types are absent from the document (Section 6)? The draft does not say, nor whether the RFC 7591 defaults (authorization_code and code) apply. Issue #131 asks for the rule to be revisited, including this case.
  • How should invalid_client be mapped at the authorization endpoint, given the editorial note about OAuth 2.1 issue 266 (Section 5)?
  • Will the working group take up the proposals one participant made on the mailing list: a pre-fetch validation step, MUST NOT for query components, and a registration-types list in server metadata (Sections 3, 6, 8 and 9.2)?

Spec notes

References

Normative references listed in the draft (Section 13.1):

  • [OpenID.RPMetadataChoices] OpenID Connect Relying Party Metadata Choices 1.0 (new in -03)
  • [RFC2119] and [RFC8174] (BCP 14)
  • [RFC3986] URI generic syntax
  • [RFC6749] OAuth 2.0
  • [RFC6819] OAuth 2.0 threat model
  • [RFC6890] special-purpose IP address registries
  • [RFC7523] JWT profile for OAuth 2.0 client authentication (informative in -02, normative in -03)
  • [RFC7591] Dynamic Client Registration
  • [RFC8259] JSON
  • [RFC8414] Authorization Server Metadata
  • [RFC8725] JWT best current practices (new in -03)
  • [RFC9110] HTTP semantics (new in -03)
  • [RFC9207] authorization server issuer identification (new in -03)
  • [RFC9700] OAuth 2.0 security best current practice

Informative references (Section 13.2):

  • [I-D.draft-ietf-oauth-attestation-based-client-auth] (-12, was -09 in -02)
  • [I-D.draft-ietf-oauth-rfc7523bis] (new, -11)
  • [I-D.draft-ietf-oauth-spiffe-client-auth] (-03, was -02 in -02)
  • [IndieAuth]
  • [OpenID] Connect Core 1.0
  • [OpenID.Federation] (1.1, was 1.0 in -02)
  • [OWASP.SSRF] (new)
  • [RFC9111] HTTP caching
  • [Solid-OIDC]

Key Changes

  • Section 3: the path / is prohibited, clients SHOULD normalize the URL per Sections 6.2.2 and 6.2.3 of [RFC3986], and the server MUST NOT normalize.
  • Section 4.1: restrictions now cover token_endpoint_auth_methods_supported and software_statement content, and jwks and jwks_uri MUST NOT both be present.
  • Sections 4.4 and 4.5: functional versus informative URIs, and a ban on deriving document contents from untrusted external input.
  • Section 5 (moved from Security Considerations, -02 Section 8.2, and expanded): authentication defaults to none, token_endpoint_auth_method is NOT RECOMMENDED, the RFC7591 default is not applied, and the server rejects with invalid_client when it supports none of the declared methods.
  • Section 6: grant_types and response_types intersection with invalid_client on empty, plus an Accept header recommendation.
  • Section 6.1: transient and terminal failure classes, no redirect of the user agent to the client, and invalid_client or HTTP 503 at the token and PAR endpoints.
  • Section 6.2: the -02 MAY for server-defined cache bounds becomes a SHOULD to enforce a maximum effective cache duration and a SHOULD to enforce a minimum when none is indicated, Expires need not be honoured, caching extends to jwks_uri and logo_uri data, and rate limiting is allowed (MAY). Errors and malformed documents are still never cached.
  • Section 7 (new): the authorization response MUST include iss.
  • Section 10: new subsections on URL confusion (10.1), Accept header (10.7.1), client presentation (10.10) and resource-scoped persisted state (10.12). Logo prefetching and re-serving went from SHOULD to MUST, with a MUST to validate the image (10.9), and Section 10.7 adds a SHOULD to follow the OWASP SSRF cheat sheet.
  • Section 11.1: adds a warning about varying documents by requester.
  • Section 12.1: the specification document reference is now Section 8 of -03.

Impact Analysis

  • Upstream: depends on OAuth 2.0 [RFC6749], Dynamic Client Registration metadata [RFC7591], Authorization Server Metadata [RFC8414], the security best current practice [RFC9700], issuer identification [RFC9207], and the OpenID metadata choices specification for token_endpoint_auth_methods_supported. The JWT typ recommendation points to a Work in Progress draft (rfc7523bis), which is not final.
  • Downstream: authorization server implementations that accept URL client_ids, client libraries and publishers of metadata documents, and any CIMD Service operators. Future specifications may place extra restrictions on document contents (Section 4). The only IANA action is the client_id_metadata_document_supported authorization server metadata name (Section 12.1).
  • Compatibility: section numbers from Section 5 on differ from -02. The default authentication method and the logo and iss requirements change observable behaviour. token_endpoint_auth_method remains readable as a fallback. The draft is a Work in Progress and may change again.

Interop checklist

  • The Client Identifier URL uses https, has no userinfo, no dot segments and no fragment, and has a path other than / (Section 3).
  • A URL with a query component is handled consistently, since the draft says SHOULD NOT and a proposal from one participant on the mailing list would make it MUST NOT (Section 3).
  • The server compares URLs by simple string and does not normalize: https://example.com/client and https://example.com:443/client are different clients (Section 3).
  • The document's client_id equals both the Client Identifier URL and the URL actually fetched (Section 4).
  • A client_id equal to the server's own issuer or to the identifier of an authorization server or resource server it trusts is rejected (SHOULD) (Section 10.1).
  • The fetch sends Accept: application/json, accepts only 200 OK, treats any redirect (including from a URL shortener) as an error, and does not follow it (Section 6).
  • A response body past the read limit (recommended 5 kilobytes) is treated as an error (Section 10.11).
  • URLs resolving to special-use addresses [RFC6890] are refused, in the main document and in jwks_uri and logo_uri. The loopback exception is off in production (Section 10.7).
  • The document contains no client_secret, no client_secret_expires_at, no shared-secret auth method in either auth property, no private key material, and not both jwks and jwks_uri. Content delivered via software_statement is held to the same rules (Sections 4.1 and 4.3).
  • A document with neither token_endpoint_auth_method nor token_endpoint_auth_methods_supported is treated as none, not client_secret_basic. A client assertion sent to a none client gets invalid_client (Section 5).
  • A document with both properties has token_endpoint_auth_method inside token_endpoint_auth_methods_supported (Section 5).
  • A server that does not implement [OpenID.RPMetadataChoices] still recognises token_endpoint_auth_methods_supported (Section 5).
  • The server picks a supported method from the list and does not fail on unsupported ones, and returns invalid_client when none is supported (Section 5).
  • A private_key_jwt document without jwks or jwks_uri is rejected with invalid_client, and the ["none", "private_key_jwt"] case is tested to see how the requirement is read (Section 5).
  • Client assertions carry a typ header, recommended value client-authentication+jwt (SHOULD), the server validates it (SHOULD), and the server implements an algorithm allowlist (MUST) (Section 5).
  • An empty grant_types or response_types intersection yields invalid_client, and the server documents how it treats a document that omits these fields, since the draft does not say whether the RFC 7591 defaults apply (Section 6).
  • A transient fetch failure leaves cached metadata and refresh tokens alone (SHOULD NOT invalidate). At the token and PAR endpoints a failure returns invalid_client, or HTTP 503 for a transient failure (MUST). A terminal client_id mismatch invalidates refresh tokens immediately (SHOULD). In every case the user agent is not redirected to the client (MUST NOT) (Section 6.1).
  • Error responses and malformed documents are never cached, and a maximum effective cache duration applies whatever the headers say (Section 6.2).
  • The authorization response includes iss and the client checks it (Section 7).
  • Server metadata publishes client_id_metadata_document_supported, and a client checks it before redirecting the user (Section 8).
  • Pre-registered and CIMD clients are distinguishable internally, and generated client_id values do not start with https:// (Section 9.1).
  • The document's contents are not derived from untrusted input such as path or query components of the URL, request headers, cookies or the requesting user or server (MUST NOT), and the server avoids sending cookies, user-specific information or unnecessary headers on the fetch (SHOULD) (Sections 4.5 and 11.1).
  • client_uri on a different origin from client_id is accepted, while redirect_uris restrictions follow server policy (Sections 4.4 and 10.2).
  • logo_uri content is prefetched, validated as an image and served from the server's own host, never linked directly (Section 10.9).
  • The consent screen shows the client_id hostname, and client_name and logo are shown only as policy allows (Sections 10.6 and 10.10).
  • Persisted or reused authorization decisions are scoped at least to the pair of Client Identifier URL and resource (Section 10.12).
  • Loopback redirect URIs with varying ports are accepted and other redirect URIs must match exactly (Section 4.2).

Hands-on log

Environment

  • Runtime:
  • Tooling:
  • Versions:

Steps

Results

Failure Modes

Next Actions