From 65ed208362d239994a997a0a582ff013b28b5657 Mon Sep 17 00:00:00 2001 From: Max Gerber Date: Mon, 27 Jul 2026 16:48:07 -0700 Subject: [PATCH 01/10] SEP: Require Token Endpoint Auth Methods Supported in CIMD --- ...endpoint-auth-methods-supported-in-cimd.md | 275 ++++++++++++++++++ 1 file changed, 275 insertions(+) create mode 100644 seps/0000-require-token-endpoint-auth-methods-supported-in-cimd.md diff --git a/seps/0000-require-token-endpoint-auth-methods-supported-in-cimd.md b/seps/0000-require-token-endpoint-auth-methods-supported-in-cimd.md new file mode 100644 index 000000000..8361c5a51 --- /dev/null +++ b/seps/0000-require-token-endpoint-auth-methods-supported-in-cimd.md @@ -0,0 +1,275 @@ +# SEP-0000: Require `token_endpoint_auth_methods_supported` in Client ID Metadata Documents + +- **Status**: Draft +- **Type**: Standards Track +- **Created**: 2026-07-27 +- **Author(s)**: @max-stytch +- **Sponsor**: @pcarleton +- **PR**: https://github.com/modelcontextprotocol/modelcontextprotocol/pull/{NUMBER} + +## Abstract + +This SEP makes the `token_endpoint_auth_methods_supported` metadata parameter +a required property of MCP Client ID Metadata Documents (CIMD), and creates a +deprecation path for the singular `token_endpoint_auth_method` parameter, +mirroring the guidance in [OpenID Connect RP Metadata Choices 1.0](https://openid.net/specs/openid-connect-rp-metadata-choices-1_0-final.html). +This enables a CIMD document to be published once and consumed by many +authorization servers with differing capabilities. It also deprecates the +implicit public-client default that applies when a document declares no +authentication method at all. Both deprecations point at the same end state: +every CIMD document declares its authentication methods explicitly in +`token_endpoint_auth_methods_supported`. This SEP is agnostic about which +authentication methods a given client advertises. It specifies the shape +and handling of the field, not its contents. + +## Motivation + +MCP's Client ID Metadata Document mechanism, introduced in +[SEP-991](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/991-enable-url-based-client-registration-using-oauth-c.md), +carried over the singular `token_endpoint_auth_method` from RFC 7591 client +metadata. It appears in the specification today only in an example document, +never in normative prose. + +A CIMD document is published at a single URL and consumed by every +authorization server the client ever connects to, and those servers do not +have uniform capabilities. Some support `private_key_jwt`; many accept only +public clients. A single-valued `token_endpoint_auth_method` gives a client no +way to express "either, depending on what you support." In practice that +forces the lowest common denominator: the client is forced to publish `none`, and the +servers that *could* have required a signed assertion never learn the client +was capable of one. + +The broader OAuth/OIDC ecosystem has already solved this capability +negotiation problem by moving from single-valued to multi-valued parameters. +RP Metadata Choices 1.0 supplements `token_endpoint_auth_method` with +`token_endpoint_auth_methods_supported`, and RFC 8414 uses that same name for +the mirror-image capability on the authorization server. Adopting it in CIMD +documents brings MCP in line with both. + +## Specification + +### CIMD Document Requirements + +MCP clients publishing a Client ID Metadata Document **MUST** include the +`token_endpoint_auth_methods_supported` metadata parameter. Its value is a +JSON array of strings drawn from the +[OAuth Token Endpoint Authentication Methods registry](https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#token-endpoint-auth-method) +established by [RFC 7591 Section 4.2](https://datatracker.ietf.org/doc/html/rfc7591#section-4.2). + +This extends the metadata document's required-property list in +[Client Registration](/specification/draft/basic/authorization/client-registration), +which currently reads: + +> The metadata document **MUST** include at least the following properties: +> `client_id`, `client_name`, `redirect_uris` + +The array **MUST** contain one or more authentication methods the client supports, in no particular order of preference. + +Authorization servers **MUST** support reading +`token_endpoint_auth_methods_supported` from a CIMD document. Documents that +omit it are handled as described in +[Deprecated Declarations](#deprecated-declarations). + +A document that carries **neither** parameter **MUST** be treated as declaring +`["none"]` — that is, as a public client. This default is itself **deprecated** +and exists only for compatibility: neither parameter is required by the +specification today, so documents omitting both are conformant under the +current revision and remain in wide use. Once the deprecation period elapses, +such a document is invalid and authorization servers reject it rather than +inferring a method. + +For illustration, a client that can operate either as a public client or with +an assertion-based credential might publish: + +```json +"token_endpoint_auth_methods_supported": ["none", "private_key_jwt"] +``` + +Here `none` indicates the client can act as a public client with no client +authentication at the token endpoint, and `private_key_jwt` indicates it can +authenticate with a signed JWT assertion per +[RFC 7523](https://datatracker.ietf.org/doc/html/rfc7523), using the JWKS +referenced by the CIMD document (see +[Section 6.2 of the Client ID Metadata Document draft](https://www.ietf.org/archive/id/draft-ietf-oauth-client-id-metadata-document-00.html#section-6.2)). +Any other registered method name is equally valid here. + +### Authorization Server Selection + +An authorization server registering a client computes the intersection +of the client's `token_endpoint_auth_methods_supported` array and +the methods the authorization server itself supports. + +If that intersection is empty, the authorization server **MUST** reject the +registration rather than falling back to a method the client did not +advertise. In particular, it **MUST NOT** assume `none` when the field is +present and non-empty but does not include it. + +This applies to the `["none"]` default for documents declaring no +authentication method as it does to an explicitly published array: an +authorization server that does not support public clients **MUST** reject +such a document rather than registering the client under some other method. + +### Deprecated Declarations + +Changing an established metadata field in a widely deployed mechanism needs a +managed transition rather than an immediate cutover, and MCP already has a +pattern for exactly this. Dynamic Client Registration is deprecated in favor +of Client ID Metadata Documents, but remains permitted and is "retained for +backwards compatibility with authorization servers that do not support Client +ID Metadata Documents," with a removal date governed by the +[feature lifecycle policy](/community/feature-lifecycle). + +This SEP applies the same treatment to the two ways a CIMD document can +currently avoid declaring its authentication methods explicitly. Both are +**deprecated**, both remain permitted for now, and both migrate to +`token_endpoint_auth_methods_supported`: + +1. **The singular `token_endpoint_auth_method` parameter**, retained for + backwards compatibility with authorization servers that do not support the + array. +2. **Declaring no authentication method at all**, retained for backwards + compatibility with documents published before the array was required. + +- Clients **MUST** publish `token_endpoint_auth_methods_supported`. +- Clients **SHOULD** additionally publish `token_endpoint_auth_method`, set + to their preferred single value from that array, for as long as the field + remains deprecated rather than removed. This follows + [OpenID Connect RP Metadata Choices 1.0, Section 2](https://openid.net/specs/openid-connect-rp-metadata-choices-1_0-final.html): + + > To facilitate interoperability with implementations not supporting this + > specification, deployments SHOULD include the single-valued metadata + > parameter alongside the corresponding multi-valued metadata parameter with + > their preferred single value. + +- Authorization servers **MUST** prefer `token_endpoint_auth_methods_supported` + when it is present, and **MUST NOT** let a present-but-conflicting + `token_endpoint_auth_method` override it. +- Authorization servers **MAY** fall back to `token_endpoint_auth_method` + when the multi-valued parameter is absent — for example, when reading a + document published before this requirement took effect. +- Authorization servers **MUST** treat a document carrying neither parameter + as declaring `["none"]` until the deprecation period elapses, and **MUST** + reject such a document thereafter. + +### Lifecycle + +Per the [feature lifecycle policy](/community/feature-lifecycle), this SEP +proposes the following deprecation entries: + +| Feature | Deprecation SEP | Deprecated in | Migration path | Earliest removal | +| ---------------------------------------------- | --------------- | --------------------- | --------------------------------------- | ------------------------------------------------------------- | +| `token_endpoint_auth_method` | SEP-0000 | _(revision on merge)_ | `token_endpoint_auth_methods_supported` | First revision released on or after one year from deprecation | +| Implicit `none` for documents declaring no method | SEP-0000 | _(revision on merge)_ | `token_endpoint_auth_methods_supported` | First revision released on or after one year from deprecation | + + +## Rationale + +`token_endpoint_auth_methods_supported` was chosen over inventing an +MCP-specific field name because it is already the standard name for this +capability within OAuth/OpenID ecosystems. + +This SEP intentionally does not recommend a specific set of authentication +methods. Which methods a client can support is determined by its deployment +model, and a blanket recommendation would be wrong for some large class of +clients. + +The field is required (MUST) rather than recommended (SHOULD) because explicit +behavior is crucial for authentication mechanisms. A required field gives +servers a single place to look and makes conformance checkable. The cost — +that existing documents must add one property — is trivial. + +### Alternatives considered + +Making `token_endpoint_auth_methods_supported` optional (SHOULD) + +- Rejected. A SHOULD leaves authorization servers unable to depend on the + field, so they must keep consulting the singular field indefinitely and the + lowest-common-denominator problem persists for any client that skips it. + Requiring the field while deprecating (not removing) the old one achieves + the transition without an interoperability break. + + +Publishing multiple metadata documents, one per `token_endpoint_auth_method` + +- Rejected because it defeats the purpose of CIMD. The metadata URL *is* the + `client_id`, so publishing one document per authentication method splits a + single logical client into several distinct client identities. User consent + records, revocation, audit logs, and rate limits would fragment across + those identities, and the same application would appear to users as + different clients depending on which authorization server they connected + through. +- The maintenance burden compounds the problem: every additional method + multiplies the documents that must be hosted and kept in sync, and each new + method a client adopts changes the set of URLs it publishes. Declaring + capabilities in one document keeps the client's identity stable while its + capabilities evolve. + + +## Backward Compatibility + +In the revision this SEP lands in, the incompatibility is at the conformance +level only. No existing CIMD document stops working. + +**What changes.** CIMD documents that omit +`token_endpoint_auth_methods_supported` become non-conformant with that +revision. Every client publishing a CIMD document must add the property, even +if it only ever supported one authentication method. + +**What does not change, for now.** Every document that is valid today +continues to register successfully: + +- Documents omitting the array but declaring `token_endpoint_auth_method` + work via the fallback above. +- Documents declaring neither parameter are treated as `["none"]`, which is + the behavior authorization servers already implement in practice and the + posture those clients already had. +- Authorization servers that have not yet implemented the multi-valued + parameter keep working, because clients SHOULD continue publishing the + singular field. + +The immediate incompatibility is therefore a conformance obligation on +clients, not a runtime failure for either party, and non-conformant documents +degrade to their current behavior rather than being rejected. + +**What changes at removal.** Both accommodations are deprecated, so this is a +deferred break rather than an avoided one. When the deprecation period +elapses, a document that declares no authentication method is rejected instead +of read as `["none"]`, and clients that never added the array stop +registering. The window exists so that the fix — publishing one additional +property — can be made on the client's own schedule rather than under an +upgrade deadline. + +**Ordering.** Because the requirement lands on clients while the fallback +remains available to servers, deployments can migrate independently: a client +can add the array before any given server reads it, and a server can start +reading it before every client publishes it. Neither side needs to coordinate +with the other. + +## Security Implications + +This proposal does not introduce a new client authentication mechanism; it +only changes how a client advertises which existing, already-specified +authentication methods it supports. Because this SEP does not prescribe the +contents of the array, it does not itself raise or lower the authentication +strength of any deployment: authorization servers remain responsible for +rejecting clients whose advertised methods do not meet the server's +requirements. + +In aggregate this change is expected to improve authentication strength across +the ecosystem rather than weaken it. Today a client that supports strong +client authentication must still publish a single value acceptable to the +weakest authorization server it needs to work with; enumerating capabilities +lets servers that support a stronger method actually use it. + +## Reference Implementation + +**TODO** + +## Open Questions + +- Should `implicit ["none"]` and `token_endpoint_auth_method` be deprecated, or + should allowances be made to not break existing CIMD clients? + +## Acknowledgments + +TBD. From ea8641860f5600ceb2c5e42b2235ed376ccca1b0 Mon Sep 17 00:00:00 2001 From: Max Gerber Date: Mon, 27 Jul 2026 19:43:01 -0700 Subject: [PATCH 02/10] SEP-3149: assign PR number Rename from the 0000 placeholder and update the title, PR link, and lifecycle table entries per the PR-based SEP workflow. --- ...token-endpoint-auth-methods-supported-in-cimd.md} | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) rename seps/{0000-require-token-endpoint-auth-methods-supported-in-cimd.md => 3149-require-token-endpoint-auth-methods-supported-in-cimd.md} (93%) diff --git a/seps/0000-require-token-endpoint-auth-methods-supported-in-cimd.md b/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md similarity index 93% rename from seps/0000-require-token-endpoint-auth-methods-supported-in-cimd.md rename to seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md index 8361c5a51..5d9bfcaed 100644 --- a/seps/0000-require-token-endpoint-auth-methods-supported-in-cimd.md +++ b/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md @@ -1,11 +1,11 @@ -# SEP-0000: Require `token_endpoint_auth_methods_supported` in Client ID Metadata Documents +# SEP-3149: Require `token_endpoint_auth_methods_supported` in Client ID Metadata Documents - **Status**: Draft - **Type**: Standards Track - **Created**: 2026-07-27 - **Author(s)**: @max-stytch - **Sponsor**: @pcarleton -- **PR**: https://github.com/modelcontextprotocol/modelcontextprotocol/pull/{NUMBER} +- **PR**: https://github.com/modelcontextprotocol/modelcontextprotocol/pull/3149 ## Abstract @@ -156,10 +156,10 @@ currently avoid declaring its authentication methods explicitly. Both are Per the [feature lifecycle policy](/community/feature-lifecycle), this SEP proposes the following deprecation entries: -| Feature | Deprecation SEP | Deprecated in | Migration path | Earliest removal | -| ---------------------------------------------- | --------------- | --------------------- | --------------------------------------- | ------------------------------------------------------------- | -| `token_endpoint_auth_method` | SEP-0000 | _(revision on merge)_ | `token_endpoint_auth_methods_supported` | First revision released on or after one year from deprecation | -| Implicit `none` for documents declaring no method | SEP-0000 | _(revision on merge)_ | `token_endpoint_auth_methods_supported` | First revision released on or after one year from deprecation | +| Feature | Deprecation SEP | Deprecated in | Migration path | Earliest removal | +| ------------------------------------------------- | --------------- | --------------------- | --------------------------------------- | ------------------------------------------------------------- | +| `token_endpoint_auth_method` | SEP-3149 | _(revision on merge)_ | `token_endpoint_auth_methods_supported` | First revision released on or after one year from deprecation | +| Implicit `none` for documents declaring no method | SEP-3149 | _(revision on merge)_ | `token_endpoint_auth_methods_supported` | First revision released on or after one year from deprecation | ## Rationale From 8bebfd988417fa7a8013a52e50864ebe96d52a14 Mon Sep 17 00:00:00 2001 From: Max Gerber Date: Mon, 27 Jul 2026 19:48:04 -0700 Subject: [PATCH 03/10] SEP-3149: format and generate SEP docs Apply Prettier formatting to the SEP and regenerate the rendered SEP documentation, navigation, and index entries. --- docs/docs.json | 6 + ...ndpoint-auth-methods-supported-in-cimd.mdx | 291 ++++++++++++++++++ docs/seps/index.mdx | 88 +++--- ...endpoint-auth-methods-supported-in-cimd.md | 15 +- 4 files changed, 348 insertions(+), 52 deletions(-) create mode 100644 docs/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.mdx diff --git a/docs/docs.json b/docs/docs.json index 74bcb9caa..d7e24d43c 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -458,6 +458,12 @@ "seps/2596-spec-feature-lifecycle-and-deprecation", "seps/2663-tasks-extension" ] + }, + { + "group": "Draft", + "pages": [ + "seps/3149-require-token-endpoint-auth-methods-supported-in-cimd" + ] } ] }, diff --git a/docs/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.mdx b/docs/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.mdx new file mode 100644 index 000000000..90ee19de8 --- /dev/null +++ b/docs/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.mdx @@ -0,0 +1,291 @@ +--- +title: "SEP-3149: Require `token_endpoint_auth_methods_supported` in Client ID Metadata Documents" +sidebarTitle: "SEP-3149: Require `token_endpoint_auth_methods_su…" +description: "Require `token_endpoint_auth_methods_supported` in Client ID Metadata Documents" +--- + +
+ + Draft + + + Standards Track + +
+ +| Field | Value | +| ------------- | ------------------------------------------------------------------------------- | +| **SEP** | 3149 | +| **Title** | Require `token_endpoint_auth_methods_supported` in Client ID Metadata Documents | +| **Status** | Draft | +| **Type** | Standards Track | +| **Created** | 2026-07-27 | +| **Author(s)** | [@max-stytch](https://github.com/max-stytch) | +| **Sponsor** | [@pcarleton](https://github.com/pcarleton) | +| **PR** | [#3149](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/3149) | + +--- + +## Abstract + +This SEP makes the `token_endpoint_auth_methods_supported` metadata parameter +a required property of MCP Client ID Metadata Documents (CIMD), and creates a +deprecation path for the singular `token_endpoint_auth_method` parameter, +mirroring the guidance in [OpenID Connect RP Metadata Choices 1.0](https://openid.net/specs/openid-connect-rp-metadata-choices-1_0-final.html). +This enables a CIMD document to be published once and consumed by many +authorization servers with differing capabilities. It also deprecates the +implicit public-client default that applies when a document declares no +authentication method at all. Both deprecations point at the same end state: +every CIMD document declares its authentication methods explicitly in +`token_endpoint_auth_methods_supported`. This SEP is agnostic about which +authentication methods a given client advertises. It specifies the shape +and handling of the field, not its contents. + +## Motivation + +MCP's Client ID Metadata Document mechanism, introduced in +[SEP-991](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/991-enable-url-based-client-registration-using-oauth-c.md), +carried over the singular `token_endpoint_auth_method` from RFC 7591 client +metadata. It appears in the specification today only in an example document, +never in normative prose. + +A CIMD document is published at a single URL and consumed by every +authorization server the client ever connects to, and those servers do not +have uniform capabilities. Some support `private_key_jwt`; many accept only +public clients. A single-valued `token_endpoint_auth_method` gives a client no +way to express "either, depending on what you support." In practice that +forces the lowest common denominator: the client is forced to publish `none`, and the +servers that _could_ have required a signed assertion never learn the client +was capable of one. + +The broader OAuth/OIDC ecosystem has already solved this capability +negotiation problem by moving from single-valued to multi-valued parameters. +RP Metadata Choices 1.0 supplements `token_endpoint_auth_method` with +`token_endpoint_auth_methods_supported`, and RFC 8414 uses that same name for +the mirror-image capability on the authorization server. Adopting it in CIMD +documents brings MCP in line with both. + +## Specification + +### CIMD Document Requirements + +MCP clients publishing a Client ID Metadata Document **MUST** include the +`token_endpoint_auth_methods_supported` metadata parameter. Its value is a +JSON array of strings drawn from the +[OAuth Token Endpoint Authentication Methods registry](https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#token-endpoint-auth-method) +established by [RFC 7591 Section 4.2](https://datatracker.ietf.org/doc/html/rfc7591#section-4.2). + +This extends the metadata document's required-property list in +[Client Registration](/specification/draft/basic/authorization/client-registration), +which currently reads: + +> The metadata document **MUST** include at least the following properties: +> `client_id`, `client_name`, `redirect_uris` + +The array **MUST** contain one or more authentication methods the client supports, in no particular order of preference. + +Authorization servers **MUST** support reading +`token_endpoint_auth_methods_supported` from a CIMD document. Documents that +omit it are handled as described in +[Deprecated Declarations](#deprecated-declarations). + +A document that carries **neither** parameter **MUST** be treated as declaring +`["none"]` — that is, as a public client. This default is itself **deprecated** +and exists only for compatibility: neither parameter is required by the +specification today, so documents omitting both are conformant under the +current revision and remain in wide use. Once the deprecation period elapses, +such a document is invalid and authorization servers reject it rather than +inferring a method. + +For illustration, a client that can operate either as a public client or with +an assertion-based credential might publish: + +```json +"token_endpoint_auth_methods_supported": ["none", "private_key_jwt"] +``` + +Here `none` indicates the client can act as a public client with no client +authentication at the token endpoint, and `private_key_jwt` indicates it can +authenticate with a signed JWT assertion per +[RFC 7523](https://datatracker.ietf.org/doc/html/rfc7523), using the JWKS +referenced by the CIMD document (see +[Section 6.2 of the Client ID Metadata Document draft](https://www.ietf.org/archive/id/draft-ietf-oauth-client-id-metadata-document-00.html#section-6.2)). +Any other registered method name is equally valid here. + +### Authorization Server Selection + +An authorization server registering a client computes the intersection +of the client's `token_endpoint_auth_methods_supported` array and +the methods the authorization server itself supports. + +If that intersection is empty, the authorization server **MUST** reject the +registration rather than falling back to a method the client did not +advertise. In particular, it **MUST NOT** assume `none` when the field is +present and non-empty but does not include it. + +This applies to the `["none"]` default for documents declaring no +authentication method as it does to an explicitly published array: an +authorization server that does not support public clients **MUST** reject +such a document rather than registering the client under some other method. + +### Deprecated Declarations + +Changing an established metadata field in a widely deployed mechanism needs a +managed transition rather than an immediate cutover, and MCP already has a +pattern for exactly this. Dynamic Client Registration is deprecated in favor +of Client ID Metadata Documents, but remains permitted and is "retained for +backwards compatibility with authorization servers that do not support Client +ID Metadata Documents," with a removal date governed by the +[feature lifecycle policy](/community/feature-lifecycle). + +This SEP applies the same treatment to the two ways a CIMD document can +currently avoid declaring its authentication methods explicitly. Both are +**deprecated**, both remain permitted for now, and both migrate to +`token_endpoint_auth_methods_supported`: + +1. **The singular `token_endpoint_auth_method` parameter**, retained for + backwards compatibility with authorization servers that do not support the + array. +2. **Declaring no authentication method at all**, retained for backwards + compatibility with documents published before the array was required. + +- Clients **MUST** publish `token_endpoint_auth_methods_supported`. +- Clients **SHOULD** additionally publish `token_endpoint_auth_method`, set + to their preferred single value from that array, for as long as the field + remains deprecated rather than removed. This follows + [OpenID Connect RP Metadata Choices 1.0, Section 2](https://openid.net/specs/openid-connect-rp-metadata-choices-1_0-final.html): + + > To facilitate interoperability with implementations not supporting this + > specification, deployments SHOULD include the single-valued metadata + > parameter alongside the corresponding multi-valued metadata parameter with + > their preferred single value. + +- Authorization servers **MUST** prefer `token_endpoint_auth_methods_supported` + when it is present, and **MUST NOT** let a present-but-conflicting + `token_endpoint_auth_method` override it. +- Authorization servers **MAY** fall back to `token_endpoint_auth_method` + when the multi-valued parameter is absent — for example, when reading a + document published before this requirement took effect. +- Authorization servers **MUST** treat a document carrying neither parameter + as declaring `["none"]` until the deprecation period elapses, and **MUST** + reject such a document thereafter. + +### Lifecycle + +Per the [feature lifecycle policy](/community/feature-lifecycle), this SEP +proposes the following deprecation entries: + +| Feature | Deprecation SEP | Deprecated in | Migration path | Earliest removal | +| ------------------------------------------------- | --------------- | --------------------- | --------------------------------------- | ------------------------------------------------------------- | +| `token_endpoint_auth_method` | SEP-3149 | _(revision on merge)_ | `token_endpoint_auth_methods_supported` | First revision released on or after one year from deprecation | +| Implicit `none` for documents declaring no method | SEP-3149 | _(revision on merge)_ | `token_endpoint_auth_methods_supported` | First revision released on or after one year from deprecation | + +## Rationale + +`token_endpoint_auth_methods_supported` was chosen over inventing an +MCP-specific field name because it is already the standard name for this +capability within OAuth/OpenID ecosystems. + +This SEP intentionally does not recommend a specific set of authentication +methods. Which methods a client can support is determined by its deployment +model, and a blanket recommendation would be wrong for some large class of +clients. + +The field is required (MUST) rather than recommended (SHOULD) because explicit +behavior is crucial for authentication mechanisms. A required field gives +servers a single place to look and makes conformance checkable. The cost — +that existing documents must add one property — is trivial. + +### Alternatives considered + +Making `token_endpoint_auth_methods_supported` optional (SHOULD) + +- Rejected. A SHOULD leaves authorization servers unable to depend on the + field, so they must keep consulting the singular field indefinitely and the + lowest-common-denominator problem persists for any client that skips it. + Requiring the field while deprecating (not removing) the old one achieves + the transition without an interoperability break. + +Publishing multiple metadata documents, one per `token_endpoint_auth_method` + +- Rejected because it defeats the purpose of CIMD. The metadata URL _is_ the + `client_id`, so publishing one document per authentication method splits a + single logical client into several distinct client identities. User consent + records, revocation, audit logs, and rate limits would fragment across + those identities, and the same application would appear to users as + different clients depending on which authorization server they connected + through. +- The maintenance burden compounds the problem: every additional method + multiplies the documents that must be hosted and kept in sync, and each new + method a client adopts changes the set of URLs it publishes. Declaring + capabilities in one document keeps the client's identity stable while its + capabilities evolve. + +## Backward Compatibility + +In the revision this SEP lands in, the incompatibility is at the conformance +level only. No existing CIMD document stops working. + +**What changes.** CIMD documents that omit +`token_endpoint_auth_methods_supported` become non-conformant with that +revision. Every client publishing a CIMD document must add the property, even +if it only ever supported one authentication method. + +**What does not change, for now.** Every document that is valid today +continues to register successfully: + +- Documents omitting the array but declaring `token_endpoint_auth_method` + work via the fallback above. +- Documents declaring neither parameter are treated as `["none"]`, which is + the behavior authorization servers already implement in practice and the + posture those clients already had. +- Authorization servers that have not yet implemented the multi-valued + parameter keep working, because clients SHOULD continue publishing the + singular field. + +The immediate incompatibility is therefore a conformance obligation on +clients, not a runtime failure for either party, and non-conformant documents +degrade to their current behavior rather than being rejected. + +**What changes at removal.** Both accommodations are deprecated, so this is a +deferred break rather than an avoided one. When the deprecation period +elapses, a document that declares no authentication method is rejected instead +of read as `["none"]`, and clients that never added the array stop +registering. The window exists so that the fix — publishing one additional +property — can be made on the client's own schedule rather than under an +upgrade deadline. + +**Ordering.** Because the requirement lands on clients while the fallback +remains available to servers, deployments can migrate independently: a client +can add the array before any given server reads it, and a server can start +reading it before every client publishes it. Neither side needs to coordinate +with the other. + +## Security Implications + +This proposal does not introduce a new client authentication mechanism; it +only changes how a client advertises which existing, already-specified +authentication methods it supports. Because this SEP does not prescribe the +contents of the array, it does not itself raise or lower the authentication +strength of any deployment: authorization servers remain responsible for +rejecting clients whose advertised methods do not meet the server's +requirements. + +In aggregate this change is expected to improve authentication strength across +the ecosystem rather than weaken it. Today a client that supports strong +client authentication must still publish a single value acceptable to the +weakest authorization server it needs to work with; enumerating capabilities +lets servers that support a stronger method actually use it. + +## Reference Implementation + +**TODO** + +## Open Questions + +- Should `implicit ["none"]` and `token_endpoint_auth_method` be deprecated, or + should allowances be made to not break existing CIMD clients? + +## Acknowledgments + +TBD. diff --git a/docs/seps/index.mdx b/docs/seps/index.mdx index 658464479..351aa78b4 100644 --- a/docs/seps/index.mdx +++ b/docs/seps/index.mdx @@ -12,53 +12,55 @@ Specification Enhancement Proposals (SEPs) are the primary mechanism for proposi ## Summary +- **Draft**: 1 - **Final**: 41 ## All SEPs -| SEP | Title | Status | Type | Created | -| ------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------- | ----------------------------------------------- | ---------------- | ---------- | -| [SEP-2663](/seps/2663-tasks-extension) | Tasks Extension | Final | Extensions Track | 2026-04-27 | -| [SEP-2596](/seps/2596-spec-feature-lifecycle-and-deprecation) | Specification Feature Lifecycle and Deprecation Policy | Final | Process | 2026-04-17 | -| [SEP-2577](/seps/2577-deprecate-roots-sampling-and-logging) | Deprecate Roots, Sampling, and Logging | Final | Standards Track | 2026-04-14 | -| [SEP-2575](/seps/2575-stateless-mcp) | Make MCP Stateless | Final | Standards Track | 2025-06-18 | -| [SEP-2567](/seps/2567-sessionless-mcp) | Sessionless MCP via Explicit State Handles | Final | Standards Track | 2026-03-11 | -| [SEP-2549](/seps/2549-TTL-for-list-results) | TTL for List Results | Final | Standards Track | 2026-04-09 | -| [SEP-2484](/seps/2484-conformance-tests-required-for-final-seps) | Require Conformance Tests for Standards Track SEPs to Reach Final Status | Final | Process | 2026-03-27 | -| [SEP-2468](/seps/2468-recommend-issuer-claim-for-auth) | Recommend Issuer (iss) Parameter in MCP Auth Responses | Final | Standards Track | 2026-03-25 | -| [SEP-2322](/seps/2322-MRTR) | Multi Round-Trip Requests | Final | Standards Track | 2026-02-03 | -| [SEP-2260](/seps/2260-Require-Server-requests-to-be-associated-with-Client-requests) | Require Server requests to be associated with a Client request. | Final | Standards Track | 2026-02-16 | -| [SEP-2243](/seps/2243-http-standardization) | HTTP Header Standardization for Streamable HTTP Transport | Final | Standards Track | 2026-02-04 | -| [SEP-2207](/seps/2207-oidc-refresh-token-guidance) | OIDC-Flavored Refresh Token Guidance | Final | Standards Track | 2026-02-04 | -| [SEP-2164](/seps/2164-resource-not-found-error) | Standardize Resource Not Found Error Code | Final | Standards Track | 2026-01-28 | -| [SEP-2149](/seps/2149-working-group-charter-template) | MCP Group Governance and Charter Template | Final | Process | 2025-01-15 | -| [SEP-2148](/seps/2148-contributor-ladder) | MCP Contributor Ladder | Final | Process | 2026-01-15 | -| [SEP-2133](/seps/2133-extensions) | Extensions | Final | Standards Track | 2025-01-21 | -| [SEP-2106](/seps/2106-json-schema-2020-12) | Tools `inputSchema` & `outputSchema` Conform to JSON Schema 2020-12 | Final | Standards Track | 2026-01-06 | -| [SEP-2085](/seps/2085-governance-succession-and-amendment) | Governance Succession and Amendment Procedures | Final | Process | 2025-12-05 | -| [SEP-1865](/seps/1865-mcp-apps-interactive-user-interfaces-for-mcp) | MCP Apps - Interactive User Interfaces for MCP | Final | Extensions Track | 2025-11-21 | -| [SEP-1850](/seps/1850-pr-based-sep-workflow) | PR-Based SEP Workflow | Final | Process | 2025-11-20 | -| [SEP-1730](/seps/1730-sdks-tiering-system) | SDKs Tiering System | Final | Standards Track | 2025-10-29 | -| [SEP-1699](/seps/1699-support-sse-polling-via-server-side-disconnect) | Support SSE polling via server-side disconnect | Final | Standards Track | 2025-10-22 | -| [SEP-1686](/seps/1686-tasks) | Tasks | Final | Standards Track | 2025-10-20 | -| [SEP-1613](/seps/1613-establish-json-schema-2020-12-as-default-dialect-f) | Establish JSON Schema 2020-12 as Default Dialect for MCP | Final | Standards Track | 2025-10-06 | -| [SEP-1577](/seps/1577--sampling-with-tools) | Sampling With Tools | Final | Standards Track | 2025-09-30 | -| [SEP-1330](/seps/1330-elicitation-enum-schema-improvements-and-standards) | Elicitation Enum Schema Improvements and Standards Compliance | Final | Standards Track | 2025-08-11 | -| [SEP-1319](/seps/1319-decouple-request-payload-from-rpc-methods-definiti) | Decouple Request Payload from RPC Methods Definition | Final | Standards Track | 2025-08-08 | -| [SEP-1303](/seps/1303-input-validation-errors-as-tool-execution-errors) | Input Validation Errors as Tool Execution Errors | Final | Standards Track | 2025-08-05 | -| [SEP-1302](/seps/1302-formalize-working-groups-and-interest-groups-in-mc) | Formalize Working Groups and Interest Groups in MCP Governance | Final | Standards Track | 2025-08-05 | -| [SEP-1046](/seps/1046-support-oauth-client-credentials-flow-in-authoriza) | Support OAuth client credentials flow in authorization | Final | Standards Track | 2025-07-23 | -| [SEP-1036](/seps/1036-url-mode-elicitation-for-secure-out-of-band-intera) | URL Mode Elicitation for secure out-of-band interactions | Final | Standards Track | 2025-07-22 | -| [SEP-1034](/seps/1034--support-default-values-for-all-primitive-types-in) | Support default values for all primitive types in elicitation schemas | Final | Standards Track | 2025-07-22 | -| [SEP-1024](/seps/1024-mcp-client-security-requirements-for-local-server-) | MCP Client Security Requirements for Local Server Installation | Final | Standards Track | 2025-07-22 | -| [SEP-994](/seps/994-shared-communication-practicesguidelines) | Shared Communication Practices/Guidelines | Final | Process | 2025-07-17 | -| [SEP-991](/seps/991-enable-url-based-client-registration-using-oauth-c) | Enable URL-based Client Registration using OAuth Client ID Metadata Documents | Final | Standards Track | 2025-07-07 | -| [SEP-990](/seps/990-enable-enterprise-idp-policy-controls-during-mcp-o) | Enable enterprise IdP policy controls during MCP OAuth flows | Final | Standards Track | 2025-06-04 | -| [SEP-986](/seps/986-specify-format-for-tool-names) | Specify Format for Tool Names | Final | Standards Track | 2025-07-16 | -| [SEP-985](/seps/985-align-oauth-20-protected-resource-metadata-with-rf) | Align OAuth 2.0 Protected Resource Metadata with RFC 9728 | Final | Standards Track | 2025-07-16 | -| [SEP-973](/seps/973-expose-additional-metadata-for-implementations-res) | Expose additional metadata for Implementations, Resources, Tools and Prompts | Final | Standards Track | 2025-07-15 | -| [SEP-932](/seps/932-model-context-protocol-governance) | Model Context Protocol Governance | Final | Process | 2025-07-08 | -| [SEP-414](/seps/414-request-meta) | Document OpenTelemetry Trace Context Propagation Conventions | Final | Standards Track | 2025-04-25 | +| SEP | Title | Status | Type | Created | +| ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------- | ----------------------------------------------- | ---------------- | ---------- | +| [SEP-3149](/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd) | Require `token_endpoint_auth_methods_supported` in Client ID Metadata Documents | Draft | Standards Track | 2026-07-27 | +| [SEP-2663](/seps/2663-tasks-extension) | Tasks Extension | Final | Extensions Track | 2026-04-27 | +| [SEP-2596](/seps/2596-spec-feature-lifecycle-and-deprecation) | Specification Feature Lifecycle and Deprecation Policy | Final | Process | 2026-04-17 | +| [SEP-2577](/seps/2577-deprecate-roots-sampling-and-logging) | Deprecate Roots, Sampling, and Logging | Final | Standards Track | 2026-04-14 | +| [SEP-2575](/seps/2575-stateless-mcp) | Make MCP Stateless | Final | Standards Track | 2025-06-18 | +| [SEP-2567](/seps/2567-sessionless-mcp) | Sessionless MCP via Explicit State Handles | Final | Standards Track | 2026-03-11 | +| [SEP-2549](/seps/2549-TTL-for-list-results) | TTL for List Results | Final | Standards Track | 2026-04-09 | +| [SEP-2484](/seps/2484-conformance-tests-required-for-final-seps) | Require Conformance Tests for Standards Track SEPs to Reach Final Status | Final | Process | 2026-03-27 | +| [SEP-2468](/seps/2468-recommend-issuer-claim-for-auth) | Recommend Issuer (iss) Parameter in MCP Auth Responses | Final | Standards Track | 2026-03-25 | +| [SEP-2322](/seps/2322-MRTR) | Multi Round-Trip Requests | Final | Standards Track | 2026-02-03 | +| [SEP-2260](/seps/2260-Require-Server-requests-to-be-associated-with-Client-requests) | Require Server requests to be associated with a Client request. | Final | Standards Track | 2026-02-16 | +| [SEP-2243](/seps/2243-http-standardization) | HTTP Header Standardization for Streamable HTTP Transport | Final | Standards Track | 2026-02-04 | +| [SEP-2207](/seps/2207-oidc-refresh-token-guidance) | OIDC-Flavored Refresh Token Guidance | Final | Standards Track | 2026-02-04 | +| [SEP-2164](/seps/2164-resource-not-found-error) | Standardize Resource Not Found Error Code | Final | Standards Track | 2026-01-28 | +| [SEP-2149](/seps/2149-working-group-charter-template) | MCP Group Governance and Charter Template | Final | Process | 2025-01-15 | +| [SEP-2148](/seps/2148-contributor-ladder) | MCP Contributor Ladder | Final | Process | 2026-01-15 | +| [SEP-2133](/seps/2133-extensions) | Extensions | Final | Standards Track | 2025-01-21 | +| [SEP-2106](/seps/2106-json-schema-2020-12) | Tools `inputSchema` & `outputSchema` Conform to JSON Schema 2020-12 | Final | Standards Track | 2026-01-06 | +| [SEP-2085](/seps/2085-governance-succession-and-amendment) | Governance Succession and Amendment Procedures | Final | Process | 2025-12-05 | +| [SEP-1865](/seps/1865-mcp-apps-interactive-user-interfaces-for-mcp) | MCP Apps - Interactive User Interfaces for MCP | Final | Extensions Track | 2025-11-21 | +| [SEP-1850](/seps/1850-pr-based-sep-workflow) | PR-Based SEP Workflow | Final | Process | 2025-11-20 | +| [SEP-1730](/seps/1730-sdks-tiering-system) | SDKs Tiering System | Final | Standards Track | 2025-10-29 | +| [SEP-1699](/seps/1699-support-sse-polling-via-server-side-disconnect) | Support SSE polling via server-side disconnect | Final | Standards Track | 2025-10-22 | +| [SEP-1686](/seps/1686-tasks) | Tasks | Final | Standards Track | 2025-10-20 | +| [SEP-1613](/seps/1613-establish-json-schema-2020-12-as-default-dialect-f) | Establish JSON Schema 2020-12 as Default Dialect for MCP | Final | Standards Track | 2025-10-06 | +| [SEP-1577](/seps/1577--sampling-with-tools) | Sampling With Tools | Final | Standards Track | 2025-09-30 | +| [SEP-1330](/seps/1330-elicitation-enum-schema-improvements-and-standards) | Elicitation Enum Schema Improvements and Standards Compliance | Final | Standards Track | 2025-08-11 | +| [SEP-1319](/seps/1319-decouple-request-payload-from-rpc-methods-definiti) | Decouple Request Payload from RPC Methods Definition | Final | Standards Track | 2025-08-08 | +| [SEP-1303](/seps/1303-input-validation-errors-as-tool-execution-errors) | Input Validation Errors as Tool Execution Errors | Final | Standards Track | 2025-08-05 | +| [SEP-1302](/seps/1302-formalize-working-groups-and-interest-groups-in-mc) | Formalize Working Groups and Interest Groups in MCP Governance | Final | Standards Track | 2025-08-05 | +| [SEP-1046](/seps/1046-support-oauth-client-credentials-flow-in-authoriza) | Support OAuth client credentials flow in authorization | Final | Standards Track | 2025-07-23 | +| [SEP-1036](/seps/1036-url-mode-elicitation-for-secure-out-of-band-intera) | URL Mode Elicitation for secure out-of-band interactions | Final | Standards Track | 2025-07-22 | +| [SEP-1034](/seps/1034--support-default-values-for-all-primitive-types-in) | Support default values for all primitive types in elicitation schemas | Final | Standards Track | 2025-07-22 | +| [SEP-1024](/seps/1024-mcp-client-security-requirements-for-local-server-) | MCP Client Security Requirements for Local Server Installation | Final | Standards Track | 2025-07-22 | +| [SEP-994](/seps/994-shared-communication-practicesguidelines) | Shared Communication Practices/Guidelines | Final | Process | 2025-07-17 | +| [SEP-991](/seps/991-enable-url-based-client-registration-using-oauth-c) | Enable URL-based Client Registration using OAuth Client ID Metadata Documents | Final | Standards Track | 2025-07-07 | +| [SEP-990](/seps/990-enable-enterprise-idp-policy-controls-during-mcp-o) | Enable enterprise IdP policy controls during MCP OAuth flows | Final | Standards Track | 2025-06-04 | +| [SEP-986](/seps/986-specify-format-for-tool-names) | Specify Format for Tool Names | Final | Standards Track | 2025-07-16 | +| [SEP-985](/seps/985-align-oauth-20-protected-resource-metadata-with-rf) | Align OAuth 2.0 Protected Resource Metadata with RFC 9728 | Final | Standards Track | 2025-07-16 | +| [SEP-973](/seps/973-expose-additional-metadata-for-implementations-res) | Expose additional metadata for Implementations, Resources, Tools and Prompts | Final | Standards Track | 2025-07-15 | +| [SEP-932](/seps/932-model-context-protocol-governance) | Model Context Protocol Governance | Final | Process | 2025-07-08 | +| [SEP-414](/seps/414-request-meta) | Document OpenTelemetry Trace Context Propagation Conventions | Final | Standards Track | 2025-04-25 | ## SEP Status Definitions diff --git a/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md b/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md index 5d9bfcaed..4af4a4c93 100644 --- a/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md +++ b/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md @@ -18,8 +18,8 @@ authorization servers with differing capabilities. It also deprecates the implicit public-client default that applies when a document declares no authentication method at all. Both deprecations point at the same end state: every CIMD document declares its authentication methods explicitly in -`token_endpoint_auth_methods_supported`. This SEP is agnostic about which -authentication methods a given client advertises. It specifies the shape +`token_endpoint_auth_methods_supported`. This SEP is agnostic about which +authentication methods a given client advertises. It specifies the shape and handling of the field, not its contents. ## Motivation @@ -36,7 +36,7 @@ have uniform capabilities. Some support `private_key_jwt`; many accept only public clients. A single-valued `token_endpoint_auth_method` gives a client no way to express "either, depending on what you support." In practice that forces the lowest common denominator: the client is forced to publish `none`, and the -servers that *could* have required a signed assertion never learn the client +servers that _could_ have required a signed assertion never learn the client was capable of one. The broader OAuth/OIDC ecosystem has already solved this capability @@ -95,7 +95,7 @@ Any other registered method name is equally valid here. ### Authorization Server Selection -An authorization server registering a client computes the intersection +An authorization server registering a client computes the intersection of the client's `token_endpoint_auth_methods_supported` array and the methods the authorization server itself supports. @@ -161,7 +161,6 @@ proposes the following deprecation entries: | `token_endpoint_auth_method` | SEP-3149 | _(revision on merge)_ | `token_endpoint_auth_methods_supported` | First revision released on or after one year from deprecation | | Implicit `none` for documents declaring no method | SEP-3149 | _(revision on merge)_ | `token_endpoint_auth_methods_supported` | First revision released on or after one year from deprecation | - ## Rationale `token_endpoint_auth_methods_supported` was chosen over inventing an @@ -188,10 +187,9 @@ Making `token_endpoint_auth_methods_supported` optional (SHOULD) Requiring the field while deprecating (not removing) the old one achieves the transition without an interoperability break. - Publishing multiple metadata documents, one per `token_endpoint_auth_method` -- Rejected because it defeats the purpose of CIMD. The metadata URL *is* the +- Rejected because it defeats the purpose of CIMD. The metadata URL _is_ the `client_id`, so publishing one document per authentication method splits a single logical client into several distinct client identities. User consent records, revocation, audit logs, and rate limits would fragment across @@ -204,7 +202,6 @@ Publishing multiple metadata documents, one per `token_endpoint_auth_method` capabilities in one document keeps the client's identity stable while its capabilities evolve. - ## Backward Compatibility In the revision this SEP lands in, the incompatibility is at the conformance @@ -267,7 +264,7 @@ lets servers that support a stronger method actually use it. ## Open Questions -- Should `implicit ["none"]` and `token_endpoint_auth_method` be deprecated, or +- Should `implicit ["none"]` and `token_endpoint_auth_method` be deprecated, or should allowances be made to not break existing CIMD clients? ## Acknowledgments From 5db590188381c786e1803573da7f613cf5077dff Mon Sep 17 00:00:00 2001 From: Steven Lee Date: Wed, 5 Aug 2026 20:03:39 +0000 Subject: [PATCH 04/10] SEP-3149: clarify auth method resolution --- ...ndpoint-auth-methods-supported-in-cimd.mdx | 81 ++++++++++++++++--- ...endpoint-auth-methods-supported-in-cimd.md | 81 ++++++++++++++++--- 2 files changed, 138 insertions(+), 24 deletions(-) diff --git a/docs/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.mdx b/docs/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.mdx index 90ee19de8..f51fa78ef 100644 --- a/docs/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.mdx +++ b/docs/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.mdx @@ -82,7 +82,12 @@ which currently reads: > The metadata document **MUST** include at least the following properties: > `client_id`, `client_name`, `redirect_uris` -The array **MUST** contain one or more authentication methods the client supports, in no particular order of preference. +The array **MUST** contain one or more authentication methods the client +supports, in no particular order of preference. The restrictions on token +endpoint authentication methods in the Client ID Metadata Document +specification continue to apply: the array **MUST NOT** include +`client_secret_post`, `client_secret_basic`, `client_secret_jwt`, or any other +method based around a shared symmetric secret. Authorization servers **MUST** support reading `token_endpoint_auth_methods_supported` from a CIMD document. Documents that @@ -110,24 +115,46 @@ authenticate with a signed JWT assertion per [RFC 7523](https://datatracker.ietf.org/doc/html/rfc7523), using the JWKS referenced by the CIMD document (see [Section 6.2 of the Client ID Metadata Document draft](https://www.ietf.org/archive/id/draft-ietf-oauth-client-id-metadata-document-00.html#section-6.2)). -Any other registered method name is equally valid here. +Other registered method names are valid only when they satisfy the +restrictions of the Client ID Metadata Document specification. -### Authorization Server Selection +### Method Resolution -An authorization server registering a client computes the intersection -of the client's `token_endpoint_auth_methods_supported` array and -the methods the authorization server itself supports. +The client and authorization server determine the set of mutually supported +token endpoint client authentication methods by intersecting the client's +`token_endpoint_auth_methods_supported` array with the authorization server's +`token_endpoint_auth_methods_supported` metadata value. -If that intersection is empty, the authorization server **MUST** reject the -registration rather than falling back to a method the client did not -advertise. In particular, it **MUST NOT** assume `none` when the field is -present and non-empty but does not include it. +For purposes of this resolution rule, `none` is unauthenticated and every +other permitted method is an authenticated client authentication method. + +If the intersection contains one or more authenticated client authentication +methods, the client **MUST** use one of those methods and **MUST NOT** use +`none`. The authorization server **MUST** reject a request using `none` for +that client when an authenticated method is mutually supported. When multiple +authenticated methods are mutually supported, the client **MAY** choose among +them. + +If the intersection contains no authenticated method but contains `none`, the +client **MAY** proceed using `none`. If the intersection is empty, the client +**MUST NOT** proceed and the authorization server **MUST** reject the client +rather than falling back to a method the client did not advertise. In +particular, an authorization server **MUST NOT** assume `none` when the field +is present and non-empty but does not include it. This applies to the `["none"]` default for documents declaring no authentication method as it does to an explicitly published array: an authorization server that does not support public clients **MUST** reject such a document rather than registering the client under some other method. +For example: + +| Client methods | Authorization server methods | Result | +| ----------------------------- | ----------------------------- | --------------------- | +| `["private_key_jwt", "none"]` | `["private_key_jwt", "none"]` | Use `private_key_jwt` | +| `["private_key_jwt", "none"]` | `["none"]` | Use `none` | +| `["private_key_jwt", "none"]` | `["client_secret_basic"]` | No compatible method | + ### Deprecated Declarations Changing an established metadata field in a widely deployed mechanism needs a @@ -161,8 +188,17 @@ currently avoid declaring its authentication methods explicitly. Both are > their preferred single value. - Authorization servers **MUST** prefer `token_endpoint_auth_methods_supported` - when it is present, and **MUST NOT** let a present-but-conflicting - `token_endpoint_auth_method` override it. + when it is present. When both parameters are present, + `token_endpoint_auth_method` **MUST** be a member of + `token_endpoint_auth_methods_supported`; otherwise the document is invalid. + Authorization servers **MUST NOT** let the singular parameter override the + array. +- Authorization servers that support the array **MAY** treat + `token_endpoint_auth_method` as the client's preferred method only when it + is mutually supported and does not conflict with the method resolution + requirements above. They **MUST NOT** reject a client solely because the + singular preferred method is unsupported when another method in the array + is mutually supported. - Authorization servers **MAY** fall back to `token_endpoint_auth_method` when the multi-valued parameter is absent — for example, when reading a document published before this requirement took effect. @@ -191,6 +227,14 @@ methods. Which methods a client can support is determined by its deployment model, and a blanket recommendation would be wrong for some large class of clients. +The method resolution rule distinguishes only between `none` and authenticated +client authentication methods. Treating `none` as a peer choice when an +authenticated method is mutually supported would make the client's security +posture equivalent to the weaker, unauthenticated option. The SEP does not +define a global ordering among authenticated methods; when more than one is +mutually supported, the client can choose without requiring an authorization +server to select a method and communicate that choice back to the client. + The field is required (MUST) rather than recommended (SHOULD) because explicit behavior is crucial for authentication mechanisms. A required field gives servers a single place to look and makes conformance checkable. The cost — @@ -243,6 +287,13 @@ continues to register successfully: parameter keep working, because clients SHOULD continue publishing the singular field. +The singular field cannot communicate fallback choices to an authorization +server that does not understand the array. A client whose singular value is +`private_key_jwt` can therefore be rejected by a legacy authorization server +that only supports `none`, even when the array also contains `none`. This is +an inherent limitation of the legacy single-valued field; authorization +servers that understand the array use the method resolution rules above. + The immediate incompatibility is therefore a conformance obligation on clients, not a runtime failure for either party, and non-conformant documents degrade to their current behavior rather than being rejected. @@ -277,6 +328,12 @@ client authentication must still publish a single value acceptable to the weakest authorization server it needs to work with; enumerating capabilities lets servers that support a stronger method actually use it. +An authorization server **MUST NOT** accept `none` for a client when an +authenticated client authentication method is mutually supported. Otherwise, +an attacker could choose `none` for the same client identifier and bypass the +stronger authentication method, making the effective security posture no +stronger than that of a public client. + ## Reference Implementation **TODO** diff --git a/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md b/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md index 4af4a4c93..886bdb766 100644 --- a/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md +++ b/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md @@ -63,7 +63,12 @@ which currently reads: > The metadata document **MUST** include at least the following properties: > `client_id`, `client_name`, `redirect_uris` -The array **MUST** contain one or more authentication methods the client supports, in no particular order of preference. +The array **MUST** contain one or more authentication methods the client +supports, in no particular order of preference. The restrictions on token +endpoint authentication methods in the Client ID Metadata Document +specification continue to apply: the array **MUST NOT** include +`client_secret_post`, `client_secret_basic`, `client_secret_jwt`, or any other +method based around a shared symmetric secret. Authorization servers **MUST** support reading `token_endpoint_auth_methods_supported` from a CIMD document. Documents that @@ -91,24 +96,46 @@ authenticate with a signed JWT assertion per [RFC 7523](https://datatracker.ietf.org/doc/html/rfc7523), using the JWKS referenced by the CIMD document (see [Section 6.2 of the Client ID Metadata Document draft](https://www.ietf.org/archive/id/draft-ietf-oauth-client-id-metadata-document-00.html#section-6.2)). -Any other registered method name is equally valid here. +Other registered method names are valid only when they satisfy the +restrictions of the Client ID Metadata Document specification. -### Authorization Server Selection +### Method Resolution -An authorization server registering a client computes the intersection -of the client's `token_endpoint_auth_methods_supported` array and -the methods the authorization server itself supports. +The client and authorization server determine the set of mutually supported +token endpoint client authentication methods by intersecting the client's +`token_endpoint_auth_methods_supported` array with the authorization server's +`token_endpoint_auth_methods_supported` metadata value. -If that intersection is empty, the authorization server **MUST** reject the -registration rather than falling back to a method the client did not -advertise. In particular, it **MUST NOT** assume `none` when the field is -present and non-empty but does not include it. +For purposes of this resolution rule, `none` is unauthenticated and every +other permitted method is an authenticated client authentication method. + +If the intersection contains one or more authenticated client authentication +methods, the client **MUST** use one of those methods and **MUST NOT** use +`none`. The authorization server **MUST** reject a request using `none` for +that client when an authenticated method is mutually supported. When multiple +authenticated methods are mutually supported, the client **MAY** choose among +them. + +If the intersection contains no authenticated method but contains `none`, the +client **MAY** proceed using `none`. If the intersection is empty, the client +**MUST NOT** proceed and the authorization server **MUST** reject the client +rather than falling back to a method the client did not advertise. In +particular, an authorization server **MUST NOT** assume `none` when the field +is present and non-empty but does not include it. This applies to the `["none"]` default for documents declaring no authentication method as it does to an explicitly published array: an authorization server that does not support public clients **MUST** reject such a document rather than registering the client under some other method. +For example: + +| Client methods | Authorization server methods | Result | +| ----------------------------- | ----------------------------- | --------------------- | +| `["private_key_jwt", "none"]` | `["private_key_jwt", "none"]` | Use `private_key_jwt` | +| `["private_key_jwt", "none"]` | `["none"]` | Use `none` | +| `["private_key_jwt", "none"]` | `["client_secret_basic"]` | No compatible method | + ### Deprecated Declarations Changing an established metadata field in a widely deployed mechanism needs a @@ -142,8 +169,17 @@ currently avoid declaring its authentication methods explicitly. Both are > their preferred single value. - Authorization servers **MUST** prefer `token_endpoint_auth_methods_supported` - when it is present, and **MUST NOT** let a present-but-conflicting - `token_endpoint_auth_method` override it. + when it is present. When both parameters are present, + `token_endpoint_auth_method` **MUST** be a member of + `token_endpoint_auth_methods_supported`; otherwise the document is invalid. + Authorization servers **MUST NOT** let the singular parameter override the + array. +- Authorization servers that support the array **MAY** treat + `token_endpoint_auth_method` as the client's preferred method only when it + is mutually supported and does not conflict with the method resolution + requirements above. They **MUST NOT** reject a client solely because the + singular preferred method is unsupported when another method in the array + is mutually supported. - Authorization servers **MAY** fall back to `token_endpoint_auth_method` when the multi-valued parameter is absent — for example, when reading a document published before this requirement took effect. @@ -172,6 +208,14 @@ methods. Which methods a client can support is determined by its deployment model, and a blanket recommendation would be wrong for some large class of clients. +The method resolution rule distinguishes only between `none` and authenticated +client authentication methods. Treating `none` as a peer choice when an +authenticated method is mutually supported would make the client's security +posture equivalent to the weaker, unauthenticated option. The SEP does not +define a global ordering among authenticated methods; when more than one is +mutually supported, the client can choose without requiring an authorization +server to select a method and communicate that choice back to the client. + The field is required (MUST) rather than recommended (SHOULD) because explicit behavior is crucial for authentication mechanisms. A required field gives servers a single place to look and makes conformance checkable. The cost — @@ -224,6 +268,13 @@ continues to register successfully: parameter keep working, because clients SHOULD continue publishing the singular field. +The singular field cannot communicate fallback choices to an authorization +server that does not understand the array. A client whose singular value is +`private_key_jwt` can therefore be rejected by a legacy authorization server +that only supports `none`, even when the array also contains `none`. This is +an inherent limitation of the legacy single-valued field; authorization +servers that understand the array use the method resolution rules above. + The immediate incompatibility is therefore a conformance obligation on clients, not a runtime failure for either party, and non-conformant documents degrade to their current behavior rather than being rejected. @@ -258,6 +309,12 @@ client authentication must still publish a single value acceptable to the weakest authorization server it needs to work with; enumerating capabilities lets servers that support a stronger method actually use it. +An authorization server **MUST NOT** accept `none` for a client when an +authenticated client authentication method is mutually supported. Otherwise, +an attacker could choose `none` for the same client identifier and bypass the +stronger authentication method, making the effective security posture no +stronger than that of a public client. + ## Reference Implementation **TODO** From c36655b4dd7e402f79a50c6458c4eecb28449870 Mon Sep 17 00:00:00 2001 From: Steven Lee Date: Wed, 5 Aug 2026 20:16:52 +0000 Subject: [PATCH 05/10] SEP-3149: simplify wording and cite live CIMD --- ...ndpoint-auth-methods-supported-in-cimd.mdx | 125 ++++++------------ ...endpoint-auth-methods-supported-in-cimd.md | 125 ++++++------------ 2 files changed, 76 insertions(+), 174 deletions(-) diff --git a/docs/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.mdx b/docs/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.mdx index f51fa78ef..020d8c6af 100644 --- a/docs/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.mdx +++ b/docs/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.mdx @@ -94,14 +94,6 @@ Authorization servers **MUST** support reading omit it are handled as described in [Deprecated Declarations](#deprecated-declarations). -A document that carries **neither** parameter **MUST** be treated as declaring -`["none"]` — that is, as a public client. This default is itself **deprecated** -and exists only for compatibility: neither parameter is required by the -specification today, so documents omitting both are conformant under the -current revision and remain in wide use. Once the deprecation period elapses, -such a document is invalid and authorization servers reject it rather than -inferring a method. - For illustration, a client that can operate either as a public client or with an assertion-based credential might publish: @@ -115,8 +107,6 @@ authenticate with a signed JWT assertion per [RFC 7523](https://datatracker.ietf.org/doc/html/rfc7523), using the JWKS referenced by the CIMD document (see [Section 6.2 of the Client ID Metadata Document draft](https://www.ietf.org/archive/id/draft-ietf-oauth-client-id-metadata-document-00.html#section-6.2)). -Other registered method names are valid only when they satisfy the -restrictions of the Client ID Metadata Document specification. ### Method Resolution @@ -125,27 +115,16 @@ token endpoint client authentication methods by intersecting the client's `token_endpoint_auth_methods_supported` array with the authorization server's `token_endpoint_auth_methods_supported` metadata value. -For purposes of this resolution rule, `none` is unauthenticated and every -other permitted method is an authenticated client authentication method. - -If the intersection contains one or more authenticated client authentication -methods, the client **MUST** use one of those methods and **MUST NOT** use -`none`. The authorization server **MUST** reject a request using `none` for -that client when an authenticated method is mutually supported. When multiple -authenticated methods are mutually supported, the client **MAY** choose among -them. +For this rule, `none` is unauthenticated; all other permitted methods are +authenticated. -If the intersection contains no authenticated method but contains `none`, the -client **MAY** proceed using `none`. If the intersection is empty, the client -**MUST NOT** proceed and the authorization server **MUST** reject the client -rather than falling back to a method the client did not advertise. In -particular, an authorization server **MUST NOT** assume `none` when the field -is present and non-empty but does not include it. - -This applies to the `["none"]` default for documents declaring no -authentication method as it does to an explicitly published array: an -authorization server that does not support public clients **MUST** reject -such a document rather than registering the client under some other method. +- If the intersection contains an authenticated method, the client **MUST** + use one such method, and the authorization server **MUST** reject `none`. + When multiple authenticated methods are available, the client **MAY** choose + among them. +- If `none` is the only mutually supported method, the client **MAY** use it. +- If the intersection is empty, the client **MUST NOT** proceed, and the + authorization server **MUST** reject the client. For example: @@ -157,18 +136,8 @@ For example: ### Deprecated Declarations -Changing an established metadata field in a widely deployed mechanism needs a -managed transition rather than an immediate cutover, and MCP already has a -pattern for exactly this. Dynamic Client Registration is deprecated in favor -of Client ID Metadata Documents, but remains permitted and is "retained for -backwards compatibility with authorization servers that do not support Client -ID Metadata Documents," with a removal date governed by the -[feature lifecycle policy](/community/feature-lifecycle). - -This SEP applies the same treatment to the two ways a CIMD document can -currently avoid declaring its authentication methods explicitly. Both are -**deprecated**, both remain permitted for now, and both migrate to -`token_endpoint_auth_methods_supported`: +Two existing declarations are **deprecated** but remain supported during the +transition to `token_endpoint_auth_methods_supported`: 1. **The singular `token_endpoint_auth_method` parameter**, retained for backwards compatibility with authorization servers that do not support the @@ -187,18 +156,13 @@ currently avoid declaring its authentication methods explicitly. Both are > parameter alongside the corresponding multi-valued metadata parameter with > their preferred single value. -- Authorization servers **MUST** prefer `token_endpoint_auth_methods_supported` - when it is present. When both parameters are present, - `token_endpoint_auth_method` **MUST** be a member of - `token_endpoint_auth_methods_supported`; otherwise the document is invalid. - Authorization servers **MUST NOT** let the singular parameter override the - array. -- Authorization servers that support the array **MAY** treat - `token_endpoint_auth_method` as the client's preferred method only when it - is mutually supported and does not conflict with the method resolution - requirements above. They **MUST NOT** reject a client solely because the - singular preferred method is unsupported when another method in the array - is mutually supported. +- When both parameters are present, `token_endpoint_auth_method` **MUST** be a + member of `token_endpoint_auth_methods_supported`. The array is authoritative; + the singular value is a preference only when it is mutually supported and + consistent with the method resolution rules. +- Authorization servers **MUST NOT** reject a client solely because the + singular preferred method is unsupported when another method in the array is + mutually supported. - Authorization servers **MAY** fall back to `token_endpoint_auth_method` when the multi-valued parameter is absent — for example, when reading a document published before this requirement took effect. @@ -227,13 +191,9 @@ methods. Which methods a client can support is determined by its deployment model, and a blanket recommendation would be wrong for some large class of clients. -The method resolution rule distinguishes only between `none` and authenticated -client authentication methods. Treating `none` as a peer choice when an -authenticated method is mutually supported would make the client's security -posture equivalent to the weaker, unauthenticated option. The SEP does not -define a global ordering among authenticated methods; when more than one is -mutually supported, the client can choose without requiring an authorization -server to select a method and communicate that choice back to the client. +The method resolution rule distinguishes authenticated methods from `none` +without ranking authenticated methods or requiring the authorization server to +communicate a selected method back to the client. The field is required (MUST) rather than recommended (SHOULD) because explicit behavior is crucial for authentication mechanisms. A required field gives @@ -267,8 +227,8 @@ Publishing multiple metadata documents, one per `token_endpoint_auth_method` ## Backward Compatibility -In the revision this SEP lands in, the incompatibility is at the conformance -level only. No existing CIMD document stops working. +Existing CIMD documents remain accepted by conformant authorization servers +during the deprecation period. **What changes.** CIMD documents that omit `token_endpoint_auth_methods_supported` become non-conformant with that @@ -294,10 +254,6 @@ that only supports `none`, even when the array also contains `none`. This is an inherent limitation of the legacy single-valued field; authorization servers that understand the array use the method resolution rules above. -The immediate incompatibility is therefore a conformance obligation on -clients, not a runtime failure for either party, and non-conformant documents -degrade to their current behavior rather than being rejected. - **What changes at removal.** Both accommodations are deprecated, so this is a deferred break rather than an avoided one. When the deprecation period elapses, a document that declares no authentication method is rejected instead @@ -314,29 +270,24 @@ with the other. ## Security Implications -This proposal does not introduce a new client authentication mechanism; it -only changes how a client advertises which existing, already-specified -authentication methods it supports. Because this SEP does not prescribe the -contents of the array, it does not itself raise or lower the authentication -strength of any deployment: authorization servers remain responsible for -rejecting clients whose advertised methods do not meet the server's -requirements. - -In aggregate this change is expected to improve authentication strength across -the ecosystem rather than weaken it. Today a client that supports strong -client authentication must still publish a single value acceptable to the -weakest authorization server it needs to work with; enumerating capabilities -lets servers that support a stronger method actually use it. - -An authorization server **MUST NOT** accept `none` for a client when an -authenticated client authentication method is mutually supported. Otherwise, -an attacker could choose `none` for the same client identifier and bypass the -stronger authentication method, making the effective security posture no -stronger than that of a public client. +This proposal does not introduce a new authentication mechanism. It allows a +client to advertise multiple existing methods so authorization servers can use +authenticated methods when they are mutually supported. + +Accepting `none` when an authenticated method is mutually supported would let +an attacker bypass client authentication for the same client identifier. The +method resolution rules prevent this downgrade while retaining `none` as a +fallback for authorization servers that do not support an authenticated method. ## Reference Implementation -**TODO** +[ChatGPT's public Client ID Metadata Document](https://chatgpt.com/oauth/client.json) +advertises `["none", "private_key_jwt"]` and includes a `jwks_uri` for +`private_key_jwt`. It demonstrates that one stable client identifier can +advertise both authentication methods across authorization servers. + +A publicly runnable client/server implementation and conformance tests remain +to be linked. ## Open Questions diff --git a/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md b/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md index 886bdb766..19a65ab72 100644 --- a/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md +++ b/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md @@ -75,14 +75,6 @@ Authorization servers **MUST** support reading omit it are handled as described in [Deprecated Declarations](#deprecated-declarations). -A document that carries **neither** parameter **MUST** be treated as declaring -`["none"]` — that is, as a public client. This default is itself **deprecated** -and exists only for compatibility: neither parameter is required by the -specification today, so documents omitting both are conformant under the -current revision and remain in wide use. Once the deprecation period elapses, -such a document is invalid and authorization servers reject it rather than -inferring a method. - For illustration, a client that can operate either as a public client or with an assertion-based credential might publish: @@ -96,8 +88,6 @@ authenticate with a signed JWT assertion per [RFC 7523](https://datatracker.ietf.org/doc/html/rfc7523), using the JWKS referenced by the CIMD document (see [Section 6.2 of the Client ID Metadata Document draft](https://www.ietf.org/archive/id/draft-ietf-oauth-client-id-metadata-document-00.html#section-6.2)). -Other registered method names are valid only when they satisfy the -restrictions of the Client ID Metadata Document specification. ### Method Resolution @@ -106,27 +96,16 @@ token endpoint client authentication methods by intersecting the client's `token_endpoint_auth_methods_supported` array with the authorization server's `token_endpoint_auth_methods_supported` metadata value. -For purposes of this resolution rule, `none` is unauthenticated and every -other permitted method is an authenticated client authentication method. - -If the intersection contains one or more authenticated client authentication -methods, the client **MUST** use one of those methods and **MUST NOT** use -`none`. The authorization server **MUST** reject a request using `none` for -that client when an authenticated method is mutually supported. When multiple -authenticated methods are mutually supported, the client **MAY** choose among -them. +For this rule, `none` is unauthenticated; all other permitted methods are +authenticated. -If the intersection contains no authenticated method but contains `none`, the -client **MAY** proceed using `none`. If the intersection is empty, the client -**MUST NOT** proceed and the authorization server **MUST** reject the client -rather than falling back to a method the client did not advertise. In -particular, an authorization server **MUST NOT** assume `none` when the field -is present and non-empty but does not include it. - -This applies to the `["none"]` default for documents declaring no -authentication method as it does to an explicitly published array: an -authorization server that does not support public clients **MUST** reject -such a document rather than registering the client under some other method. +- If the intersection contains an authenticated method, the client **MUST** + use one such method, and the authorization server **MUST** reject `none`. + When multiple authenticated methods are available, the client **MAY** choose + among them. +- If `none` is the only mutually supported method, the client **MAY** use it. +- If the intersection is empty, the client **MUST NOT** proceed, and the + authorization server **MUST** reject the client. For example: @@ -138,18 +117,8 @@ For example: ### Deprecated Declarations -Changing an established metadata field in a widely deployed mechanism needs a -managed transition rather than an immediate cutover, and MCP already has a -pattern for exactly this. Dynamic Client Registration is deprecated in favor -of Client ID Metadata Documents, but remains permitted and is "retained for -backwards compatibility with authorization servers that do not support Client -ID Metadata Documents," with a removal date governed by the -[feature lifecycle policy](/community/feature-lifecycle). - -This SEP applies the same treatment to the two ways a CIMD document can -currently avoid declaring its authentication methods explicitly. Both are -**deprecated**, both remain permitted for now, and both migrate to -`token_endpoint_auth_methods_supported`: +Two existing declarations are **deprecated** but remain supported during the +transition to `token_endpoint_auth_methods_supported`: 1. **The singular `token_endpoint_auth_method` parameter**, retained for backwards compatibility with authorization servers that do not support the @@ -168,18 +137,13 @@ currently avoid declaring its authentication methods explicitly. Both are > parameter alongside the corresponding multi-valued metadata parameter with > their preferred single value. -- Authorization servers **MUST** prefer `token_endpoint_auth_methods_supported` - when it is present. When both parameters are present, - `token_endpoint_auth_method` **MUST** be a member of - `token_endpoint_auth_methods_supported`; otherwise the document is invalid. - Authorization servers **MUST NOT** let the singular parameter override the - array. -- Authorization servers that support the array **MAY** treat - `token_endpoint_auth_method` as the client's preferred method only when it - is mutually supported and does not conflict with the method resolution - requirements above. They **MUST NOT** reject a client solely because the - singular preferred method is unsupported when another method in the array - is mutually supported. +- When both parameters are present, `token_endpoint_auth_method` **MUST** be a + member of `token_endpoint_auth_methods_supported`. The array is authoritative; + the singular value is a preference only when it is mutually supported and + consistent with the method resolution rules. +- Authorization servers **MUST NOT** reject a client solely because the + singular preferred method is unsupported when another method in the array is + mutually supported. - Authorization servers **MAY** fall back to `token_endpoint_auth_method` when the multi-valued parameter is absent — for example, when reading a document published before this requirement took effect. @@ -208,13 +172,9 @@ methods. Which methods a client can support is determined by its deployment model, and a blanket recommendation would be wrong for some large class of clients. -The method resolution rule distinguishes only between `none` and authenticated -client authentication methods. Treating `none` as a peer choice when an -authenticated method is mutually supported would make the client's security -posture equivalent to the weaker, unauthenticated option. The SEP does not -define a global ordering among authenticated methods; when more than one is -mutually supported, the client can choose without requiring an authorization -server to select a method and communicate that choice back to the client. +The method resolution rule distinguishes authenticated methods from `none` +without ranking authenticated methods or requiring the authorization server to +communicate a selected method back to the client. The field is required (MUST) rather than recommended (SHOULD) because explicit behavior is crucial for authentication mechanisms. A required field gives @@ -248,8 +208,8 @@ Publishing multiple metadata documents, one per `token_endpoint_auth_method` ## Backward Compatibility -In the revision this SEP lands in, the incompatibility is at the conformance -level only. No existing CIMD document stops working. +Existing CIMD documents remain accepted by conformant authorization servers +during the deprecation period. **What changes.** CIMD documents that omit `token_endpoint_auth_methods_supported` become non-conformant with that @@ -275,10 +235,6 @@ that only supports `none`, even when the array also contains `none`. This is an inherent limitation of the legacy single-valued field; authorization servers that understand the array use the method resolution rules above. -The immediate incompatibility is therefore a conformance obligation on -clients, not a runtime failure for either party, and non-conformant documents -degrade to their current behavior rather than being rejected. - **What changes at removal.** Both accommodations are deprecated, so this is a deferred break rather than an avoided one. When the deprecation period elapses, a document that declares no authentication method is rejected instead @@ -295,29 +251,24 @@ with the other. ## Security Implications -This proposal does not introduce a new client authentication mechanism; it -only changes how a client advertises which existing, already-specified -authentication methods it supports. Because this SEP does not prescribe the -contents of the array, it does not itself raise or lower the authentication -strength of any deployment: authorization servers remain responsible for -rejecting clients whose advertised methods do not meet the server's -requirements. - -In aggregate this change is expected to improve authentication strength across -the ecosystem rather than weaken it. Today a client that supports strong -client authentication must still publish a single value acceptable to the -weakest authorization server it needs to work with; enumerating capabilities -lets servers that support a stronger method actually use it. - -An authorization server **MUST NOT** accept `none` for a client when an -authenticated client authentication method is mutually supported. Otherwise, -an attacker could choose `none` for the same client identifier and bypass the -stronger authentication method, making the effective security posture no -stronger than that of a public client. +This proposal does not introduce a new authentication mechanism. It allows a +client to advertise multiple existing methods so authorization servers can use +authenticated methods when they are mutually supported. + +Accepting `none` when an authenticated method is mutually supported would let +an attacker bypass client authentication for the same client identifier. The +method resolution rules prevent this downgrade while retaining `none` as a +fallback for authorization servers that do not support an authenticated method. ## Reference Implementation -**TODO** +[ChatGPT's public Client ID Metadata Document](https://chatgpt.com/oauth/client.json) +advertises `["none", "private_key_jwt"]` and includes a `jwks_uri` for +`private_key_jwt`. It demonstrates that one stable client identifier can +advertise both authentication methods across authorization servers. + +A publicly runnable client/server implementation and conformance tests remain +to be linked. ## Open Questions From 35dcac9fa68c1ca9274dbe3f2f8ea3674644762e Mon Sep 17 00:00:00 2001 From: Steven Lee Date: Wed, 5 Aug 2026 21:13:08 +0000 Subject: [PATCH 06/10] SEP-3149: add migration configuration examples --- ...oken-endpoint-auth-methods-supported-in-cimd.mdx | 13 +++++++++++++ ...token-endpoint-auth-methods-supported-in-cimd.md | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/docs/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.mdx b/docs/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.mdx index 020d8c6af..cd82408e2 100644 --- a/docs/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.mdx +++ b/docs/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.mdx @@ -132,6 +132,7 @@ For example: | ----------------------------- | ----------------------------- | --------------------- | | `["private_key_jwt", "none"]` | `["private_key_jwt", "none"]` | Use `private_key_jwt` | | `["private_key_jwt", "none"]` | `["none"]` | Use `none` | +| `["none"]` | `["private_key_jwt", "none"]` | Use `none` | | `["private_key_jwt", "none"]` | `["client_secret_basic"]` | No compatible method | ### Deprecated Declarations @@ -170,6 +171,18 @@ transition to `token_endpoint_auth_methods_supported`: as declaring `["none"]` until the deprecation period elapses, and **MUST** reject such a document thereafter. +The following examples show how the singular field behaves during the +deprecation period: + +| Client methods | Singular preference | Authorization server methods | Result | +| ----------------------------- | ------------------- | ----------------------------- | -------------------------- | +| `["private_key_jwt", "none"]` | `private_key_jwt` | `["none"]` | Use `none` | +| `["private_key_jwt", "none"]` | `none` | `["private_key_jwt", "none"]` | Use `private_key_jwt` | +| `["none"]` | `private_key_jwt` | `["none"]` | Reject invalid metadata | +| Omitted | `none` | `["none"]` | Use legacy `none` | +| Omitted | Omitted | `["none"]` | Use deprecated `none` | +| Omitted | Omitted | `["private_key_jwt"]` | Reject incompatible client | + ### Lifecycle Per the [feature lifecycle policy](/community/feature-lifecycle), this SEP diff --git a/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md b/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md index 19a65ab72..8c9fe806b 100644 --- a/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md +++ b/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md @@ -113,6 +113,7 @@ For example: | ----------------------------- | ----------------------------- | --------------------- | | `["private_key_jwt", "none"]` | `["private_key_jwt", "none"]` | Use `private_key_jwt` | | `["private_key_jwt", "none"]` | `["none"]` | Use `none` | +| `["none"]` | `["private_key_jwt", "none"]` | Use `none` | | `["private_key_jwt", "none"]` | `["client_secret_basic"]` | No compatible method | ### Deprecated Declarations @@ -151,6 +152,18 @@ transition to `token_endpoint_auth_methods_supported`: as declaring `["none"]` until the deprecation period elapses, and **MUST** reject such a document thereafter. +The following examples show how the singular field behaves during the +deprecation period: + +| Client methods | Singular preference | Authorization server methods | Result | +| ----------------------------- | ------------------- | ----------------------------- | -------------------------- | +| `["private_key_jwt", "none"]` | `private_key_jwt` | `["none"]` | Use `none` | +| `["private_key_jwt", "none"]` | `none` | `["private_key_jwt", "none"]` | Use `private_key_jwt` | +| `["none"]` | `private_key_jwt` | `["none"]` | Reject invalid metadata | +| Omitted | `none` | `["none"]` | Use legacy `none` | +| Omitted | Omitted | `["none"]` | Use deprecated `none` | +| Omitted | Omitted | `["private_key_jwt"]` | Reject incompatible client | + ### Lifecycle Per the [feature lifecycle policy](/community/feature-lifecycle), this SEP From 547c4c8a0ffaf6d5a75cdcafe5c5f7fffb5d257a Mon Sep 17 00:00:00 2001 From: Steven Lee Date: Wed, 5 Aug 2026 21:44:59 +0000 Subject: [PATCH 07/10] SEP-3149: document backwards-compatible client examples --- ...ndpoint-auth-methods-supported-in-cimd.mdx | 25 ++++++++++++++++--- ...endpoint-auth-methods-supported-in-cimd.md | 25 ++++++++++++++++--- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/docs/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.mdx b/docs/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.mdx index cd82408e2..5e8285a00 100644 --- a/docs/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.mdx +++ b/docs/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.mdx @@ -295,9 +295,28 @@ fallback for authorization servers that do not support an authenticated method. ## Reference Implementation [ChatGPT's public Client ID Metadata Document](https://chatgpt.com/oauth/client.json) -advertises `["none", "private_key_jwt"]` and includes a `jwks_uri` for -`private_key_jwt`. It demonstrates that one stable client identifier can -advertise both authentication methods across authorization servers. +advertises both methods, prefers `private_key_jwt` for backwards compatibility, +and includes the key material required to authenticate: + +```json +{ + "token_endpoint_auth_methods_supported": ["none", "private_key_jwt"], + "token_endpoint_auth_method": "private_key_jwt", + "jwks_uri": "https://chatgpt.com/oauth/jwks.json" +} +``` + +Codex advertises and prefers only its supported public-client method: + +```json +{ + "token_endpoint_auth_methods_supported": ["none"], + "token_endpoint_auth_method": "none" +} +``` + +Both examples maintain a stable client identifier while exposing a singular +preference for authorization servers that do not support the array. A publicly runnable client/server implementation and conformance tests remain to be linked. diff --git a/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md b/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md index 8c9fe806b..9a004ae54 100644 --- a/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md +++ b/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md @@ -276,9 +276,28 @@ fallback for authorization servers that do not support an authenticated method. ## Reference Implementation [ChatGPT's public Client ID Metadata Document](https://chatgpt.com/oauth/client.json) -advertises `["none", "private_key_jwt"]` and includes a `jwks_uri` for -`private_key_jwt`. It demonstrates that one stable client identifier can -advertise both authentication methods across authorization servers. +advertises both methods, prefers `private_key_jwt` for backwards compatibility, +and includes the key material required to authenticate: + +```json +{ + "token_endpoint_auth_methods_supported": ["none", "private_key_jwt"], + "token_endpoint_auth_method": "private_key_jwt", + "jwks_uri": "https://chatgpt.com/oauth/jwks.json" +} +``` + +Codex advertises and prefers only its supported public-client method: + +```json +{ + "token_endpoint_auth_methods_supported": ["none"], + "token_endpoint_auth_method": "none" +} +``` + +Both examples maintain a stable client identifier while exposing a singular +preference for authorization servers that do not support the array. A publicly runnable client/server implementation and conformance tests remain to be linked. From 42b17a02b8c7acf65c5b343cd2d1c7e08f18ec12 Mon Sep 17 00:00:00 2001 From: stevenlee-oai Date: Thu, 6 Aug 2026 17:11:05 -0700 Subject: [PATCH 08/10] Update seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md Co-authored-by: Max Gerber <89937743+max-stytch@users.noreply.github.com> --- ...149-require-token-endpoint-auth-methods-supported-in-cimd.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md b/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md index 9a004ae54..4cfafb108 100644 --- a/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md +++ b/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md @@ -3,7 +3,7 @@ - **Status**: Draft - **Type**: Standards Track - **Created**: 2026-07-27 -- **Author(s)**: @max-stytch +- **Author(s)**: @max-stytch @stevenlee-oai - **Sponsor**: @pcarleton - **PR**: https://github.com/modelcontextprotocol/modelcontextprotocol/pull/3149 From d8ffd11dc1a784e6e796cc63f75ded3179f8af08 Mon Sep 17 00:00:00 2001 From: Steven Lee Date: Fri, 7 Aug 2026 01:11:01 +0000 Subject: [PATCH 09/10] SEP-3149: clarify legacy-compatible method selection --- ...ndpoint-auth-methods-supported-in-cimd.mdx | 125 ++++++++++-------- ...endpoint-auth-methods-supported-in-cimd.md | 107 +++++++++------ 2 files changed, 135 insertions(+), 97 deletions(-) diff --git a/docs/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.mdx b/docs/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.mdx index 5e8285a00..fc0c34f90 100644 --- a/docs/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.mdx +++ b/docs/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.mdx @@ -13,16 +13,16 @@ description: "Require `token_endpoint_auth_methods_supported` in Client ID Metad -| Field | Value | -| ------------- | ------------------------------------------------------------------------------- | -| **SEP** | 3149 | -| **Title** | Require `token_endpoint_auth_methods_supported` in Client ID Metadata Documents | -| **Status** | Draft | -| **Type** | Standards Track | -| **Created** | 2026-07-27 | -| **Author(s)** | [@max-stytch](https://github.com/max-stytch) | -| **Sponsor** | [@pcarleton](https://github.com/pcarleton) | -| **PR** | [#3149](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/3149) | +| Field | Value | +| ------------- | ----------------------------------------------------------------------------------------------- | +| **SEP** | 3149 | +| **Title** | Require `token_endpoint_auth_methods_supported` in Client ID Metadata Documents | +| **Status** | Draft | +| **Type** | Standards Track | +| **Created** | 2026-07-27 | +| **Author(s)** | [@max-stytch](https://github.com/max-stytch) [@stevenlee-oai](https://github.com/stevenlee-oai) | +| **Sponsor** | [@pcarleton](https://github.com/pcarleton) | +| **PR** | [#3149](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/3149) | --- @@ -115,25 +115,27 @@ token endpoint client authentication methods by intersecting the client's `token_endpoint_auth_methods_supported` array with the authorization server's `token_endpoint_auth_methods_supported` metadata value. -For this rule, `none` is unauthenticated; all other permitted methods are -authenticated. - -- If the intersection contains an authenticated method, the client **MUST** - use one such method, and the authorization server **MUST** reject `none`. - When multiple authenticated methods are available, the client **MAY** choose - among them. -- If `none` is the only mutually supported method, the client **MAY** use it. +- The client **MUST** use a method from the intersection. +- When the client's singular `token_endpoint_auth_method` is present and + mutually supported, the client **SHOULD** use that method to preserve + compatibility with authorization servers that treat the singular field as + binding. +- When the singular method is absent or unsupported, the client **MAY** use + another mutually supported method. Authorization servers that understand the + array **SHOULD** accept mutually supported methods that satisfy their local + security policies. - If the intersection is empty, the client **MUST NOT** proceed, and the authorization server **MUST** reject the client. +- Authorization servers **MUST** reject any method outside the intersection. For example: -| Client methods | Authorization server methods | Result | -| ----------------------------- | ----------------------------- | --------------------- | -| `["private_key_jwt", "none"]` | `["private_key_jwt", "none"]` | Use `private_key_jwt` | -| `["private_key_jwt", "none"]` | `["none"]` | Use `none` | -| `["none"]` | `["private_key_jwt", "none"]` | Use `none` | -| `["private_key_jwt", "none"]` | `["client_secret_basic"]` | No compatible method | +| Client methods | Authorization server methods | Result | +| ----------------------------- | ----------------------------- | ------------------------------ | +| `["private_key_jwt", "none"]` | `["private_key_jwt", "none"]` | Client chooses a shared method | +| `["private_key_jwt", "none"]` | `["none"]` | Use `none` | +| `["none"]` | `["private_key_jwt", "none"]` | Use `none` | +| `["private_key_jwt", "none"]` | `["client_secret_basic"]` | No compatible method | ### Deprecated Declarations @@ -159,8 +161,8 @@ transition to `token_endpoint_auth_methods_supported`: - When both parameters are present, `token_endpoint_auth_method` **MUST** be a member of `token_endpoint_auth_methods_supported`. The array is authoritative; - the singular value is a preference only when it is mutually supported and - consistent with the method resolution rules. + the singular value is the client's backwards-compatible preference when it is + mutually supported. - Authorization servers **MUST NOT** reject a client solely because the singular preferred method is unsupported when another method in the array is mutually supported. @@ -174,14 +176,15 @@ transition to `token_endpoint_auth_methods_supported`: The following examples show how the singular field behaves during the deprecation period: -| Client methods | Singular preference | Authorization server methods | Result | -| ----------------------------- | ------------------- | ----------------------------- | -------------------------- | -| `["private_key_jwt", "none"]` | `private_key_jwt` | `["none"]` | Use `none` | -| `["private_key_jwt", "none"]` | `none` | `["private_key_jwt", "none"]` | Use `private_key_jwt` | -| `["none"]` | `private_key_jwt` | `["none"]` | Reject invalid metadata | -| Omitted | `none` | `["none"]` | Use legacy `none` | -| Omitted | Omitted | `["none"]` | Use deprecated `none` | -| Omitted | Omitted | `["private_key_jwt"]` | Reject incompatible client | +| Client methods | Singular preference | Authorization server methods | Result | +| ----------------------------- | ------------------- | ----------------------------- | ------------------------------- | +| `["private_key_jwt", "none"]` | `private_key_jwt` | `["private_key_jwt", "none"]` | Use preferred `private_key_jwt` | +| `["private_key_jwt", "none"]` | `private_key_jwt` | `["none"]` | Try `none` | +| `["private_key_jwt", "none"]` | `none` | `["private_key_jwt", "none"]` | Use preferred `none` | +| `["none"]` | `private_key_jwt` | `["none"]` | Reject invalid metadata | +| Omitted | `none` | `["none"]` | Use legacy `none` | +| Omitted | Omitted | `["none"]` | Use deprecated `none` | +| Omitted | Omitted | `["private_key_jwt"]` | Reject incompatible client | ### Lifecycle @@ -204,9 +207,13 @@ methods. Which methods a client can support is determined by its deployment model, and a blanket recommendation would be wrong for some large class of clients. -The method resolution rule distinguishes authenticated methods from `none` -without ranking authenticated methods or requiring the authorization server to -communicate a selected method back to the client. +The client selects a mutually supported method without requiring the +authorization server to communicate a selected method back to the client. +Preserving the singular preference when possible keeps existing +authorization-server behavior intact. This follows +[OpenID Federation 1.0, Section 12.1.4](https://openid.net/specs/openid-federation-1_0.html#section-12.1.4), +which requires clients to use mutually supported methods and recommends that +authorization servers accept them. The field is required (MUST) rather than recommended (SHOULD) because explicit behavior is crucial for authentication mechanisms. A required field gives @@ -233,10 +240,15 @@ Publishing multiple metadata documents, one per `token_endpoint_auth_method` different clients depending on which authorization server they connected through. - The maintenance burden compounds the problem: every additional method - multiplies the documents that must be hosted and kept in sync, and each new - method a client adopts changes the set of URLs it publishes. Declaring - capabilities in one document keeps the client's identity stable while its - capabilities evolve. + multiplies the documents that must be hosted and kept in sync. Other + independently varying properties, such as callback identifiers, multiply + that cardinality further. New URLs also complicate authorization-server + allowlists and existing registrations, while query-string variants can be + rejected because + [Client ID Metadata Document identifiers](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-client-id-metadata-document-01#section-3) + **SHOULD NOT** include query strings. Multiple documents can serve as a + migration fallback, but one document keeps the client's identity stable as + its capabilities evolve. ## Backward Compatibility @@ -260,12 +272,14 @@ continues to register successfully: parameter keep working, because clients SHOULD continue publishing the singular field. -The singular field cannot communicate fallback choices to an authorization -server that does not understand the array. A client whose singular value is -`private_key_jwt` can therefore be rejected by a legacy authorization server -that only supports `none`, even when the array also contains `none`. This is -an inherent limitation of the legacy single-valued field; authorization -servers that understand the array use the method resolution rules above. +Clients do not need a separate signal indicating whether an authorization +server understands the array. When the singular preferred method is supported, +using it preserves compatibility with legacy authorization servers. When it is +unsupported, a client can try another mutually supported method from the +array: an updated authorization server can accept it, while a legacy server +may still reject the client. That legacy server would already have rejected the +unsupported singular method, so this fallback improves compatibility without +creating a new failure case. **What changes at removal.** Both accommodations are deprecated, so this is a deferred break rather than an avoided one. When the deprecation period @@ -284,13 +298,13 @@ with the other. ## Security Implications This proposal does not introduce a new authentication mechanism. It allows a -client to advertise multiple existing methods so authorization servers can use -authenticated methods when they are mutually supported. +client to advertise multiple existing methods while preserving the +authorization server's ability to enforce its local security policy. -Accepting `none` when an authenticated method is mutually supported would let -an attacker bypass client authentication for the same client identifier. The -method resolution rules prevent this downgrade while retaining `none` as a -fallback for authorization servers that do not support an authenticated method. +An authorization server that accepts `none` treats the client as a public +client for that interaction. Servers requiring client authentication can +reject `none`, and clients can prefer authenticated methods when compatible +with their deployment and backwards-compatibility requirements. ## Reference Implementation @@ -325,6 +339,11 @@ to be linked. - Should `implicit ["none"]` and `token_endpoint_auth_method` be deprecated, or should allowances be made to not break existing CIMD clients? +- Should MCP recommend preferring authenticated methods over `none`, and how + would that interact with authorization servers that treat the singular + method as binding? +- How should an authorization server report an incompatible CIMD client when + it has not established a trusted redirect URI? ## Acknowledgments diff --git a/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md b/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md index 4cfafb108..1a027eeea 100644 --- a/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md +++ b/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md @@ -3,7 +3,7 @@ - **Status**: Draft - **Type**: Standards Track - **Created**: 2026-07-27 -- **Author(s)**: @max-stytch @stevenlee-oai +- **Author(s)**: @max-stytch @stevenlee-oai - **Sponsor**: @pcarleton - **PR**: https://github.com/modelcontextprotocol/modelcontextprotocol/pull/3149 @@ -96,25 +96,27 @@ token endpoint client authentication methods by intersecting the client's `token_endpoint_auth_methods_supported` array with the authorization server's `token_endpoint_auth_methods_supported` metadata value. -For this rule, `none` is unauthenticated; all other permitted methods are -authenticated. - -- If the intersection contains an authenticated method, the client **MUST** - use one such method, and the authorization server **MUST** reject `none`. - When multiple authenticated methods are available, the client **MAY** choose - among them. -- If `none` is the only mutually supported method, the client **MAY** use it. +- The client **MUST** use a method from the intersection. +- When the client's singular `token_endpoint_auth_method` is present and + mutually supported, the client **SHOULD** use that method to preserve + compatibility with authorization servers that treat the singular field as + binding. +- When the singular method is absent or unsupported, the client **MAY** use + another mutually supported method. Authorization servers that understand the + array **SHOULD** accept mutually supported methods that satisfy their local + security policies. - If the intersection is empty, the client **MUST NOT** proceed, and the authorization server **MUST** reject the client. +- Authorization servers **MUST** reject any method outside the intersection. For example: -| Client methods | Authorization server methods | Result | -| ----------------------------- | ----------------------------- | --------------------- | -| `["private_key_jwt", "none"]` | `["private_key_jwt", "none"]` | Use `private_key_jwt` | -| `["private_key_jwt", "none"]` | `["none"]` | Use `none` | -| `["none"]` | `["private_key_jwt", "none"]` | Use `none` | -| `["private_key_jwt", "none"]` | `["client_secret_basic"]` | No compatible method | +| Client methods | Authorization server methods | Result | +| ----------------------------- | ----------------------------- | ------------------------------ | +| `["private_key_jwt", "none"]` | `["private_key_jwt", "none"]` | Client chooses a shared method | +| `["private_key_jwt", "none"]` | `["none"]` | Use `none` | +| `["none"]` | `["private_key_jwt", "none"]` | Use `none` | +| `["private_key_jwt", "none"]` | `["client_secret_basic"]` | No compatible method | ### Deprecated Declarations @@ -140,8 +142,8 @@ transition to `token_endpoint_auth_methods_supported`: - When both parameters are present, `token_endpoint_auth_method` **MUST** be a member of `token_endpoint_auth_methods_supported`. The array is authoritative; - the singular value is a preference only when it is mutually supported and - consistent with the method resolution rules. + the singular value is the client's backwards-compatible preference when it is + mutually supported. - Authorization servers **MUST NOT** reject a client solely because the singular preferred method is unsupported when another method in the array is mutually supported. @@ -155,14 +157,15 @@ transition to `token_endpoint_auth_methods_supported`: The following examples show how the singular field behaves during the deprecation period: -| Client methods | Singular preference | Authorization server methods | Result | -| ----------------------------- | ------------------- | ----------------------------- | -------------------------- | -| `["private_key_jwt", "none"]` | `private_key_jwt` | `["none"]` | Use `none` | -| `["private_key_jwt", "none"]` | `none` | `["private_key_jwt", "none"]` | Use `private_key_jwt` | -| `["none"]` | `private_key_jwt` | `["none"]` | Reject invalid metadata | -| Omitted | `none` | `["none"]` | Use legacy `none` | -| Omitted | Omitted | `["none"]` | Use deprecated `none` | -| Omitted | Omitted | `["private_key_jwt"]` | Reject incompatible client | +| Client methods | Singular preference | Authorization server methods | Result | +| ----------------------------- | ------------------- | ----------------------------- | ------------------------------- | +| `["private_key_jwt", "none"]` | `private_key_jwt` | `["private_key_jwt", "none"]` | Use preferred `private_key_jwt` | +| `["private_key_jwt", "none"]` | `private_key_jwt` | `["none"]` | Try `none` | +| `["private_key_jwt", "none"]` | `none` | `["private_key_jwt", "none"]` | Use preferred `none` | +| `["none"]` | `private_key_jwt` | `["none"]` | Reject invalid metadata | +| Omitted | `none` | `["none"]` | Use legacy `none` | +| Omitted | Omitted | `["none"]` | Use deprecated `none` | +| Omitted | Omitted | `["private_key_jwt"]` | Reject incompatible client | ### Lifecycle @@ -185,9 +188,13 @@ methods. Which methods a client can support is determined by its deployment model, and a blanket recommendation would be wrong for some large class of clients. -The method resolution rule distinguishes authenticated methods from `none` -without ranking authenticated methods or requiring the authorization server to -communicate a selected method back to the client. +The client selects a mutually supported method without requiring the +authorization server to communicate a selected method back to the client. +Preserving the singular preference when possible keeps existing +authorization-server behavior intact. This follows +[OpenID Federation 1.0, Section 12.1.4](https://openid.net/specs/openid-federation-1_0.html#section-12.1.4), +which requires clients to use mutually supported methods and recommends that +authorization servers accept them. The field is required (MUST) rather than recommended (SHOULD) because explicit behavior is crucial for authentication mechanisms. A required field gives @@ -214,10 +221,15 @@ Publishing multiple metadata documents, one per `token_endpoint_auth_method` different clients depending on which authorization server they connected through. - The maintenance burden compounds the problem: every additional method - multiplies the documents that must be hosted and kept in sync, and each new - method a client adopts changes the set of URLs it publishes. Declaring - capabilities in one document keeps the client's identity stable while its - capabilities evolve. + multiplies the documents that must be hosted and kept in sync. Other + independently varying properties, such as callback identifiers, multiply + that cardinality further. New URLs also complicate authorization-server + allowlists and existing registrations, while query-string variants can be + rejected because + [Client ID Metadata Document identifiers](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-client-id-metadata-document-01#section-3) + **SHOULD NOT** include query strings. Multiple documents can serve as a + migration fallback, but one document keeps the client's identity stable as + its capabilities evolve. ## Backward Compatibility @@ -241,12 +253,14 @@ continues to register successfully: parameter keep working, because clients SHOULD continue publishing the singular field. -The singular field cannot communicate fallback choices to an authorization -server that does not understand the array. A client whose singular value is -`private_key_jwt` can therefore be rejected by a legacy authorization server -that only supports `none`, even when the array also contains `none`. This is -an inherent limitation of the legacy single-valued field; authorization -servers that understand the array use the method resolution rules above. +Clients do not need a separate signal indicating whether an authorization +server understands the array. When the singular preferred method is supported, +using it preserves compatibility with legacy authorization servers. When it is +unsupported, a client can try another mutually supported method from the +array: an updated authorization server can accept it, while a legacy server +may still reject the client. That legacy server would already have rejected the +unsupported singular method, so this fallback improves compatibility without +creating a new failure case. **What changes at removal.** Both accommodations are deprecated, so this is a deferred break rather than an avoided one. When the deprecation period @@ -265,13 +279,13 @@ with the other. ## Security Implications This proposal does not introduce a new authentication mechanism. It allows a -client to advertise multiple existing methods so authorization servers can use -authenticated methods when they are mutually supported. +client to advertise multiple existing methods while preserving the +authorization server's ability to enforce its local security policy. -Accepting `none` when an authenticated method is mutually supported would let -an attacker bypass client authentication for the same client identifier. The -method resolution rules prevent this downgrade while retaining `none` as a -fallback for authorization servers that do not support an authenticated method. +An authorization server that accepts `none` treats the client as a public +client for that interaction. Servers requiring client authentication can +reject `none`, and clients can prefer authenticated methods when compatible +with their deployment and backwards-compatibility requirements. ## Reference Implementation @@ -306,6 +320,11 @@ to be linked. - Should `implicit ["none"]` and `token_endpoint_auth_method` be deprecated, or should allowances be made to not break existing CIMD clients? +- Should MCP recommend preferring authenticated methods over `none`, and how + would that interact with authorization servers that treat the singular + method as binding? +- How should an authorization server report an incompatible CIMD client when + it has not established a trusted redirect URI? ## Acknowledgments From b5ce93685137301fc1d033de3d6a298a605686f2 Mon Sep 17 00:00:00 2001 From: Steven Lee Date: Fri, 7 Aug 2026 22:17:37 +0000 Subject: [PATCH 10/10] SEP-3149: narrow auth method scope --- ...ndpoint-auth-methods-supported-in-cimd.mdx | 56 ++++++------------- ...endpoint-auth-methods-supported-in-cimd.md | 56 ++++++------------- 2 files changed, 32 insertions(+), 80 deletions(-) diff --git a/docs/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.mdx b/docs/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.mdx index fc0c34f90..a36b1f597 100644 --- a/docs/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.mdx +++ b/docs/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.mdx @@ -51,12 +51,8 @@ never in normative prose. A CIMD document is published at a single URL and consumed by every authorization server the client ever connects to, and those servers do not -have uniform capabilities. Some support `private_key_jwt`; many accept only -public clients. A single-valued `token_endpoint_auth_method` gives a client no -way to express "either, depending on what you support." In practice that -forces the lowest common denominator: the client is forced to publish `none`, and the -servers that _could_ have required a signed assertion never learn the client -was capable of one. +have uniform capabilities. A single-valued `token_endpoint_auth_method` gives +a client no way to express "any of these, depending on what you support." The broader OAuth/OIDC ecosystem has already solved this capability negotiation problem by moving from single-valued to multi-valued parameters. @@ -94,20 +90,12 @@ Authorization servers **MUST** support reading omit it are handled as described in [Deprecated Declarations](#deprecated-declarations). -For illustration, a client that can operate either as a public client or with -an assertion-based credential might publish: +For illustration, a client that supports two registered methods might publish: ```json "token_endpoint_auth_methods_supported": ["none", "private_key_jwt"] ``` -Here `none` indicates the client can act as a public client with no client -authentication at the token endpoint, and `private_key_jwt` indicates it can -authenticate with a signed JWT assertion per -[RFC 7523](https://datatracker.ietf.org/doc/html/rfc7523), using the JWKS -referenced by the CIMD document (see -[Section 6.2 of the Client ID Metadata Document draft](https://www.ietf.org/archive/id/draft-ietf-oauth-client-id-metadata-document-00.html#section-6.2)). - ### Method Resolution The client and authorization server determine the set of mutually supported @@ -115,15 +103,17 @@ token endpoint client authentication methods by intersecting the client's `token_endpoint_auth_methods_supported` array with the authorization server's `token_endpoint_auth_methods_supported` metadata value. -- The client **MUST** use a method from the intersection. +- The client **MUST** select and use a method from the intersection. - When the client's singular `token_endpoint_auth_method` is present and mutually supported, the client **SHOULD** use that method to preserve compatibility with authorization servers that treat the singular field as binding. -- When the singular method is absent or unsupported, the client **MAY** use - another mutually supported method. Authorization servers that understand the - array **SHOULD** accept mutually supported methods that satisfy their local - security policies. +- When the singular method is absent or unsupported, the client **MAY** select + another method from the intersection. +- After reading `token_endpoint_auth_methods_supported` from the CIMD + document, an authorization server **SHOULD** accept any method in the + intersection, unless its local security policy disallows that method for + the client. - If the intersection is empty, the client **MUST NOT** proceed, and the authorization server **MUST** reject the client. - Authorization servers **MUST** reject any method outside the intersection. @@ -210,10 +200,7 @@ clients. The client selects a mutually supported method without requiring the authorization server to communicate a selected method back to the client. Preserving the singular preference when possible keeps existing -authorization-server behavior intact. This follows -[OpenID Federation 1.0, Section 12.1.4](https://openid.net/specs/openid-federation-1_0.html#section-12.1.4), -which requires clients to use mutually supported methods and recommends that -authorization servers accept them. +authorization-server behavior intact. The field is required (MUST) rather than recommended (SHOULD) because explicit behavior is crucial for authentication mechanisms. A required field gives @@ -297,26 +284,20 @@ with the other. ## Security Implications -This proposal does not introduce a new authentication mechanism. It allows a -client to advertise multiple existing methods while preserving the +This proposal does not introduce or rank authentication mechanisms. It allows +a client to advertise multiple existing methods while preserving the authorization server's ability to enforce its local security policy. -An authorization server that accepts `none` treats the client as a public -client for that interaction. Servers requiring client authentication can -reject `none`, and clients can prefer authenticated methods when compatible -with their deployment and backwards-compatibility requirements. - ## Reference Implementation [ChatGPT's public Client ID Metadata Document](https://chatgpt.com/oauth/client.json) -advertises both methods, prefers `private_key_jwt` for backwards compatibility, -and includes the key material required to authenticate: +advertises two methods and publishes one as its backwards-compatible singular +preference: ```json { "token_endpoint_auth_methods_supported": ["none", "private_key_jwt"], - "token_endpoint_auth_method": "private_key_jwt", - "jwks_uri": "https://chatgpt.com/oauth/jwks.json" + "token_endpoint_auth_method": "private_key_jwt" } ``` @@ -339,11 +320,6 @@ to be linked. - Should `implicit ["none"]` and `token_endpoint_auth_method` be deprecated, or should allowances be made to not break existing CIMD clients? -- Should MCP recommend preferring authenticated methods over `none`, and how - would that interact with authorization servers that treat the singular - method as binding? -- How should an authorization server report an incompatible CIMD client when - it has not established a trusted redirect URI? ## Acknowledgments diff --git a/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md b/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md index 1a027eeea..5dece3f7e 100644 --- a/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md +++ b/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md @@ -32,12 +32,8 @@ never in normative prose. A CIMD document is published at a single URL and consumed by every authorization server the client ever connects to, and those servers do not -have uniform capabilities. Some support `private_key_jwt`; many accept only -public clients. A single-valued `token_endpoint_auth_method` gives a client no -way to express "either, depending on what you support." In practice that -forces the lowest common denominator: the client is forced to publish `none`, and the -servers that _could_ have required a signed assertion never learn the client -was capable of one. +have uniform capabilities. A single-valued `token_endpoint_auth_method` gives +a client no way to express "any of these, depending on what you support." The broader OAuth/OIDC ecosystem has already solved this capability negotiation problem by moving from single-valued to multi-valued parameters. @@ -75,20 +71,12 @@ Authorization servers **MUST** support reading omit it are handled as described in [Deprecated Declarations](#deprecated-declarations). -For illustration, a client that can operate either as a public client or with -an assertion-based credential might publish: +For illustration, a client that supports two registered methods might publish: ```json "token_endpoint_auth_methods_supported": ["none", "private_key_jwt"] ``` -Here `none` indicates the client can act as a public client with no client -authentication at the token endpoint, and `private_key_jwt` indicates it can -authenticate with a signed JWT assertion per -[RFC 7523](https://datatracker.ietf.org/doc/html/rfc7523), using the JWKS -referenced by the CIMD document (see -[Section 6.2 of the Client ID Metadata Document draft](https://www.ietf.org/archive/id/draft-ietf-oauth-client-id-metadata-document-00.html#section-6.2)). - ### Method Resolution The client and authorization server determine the set of mutually supported @@ -96,15 +84,17 @@ token endpoint client authentication methods by intersecting the client's `token_endpoint_auth_methods_supported` array with the authorization server's `token_endpoint_auth_methods_supported` metadata value. -- The client **MUST** use a method from the intersection. +- The client **MUST** select and use a method from the intersection. - When the client's singular `token_endpoint_auth_method` is present and mutually supported, the client **SHOULD** use that method to preserve compatibility with authorization servers that treat the singular field as binding. -- When the singular method is absent or unsupported, the client **MAY** use - another mutually supported method. Authorization servers that understand the - array **SHOULD** accept mutually supported methods that satisfy their local - security policies. +- When the singular method is absent or unsupported, the client **MAY** select + another method from the intersection. +- After reading `token_endpoint_auth_methods_supported` from the CIMD + document, an authorization server **SHOULD** accept any method in the + intersection, unless its local security policy disallows that method for + the client. - If the intersection is empty, the client **MUST NOT** proceed, and the authorization server **MUST** reject the client. - Authorization servers **MUST** reject any method outside the intersection. @@ -191,10 +181,7 @@ clients. The client selects a mutually supported method without requiring the authorization server to communicate a selected method back to the client. Preserving the singular preference when possible keeps existing -authorization-server behavior intact. This follows -[OpenID Federation 1.0, Section 12.1.4](https://openid.net/specs/openid-federation-1_0.html#section-12.1.4), -which requires clients to use mutually supported methods and recommends that -authorization servers accept them. +authorization-server behavior intact. The field is required (MUST) rather than recommended (SHOULD) because explicit behavior is crucial for authentication mechanisms. A required field gives @@ -278,26 +265,20 @@ with the other. ## Security Implications -This proposal does not introduce a new authentication mechanism. It allows a -client to advertise multiple existing methods while preserving the +This proposal does not introduce or rank authentication mechanisms. It allows +a client to advertise multiple existing methods while preserving the authorization server's ability to enforce its local security policy. -An authorization server that accepts `none` treats the client as a public -client for that interaction. Servers requiring client authentication can -reject `none`, and clients can prefer authenticated methods when compatible -with their deployment and backwards-compatibility requirements. - ## Reference Implementation [ChatGPT's public Client ID Metadata Document](https://chatgpt.com/oauth/client.json) -advertises both methods, prefers `private_key_jwt` for backwards compatibility, -and includes the key material required to authenticate: +advertises two methods and publishes one as its backwards-compatible singular +preference: ```json { "token_endpoint_auth_methods_supported": ["none", "private_key_jwt"], - "token_endpoint_auth_method": "private_key_jwt", - "jwks_uri": "https://chatgpt.com/oauth/jwks.json" + "token_endpoint_auth_method": "private_key_jwt" } ``` @@ -320,11 +301,6 @@ to be linked. - Should `implicit ["none"]` and `token_endpoint_auth_method` be deprecated, or should allowances be made to not break existing CIMD clients? -- Should MCP recommend preferring authenticated methods over `none`, and how - would that interact with authorization servers that treat the singular - method as binding? -- How should an authorization server report an incompatible CIMD client when - it has not established a trusted redirect URI? ## Acknowledgments