From f6a0eb779b4ea4a22c7611dccf8150662a24621f Mon Sep 17 00:00:00 2001 From: PieterKas <90690777+PieterKas@users.noreply.github.com> Date: Thu, 1 Oct 2026 16:28:26 +0100 Subject: [PATCH 1/7] Add Bearer Scheme Downgrade Protection section Added section on Bearer Scheme Downgrade Protection, specifying that DPoP-bound access tokens must not be used as bearer tokens and detailing the server's response requirements. --- specification/draft/dpop-extension.mdx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/specification/draft/dpop-extension.mdx b/specification/draft/dpop-extension.mdx index 20fafb1..5cd98e0 100644 --- a/specification/draft/dpop-extension.mdx +++ b/specification/draft/dpop-extension.mdx @@ -65,6 +65,10 @@ MCP servers MUST validate DPoP proofs according to [RFC 9449 Section 4.3](https: If any validation step fails, the MCP server MUST reject the request with an HTTP 401 response and include appropriate error information in the `WWW-Authenticate` header as specified in [RFC 9449 Section 7.1](https://datatracker.ietf.org/doc/html/rfc9449#section-7.1). +### Bearer Scheme Downgrade Protection + +A DPoP-bound access token is sender-constrained and MUST NOT be usable as a bearer token. MCP servers MUST NOT accept a DPoP-bound access token presented using the `Bearer` authentication scheme (see [RFC 9449 Section 7.2](https://datatracker.ietf.org/doc/html/rfc9449#section-7.2)). The MCP server MUST reject such a request with an HTTP 401 response that includes a `WWW-Authenticate` challenge using the `Bearer` ([RFC 6750 Section 3](https://datatracker.ietf.org/doc/html/rfc6750#section-3)) or `DPoP` ([RFC 9449 Section 7.1](https://datatracker.ietf.org/doc/html/rfc9449#section-7.1)) scheme, and SHOULD indicate the `invalid_token` error code ([RFC 6750 Section 3.1](https://datatracker.ietf.org/doc/html/rfc6750#section-3.1)). + ### Stateless Operation and DPoP Proof Replay Protection {#stateless-replay-protection} [RFC 9449 Section 11.1](https://www.rfc-editor.org/rfc/rfc9449.html#name-dpop-proof-replay) provides specific guidance on replay protection mechanisms that adress the risks of a DPoP Proofs being replayed. From c7cbbdbbb730152b499d25d5d8094b61719ec16c Mon Sep 17 00:00:00 2001 From: PieterKas <90690777+PieterKas@users.noreply.github.com> Date: Thu, 1 Oct 2026 20:03:42 +0100 Subject: [PATCH 2/7] Specify error codes for DPoP request rejections Clarified error codes for DPoP proof validation failures and access token issues. See https://github.com/modelcontextprotocol/conformance/pull/528 --- specification/draft/dpop-extension.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/specification/draft/dpop-extension.mdx b/specification/draft/dpop-extension.mdx index 5cd98e0..ed7dc2b 100644 --- a/specification/draft/dpop-extension.mdx +++ b/specification/draft/dpop-extension.mdx @@ -65,6 +65,8 @@ MCP servers MUST validate DPoP proofs according to [RFC 9449 Section 4.3](https: If any validation step fails, the MCP server MUST reject the request with an HTTP 401 response and include appropriate error information in the `WWW-Authenticate` header as specified in [RFC 9449 Section 7.1](https://datatracker.ietf.org/doc/html/rfc9449#section-7.1). +When rejecting a request, the MCP server SHOULD use the `invalid_dpop_proof`error code for any failure of the [RFC 9449 Section 4.3](https://datatracker.ietf.org/doc/html/rfc9449#section-4.3) validation steps, including a malformed or duplicated `DPoP` header, and the `invalid_token` error code for failures of the access token itself ([RFC 6750 Section 3.1] https://datatracker.ietf.org/doc/html/rfc6750#section-3.1)). + ### Bearer Scheme Downgrade Protection A DPoP-bound access token is sender-constrained and MUST NOT be usable as a bearer token. MCP servers MUST NOT accept a DPoP-bound access token presented using the `Bearer` authentication scheme (see [RFC 9449 Section 7.2](https://datatracker.ietf.org/doc/html/rfc9449#section-7.2)). The MCP server MUST reject such a request with an HTTP 401 response that includes a `WWW-Authenticate` challenge using the `Bearer` ([RFC 6750 Section 3](https://datatracker.ietf.org/doc/html/rfc6750#section-3)) or `DPoP` ([RFC 9449 Section 7.1](https://datatracker.ietf.org/doc/html/rfc9449#section-7.1)) scheme, and SHOULD indicate the `invalid_token` error code ([RFC 6750 Section 3.1](https://datatracker.ietf.org/doc/html/rfc6750#section-3.1)). From 061b1c0689fba361d98832bdca7dc1af9c3bb5c8 Mon Sep 17 00:00:00 2001 From: PieterKas <90690777+PieterKas@users.noreply.github.com> Date: Thu, 1 Oct 2026 20:14:38 +0100 Subject: [PATCH 3/7] Fix formatting of error code references in DPoP section --- specification/draft/dpop-extension.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/draft/dpop-extension.mdx b/specification/draft/dpop-extension.mdx index ed7dc2b..9a16ad9 100644 --- a/specification/draft/dpop-extension.mdx +++ b/specification/draft/dpop-extension.mdx @@ -65,7 +65,7 @@ MCP servers MUST validate DPoP proofs according to [RFC 9449 Section 4.3](https: If any validation step fails, the MCP server MUST reject the request with an HTTP 401 response and include appropriate error information in the `WWW-Authenticate` header as specified in [RFC 9449 Section 7.1](https://datatracker.ietf.org/doc/html/rfc9449#section-7.1). -When rejecting a request, the MCP server SHOULD use the `invalid_dpop_proof`error code for any failure of the [RFC 9449 Section 4.3](https://datatracker.ietf.org/doc/html/rfc9449#section-4.3) validation steps, including a malformed or duplicated `DPoP` header, and the `invalid_token` error code for failures of the access token itself ([RFC 6750 Section 3.1] https://datatracker.ietf.org/doc/html/rfc6750#section-3.1)). +When rejecting a request, the MCP server SHOULD use the `invalid_dpop_proof` error code for any failure of the [RFC 9449 Section 4.3](https://datatracker.ietf.org/doc/html/rfc9449#section-4.3) validation steps, including a malformed or duplicated `DPoP` header, and the `invalid_token` error code for failures of the access token itself ([RFC 6750 Section 3.1](https://datatracker.ietf.org/doc/html/rfc6750#section-3.1)). ### Bearer Scheme Downgrade Protection From e4458f0f7f52056acc8b4deb2ae49d980740e681 Mon Sep 17 00:00:00 2001 From: PieterKas <90690777+PieterKas@users.noreply.github.com> Date: Fri, 2 Oct 2026 13:57:12 +0100 Subject: [PATCH 4/7] Enhance DPoP extension with MCP server advertisement Added DPoP advertisement section for MCP servers, including requirements for `dpop_signing_alg_values_supported` and `dpop_bound_access_tokens_required` fields in Protected Resource Metadata. --- specification/draft/dpop-extension.mdx | 35 +++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/specification/draft/dpop-extension.mdx b/specification/draft/dpop-extension.mdx index 9a16ad9..6a67e92 100644 --- a/specification/draft/dpop-extension.mdx +++ b/specification/draft/dpop-extension.mdx @@ -20,6 +20,7 @@ This extension is based on the following established specifications: - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP) ([RFC 9449](https://datatracker.ietf.org/doc/html/rfc9449)) - OAuth 2.0 Authorization Server Metadata ([RFC8414](https://datatracker.ietf.org/doc/html/rfc8414)) +- OAuth 2.0 Protected Resource Metadata ([RFC 9728](https://datatracker.ietf.org/doc/html/rfc9728)) - JSON Web Algorithms (JWA) [RFC 7518 Section 5.2](https://www.rfc-editor.org/rfc/rfc7518) ## DPoP for MCP Resource Access @@ -92,7 +93,7 @@ Example Authorization Server Metadata: "issuer": "https://auth.example.com", "authorization_endpoint": "https://auth.example.com/authorize", "token_endpoint": "https://auth.example.com/token", - "dpop_signing_alg_values_supported": ["ES256", "RS256", "PS256"] + "dpop_signing_alg_values_supported": ["ES256", "PS256"] } ``` @@ -175,6 +176,38 @@ Content-Type: application/json ``` +## MCP Server DPoP Advertisement + +MCP clients need a way to learn that an MCP server supports or requires DPoP before presenting credentials. This section defines how MCP servers supporting this extension advertise that capability. The baseline MCP authorization discovery mechanisms (Protected Resource Metadata discovery via the `WWW-Authenticate` header or well-known URIs) are unchanged. + +### Protected Resource Metadata + +MCP servers supporting this extension MUST include the `dpop_signing_alg_values_supported` field in their Protected Resource Metadata ([RFC 9728 Section 2](https://datatracker.ietf.org/doc/html/rfc9728#section-2)). This field MUST contain a non-empty JSON array of registered JWS algorithm values (from the IANA JSON Web Signature and Encryption Algorithms registry) that the server accepts for DPoP proof JWTs. Only asymmetric digital signature algorithms are permitted. The `none` algorithm and symmetric (MAC) algorithms MUST NOT be included. + +An MCP server that requires DPoP-bound access tokens (that is, one that does not accept bearer tokens) MUST set the `dpop_bound_access_tokens_required` field to `true` in its Protected Resource Metadata. Conversely, an MCP server that sets `dpop_bound_access_tokens_required` to `true` MUST reject requests that do not present a DPoP-bound access token with a valid DPoP proof. When the field is absent, the default behavior defined in [RFC 9728](https://datatracker.ietf.org/doc/html/rfc9728) applies and DPoP-bound access tokens are not required. + +Example Protected Resource Metadata for a server that requires DPoP: + +```json +{ + "resource": "https://mcp.example.com/mcp", + "authorization_servers": ["https://auth.example.com"], + "dpop_signing_alg_values_supported": ["ES256", "PS256"], + "dpop_bound_access_tokens_required": true +} +``` +### WWW-Authenticate Challenge + +When responding to an unauthenticated or failed request with HTTP 401, an MCP server supporting this extension SHOULD include a `DPoP` challenge in the `WWW-Authenticate` header, and that challenge SHOULD include the `algs` parameter signaling the JWS algorithms acceptable for DPoP proof JWTs, as described in [RFC 9449 Section 7.1](https://datatracker.ietf.org/doc/html/rfc9449#section-7.1). The `DPoP` challenge MAY appear alongside other challenges, such as a `Bearer` challenge carrying the `resource_metadata` parameter defined in [RFC 9728 Section 5.1](https://datatracker.ietf.org/doc/html/rfc9728#section-5.1). + +Example challenge: + +``` +HTTP/1.1 401 Unauthorized +WWW-Authenticate: DPoP algs="ES256 PS256", + resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource/mcp" +``` + ## Security Considerations Implementations adopting this extension MUST follow the security considerations outlined in: From e6a2bbf0c600ea5fb4e0ea362d2e2beb2e5c9039 Mon Sep 17 00:00:00 2001 From: PieterKas <90690777+PieterKas@users.noreply.github.com> Date: Fri, 2 Oct 2026 14:04:06 +0100 Subject: [PATCH 5/7] Document MCP server DPoP advertisement requirements Added details on MCP server DPoP advertisement and requirements for DPoP-bound access tokens. --- specification/draft/dpop-extension.mdx | 64 +++++++++++++------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/specification/draft/dpop-extension.mdx b/specification/draft/dpop-extension.mdx index 6a67e92..4c82886 100644 --- a/specification/draft/dpop-extension.mdx +++ b/specification/draft/dpop-extension.mdx @@ -106,6 +106,38 @@ Clients that exclusively use DPoP MAY indicate this through the `dpop_bound_acce When this field is set to `true`, the authorization server MUST reject token requests from the client that do not include a valid DPoP proof. +## MCP Server DPoP Advertisement + +MCP clients need a way to learn that an MCP server supports or requires DPoP before presenting credentials. This section defines how MCP servers supporting this extension advertise that capability. The baseline MCP authorization discovery mechanisms (Protected Resource Metadata discovery via the `WWW-Authenticate` header or well-known URIs) are unchanged. + +### Protected Resource Metadata + +MCP servers supporting this extension MUST include the `dpop_signing_alg_values_supported` field in their Protected Resource Metadata ([RFC 9728 Section 2](https://datatracker.ietf.org/doc/html/rfc9728#section-2)). This field MUST contain a non-empty JSON array of registered JWS algorithm values (from the IANA JSON Web Signature and Encryption Algorithms registry) that the server accepts for DPoP proof JWTs. Only asymmetric digital signature algorithms are permitted. The `none` algorithm and symmetric (MAC) algorithms MUST NOT be included. + +An MCP server that requires DPoP-bound access tokens (that is, one that does not accept bearer tokens) MUST set the `dpop_bound_access_tokens_required` field to `true` in its Protected Resource Metadata. Conversely, an MCP server that sets `dpop_bound_access_tokens_required` to `true` MUST reject requests that do not present a DPoP-bound access token with a valid DPoP proof. When the field is absent, the default behavior defined in [RFC 9728](https://datatracker.ietf.org/doc/html/rfc9728) applies and DPoP-bound access tokens are not required. + +Example Protected Resource Metadata for a server that requires DPoP: + +```json +{ + "resource": "https://mcp.example.com/mcp", + "authorization_servers": ["https://auth.example.com"], + "dpop_signing_alg_values_supported": ["ES256", "PS256"], + "dpop_bound_access_tokens_required": true +} +``` +### WWW-Authenticate Challenge + +When responding to an unauthenticated or failed request with HTTP 401, an MCP server supporting this extension SHOULD include a `DPoP` challenge in the `WWW-Authenticate` header, and that challenge SHOULD include the `algs` parameter signaling the JWS algorithms acceptable for DPoP proof JWTs, as described in [RFC 9449 Section 7.1](https://datatracker.ietf.org/doc/html/rfc9449#section-7.1). The `DPoP` challenge MAY appear alongside other challenges, such as a `Bearer` challenge carrying the `resource_metadata` parameter defined in [RFC 9728 Section 5.1](https://datatracker.ietf.org/doc/html/rfc9728#section-5.1). + +Example challenge: + +``` +HTTP/1.1 401 Unauthorized +WWW-Authenticate: DPoP algs="ES256 PS256", + resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource/mcp" +``` + ## Examples ### Complete DPoP Proof Example @@ -176,38 +208,6 @@ Content-Type: application/json ``` -## MCP Server DPoP Advertisement - -MCP clients need a way to learn that an MCP server supports or requires DPoP before presenting credentials. This section defines how MCP servers supporting this extension advertise that capability. The baseline MCP authorization discovery mechanisms (Protected Resource Metadata discovery via the `WWW-Authenticate` header or well-known URIs) are unchanged. - -### Protected Resource Metadata - -MCP servers supporting this extension MUST include the `dpop_signing_alg_values_supported` field in their Protected Resource Metadata ([RFC 9728 Section 2](https://datatracker.ietf.org/doc/html/rfc9728#section-2)). This field MUST contain a non-empty JSON array of registered JWS algorithm values (from the IANA JSON Web Signature and Encryption Algorithms registry) that the server accepts for DPoP proof JWTs. Only asymmetric digital signature algorithms are permitted. The `none` algorithm and symmetric (MAC) algorithms MUST NOT be included. - -An MCP server that requires DPoP-bound access tokens (that is, one that does not accept bearer tokens) MUST set the `dpop_bound_access_tokens_required` field to `true` in its Protected Resource Metadata. Conversely, an MCP server that sets `dpop_bound_access_tokens_required` to `true` MUST reject requests that do not present a DPoP-bound access token with a valid DPoP proof. When the field is absent, the default behavior defined in [RFC 9728](https://datatracker.ietf.org/doc/html/rfc9728) applies and DPoP-bound access tokens are not required. - -Example Protected Resource Metadata for a server that requires DPoP: - -```json -{ - "resource": "https://mcp.example.com/mcp", - "authorization_servers": ["https://auth.example.com"], - "dpop_signing_alg_values_supported": ["ES256", "PS256"], - "dpop_bound_access_tokens_required": true -} -``` -### WWW-Authenticate Challenge - -When responding to an unauthenticated or failed request with HTTP 401, an MCP server supporting this extension SHOULD include a `DPoP` challenge in the `WWW-Authenticate` header, and that challenge SHOULD include the `algs` parameter signaling the JWS algorithms acceptable for DPoP proof JWTs, as described in [RFC 9449 Section 7.1](https://datatracker.ietf.org/doc/html/rfc9449#section-7.1). The `DPoP` challenge MAY appear alongside other challenges, such as a `Bearer` challenge carrying the `resource_metadata` parameter defined in [RFC 9728 Section 5.1](https://datatracker.ietf.org/doc/html/rfc9728#section-5.1). - -Example challenge: - -``` -HTTP/1.1 401 Unauthorized -WWW-Authenticate: DPoP algs="ES256 PS256", - resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource/mcp" -``` - ## Security Considerations Implementations adopting this extension MUST follow the security considerations outlined in: From 203c2f7a46bd93da616301557389906acdeb4cce Mon Sep 17 00:00:00 2001 From: PieterKas <90690777+PieterKas@users.noreply.github.com> Date: Fri, 2 Oct 2026 14:12:12 +0100 Subject: [PATCH 6/7] Fix formatting in DPoP challenge description Removed extra line break in the DPoP challenge section. --- specification/draft/dpop-extension.mdx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/specification/draft/dpop-extension.mdx b/specification/draft/dpop-extension.mdx index 4c82886..8f4fe2d 100644 --- a/specification/draft/dpop-extension.mdx +++ b/specification/draft/dpop-extension.mdx @@ -126,9 +126,10 @@ Example Protected Resource Metadata for a server that requires DPoP: "dpop_bound_access_tokens_required": true } ``` + ### WWW-Authenticate Challenge -When responding to an unauthenticated or failed request with HTTP 401, an MCP server supporting this extension SHOULD include a `DPoP` challenge in the `WWW-Authenticate` header, and that challenge SHOULD include the `algs` parameter signaling the JWS algorithms acceptable for DPoP proof JWTs, as described in [RFC 9449 Section 7.1](https://datatracker.ietf.org/doc/html/rfc9449#section-7.1). The `DPoP` challenge MAY appear alongside other challenges, such as a `Bearer` challenge carrying the `resource_metadata` parameter defined in [RFC 9728 Section 5.1](https://datatracker.ietf.org/doc/html/rfc9728#section-5.1). +When responding to an unauthenticated or failed request with HTTP 401, an MCP server supporting this extension SHOULD include a `DPoP` challenge in the `WWW-Authenticate` header, and that challenge SHOULD include the `algs` parameter signaling the JWS algorithms acceptable for DPoP proof JWTs, as described in [RFC 9449 Section 7.1](https://datatracker.ietf.org/doc/html/rfc9449#section-7.1). The `DPoP` challenge MAY appear alongside other challenges, such as a `Bearer` challenge carrying the `resource_metadata` parameter defined in [RFC 9728 Section 5.1](https://datatracker.ietf.org/doc/html/rfc9728#section-5.1). Example challenge: From 977e07663b1862bda943701d1131e55bf476a283 Mon Sep 17 00:00:00 2001 From: PieterKas <90690777+PieterKas@users.noreply.github.com> Date: Fri, 2 Oct 2026 15:13:25 +0100 Subject: [PATCH 7/7] Update DPoP challenge requirements in specification Clarify requirements for DPoP challenge in WWW-Authenticate header. --- specification/draft/dpop-extension.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/specification/draft/dpop-extension.mdx b/specification/draft/dpop-extension.mdx index 8f4fe2d..55cefad 100644 --- a/specification/draft/dpop-extension.mdx +++ b/specification/draft/dpop-extension.mdx @@ -131,6 +131,8 @@ Example Protected Resource Metadata for a server that requires DPoP: When responding to an unauthenticated or failed request with HTTP 401, an MCP server supporting this extension SHOULD include a `DPoP` challenge in the `WWW-Authenticate` header, and that challenge SHOULD include the `algs` parameter signaling the JWS algorithms acceptable for DPoP proof JWTs, as described in [RFC 9449 Section 7.1](https://datatracker.ietf.org/doc/html/rfc9449#section-7.1). The `DPoP` challenge MAY appear alongside other challenges, such as a `Bearer` challenge carrying the `resource_metadata` parameter defined in [RFC 9728 Section 5.1](https://datatracker.ietf.org/doc/html/rfc9728#section-5.1). +An MCP server that sets `dpop_bound_access_tokens_required` to `true` in its Protected Resource Metadata MUST include a `DPoP` challenge in every `WWW-Authenticate` response it sends. Other challenges MAY appear alongside it, for example a `Bearer` challenge used to deliver error information to a client that attempted bearer authentication, as described in [RFC 9449 Section 7.2](https://datatracker.ietf.org/doc/html/rfc9449#section-7.2). + Example challenge: ```