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..a36b1f597 --- /dev/null +++ b/docs/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.mdx @@ -0,0 +1,326 @@ +--- +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) [@stevenlee-oai](https://github.com/stevenlee-oai) | +| **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. 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. +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. 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 +omit it are handled as described in +[Deprecated Declarations](#deprecated-declarations). + +For illustration, a client that supports two registered methods might publish: + +```json +"token_endpoint_auth_methods_supported": ["none", "private_key_jwt"] +``` + +### Method Resolution + +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. + +- 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** 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. + +For example: + +| 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 + +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 + 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. + +- 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 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. +- 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. + +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` | `["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 + +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 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. + +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. 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 + +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 +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. + +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 +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 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. + +## Reference Implementation + +[ChatGPT's public Client ID Metadata Document](https://chatgpt.com/oauth/client.json) +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" +} +``` + +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. + +## 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 new file mode 100644 index 000000000..5dece3f7e --- /dev/null +++ b/seps/3149-require-token-endpoint-auth-methods-supported-in-cimd.md @@ -0,0 +1,307 @@ +# 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 @stevenlee-oai +- **Sponsor**: @pcarleton +- **PR**: 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. 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. +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. 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 +omit it are handled as described in +[Deprecated Declarations](#deprecated-declarations). + +For illustration, a client that supports two registered methods might publish: + +```json +"token_endpoint_auth_methods_supported": ["none", "private_key_jwt"] +``` + +### Method Resolution + +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. + +- 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** 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. + +For example: + +| 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 + +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 + 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. + +- 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 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. +- 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. + +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` | `["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 + +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 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. + +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. 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 + +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 +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. + +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 +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 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. + +## Reference Implementation + +[ChatGPT's public Client ID Metadata Document](https://chatgpt.com/oauth/client.json) +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" +} +``` + +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. + +## 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.