Repository navigation
Conversation
Revised the DPoP extension documentation to clarify the purpose, scope, and requirements for sender-constrained access tokens in the Model Context Protocol. Enhanced explanations of DPoP proof requirements, content digest calculations, and replay protection mechanisms.
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.
Clarified error codes for DPoP proof validation failures and access token issues. See modelcontextprotocol/conformance#528
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.
Added details on MCP server DPoP advertisement and requirements for DPoP-bound access tokens.
Removed extra line break in the DPoP challenge section.
Clarify requirements for DPoP challenge in WWW-Authenticate header.
Adds a SHOULD for MCP clients to bind the authorization code to their DPoP key per RFC 9449 Section 10. RFC 9449 makes this OPTIONAL; this profile recommends it as defense in depth alongside MCP’s mandatory PKCE. Surfaced by the conformance work in modelcontextprotocol/conformance#523; kept separate from #33 so the two can be discussed and merged independently.
Clarified DPoP proof validation requirements and replay protection mechanisms for MCP servers, emphasizing the rejection of invalid 'iat' claims and the use of nonces for enhanced security.
Added section on server-provided nonces in DPoP proofs, detailing requirements for authorization and MCP servers regarding nonce handling and client behavior.
Added section on obtaining DPoP-bound access tokens, detailing requirements for MCP clients to include DPoP proof in token requests.
Clarified nonce usage and replay protection mechanisms for DPoP Proofs, including guidance on client binding and stateless server requirements.
Add example challenge for server supporting dual authentication schemes with scope and resource metadata.
Move Pieter Kasselman's DPoP profile from specification/draft/ to specification/experimental/dpop.mdx and list it in README.md. The only changes to the text are the ones Prettier makes, so the format check passes.
|
I'm implicitly approving this as experimental given the amount of work and conversation we've had about it. Note that in SEP-3392 terms, experimental is for prototypes, and the move to
|
| "authorization_endpoint": "https://auth.example.com/authorize", | ||
| "token_endpoint": "https://auth.example.com/token", | ||
| "dpop_signing_alg_values_supported": ["ES256", "PS256"] | ||
| } |
There was a problem hiding this comment.
In a recent discussion with @ThisIsMissEm we noticed that there is no AS Metadata parameter to indicate that DPoP is required by an AS. There's a DCR Metadata param, a RS Metadata param, but no AS Metadata param. Should we propose one to IANA? (very much outside the scope of this PR)
| WWW-Authenticate: Bearer scope="files:read", | ||
| resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource/mcp", | ||
| DPoP algs="ES256 PS256" | ||
| ``` |
There was a problem hiding this comment.
Reading https://www.rfc-editor.org/info/rfc9110/#section-11.6.1 - it looks like WWW-Auth can operate in two ways:
- a challenge + list of params per challenge, one per header
- A list of (challenge, param list), all under one header
The params are unique to the challenge, and are not shared among challenges. The §11.6.1 example shows multiple challenges describing the realm param.
So I think that we need to restate scope and resource_metadata on the DPoP challenge as well
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer scope="files:read",
resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource/mcp",
DPoP algs="ES256 PS256", scope="files:read",
resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource/mcp"
We could also use an example showing WWW-Auth split over multiple headers, which is also valid (ref)
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer scope="files:read", resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource/mcp"
WWW-Authenticate: DPoP scope="files:read", resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource/mcp", algs="ES256 PS256"
There was a problem hiding this comment.
Good catch, agreed parameters should belong to a specific challenge. Our server already repeats resource_metadata on the DPoP challenge. I folded this into my suggestion below too.
|
|
||
| ### DPoP Limitations | ||
|
|
||
| DPoP does not prevent token theft, but provides a mechanism that allows detection of replay attacks that utilise a stolen token. In addition, DPoP does not address confused deputy vulnerabilities or other authorization-level attacks. Consequently. implementations must maintain defense in depth by implementing all required security controls. |
There was a problem hiding this comment.
| DPoP does not prevent token theft, but provides a mechanism that allows detection of replay attacks that utilise a stolen token. In addition, DPoP does not address confused deputy vulnerabilities or other authorization-level attacks. Consequently. implementations must maintain defense in depth by implementing all required security controls. | |
| DPoP does not prevent token theft, but provides a mechanism that allows detection of replay attacks that utilise a stolen token. In addition, DPoP does not address confused deputy vulnerabilities or other authorization-level attacks. Consequently, implementations must maintain defense in depth by implementing all required security controls. |
|
|
||
| ### Error Response Example | ||
|
|
||
| When validation fails, the MCP server returns an error response: |
There was a problem hiding this comment.
Would also <3 an error response showing the nonce
HTTP/1.1 401 Unauthorized
WWW-Authenticate: DPoP error="use_dpop_nonce",
error_description="Fresh nonce required in DPoP proof",
algs="ES256 PS256"
DPoP-Nonce: eyJ7S_zG.eyJH0-Z.HX4w-7v
Content-Type: application/json
{
"jsonrpc": "2.0",
"error": {
"code": -32001,
"message": "Unauthorized"
},
"id": 1
}
There was a problem hiding this comment.
Should this error include resource_metadata and/or scope args?
|
|
||
| ``` | ||
| HTTP/1.1 401 Unauthorized | ||
| WWW-Authenticate: DPoP error="invalid_dpop_proof", |
There was a problem hiding this comment.
Should this error include resource_metadata and/or scope args?
| - Deployments where token theft risk is elevated. | ||
| - Compliance requirements mandating proof of possession or sender constrained tokens. | ||
|
|
||
| This extension uses DPoP as defined in [RFC 9449](https://datatracker.ietf.org/doc/html/rfc9449), without introducing MCP-specific claims, request body digests, or additional proof material. This design choice reflects a deliberate trade-off in favor of interoperability, deployability, and alignment with existing OAuth 2.0 security models. It does not preclude the use of the extension mechanisms defined in [RFC 9449](https://datatracker.ietf.org/doc/html/rfc9449). |
There was a problem hiding this comment.
Should we be more specific about the trade-off somewhere in the spec? Namely htm and htu are always the same for MCP servers, which makes it possible that a DPoP proof can be replayed if the RS doesn't check jti and the proof is still valid.
| When making requests to protected MCP server resources, clients MUST: | ||
|
|
||
| 1. Include the access token using the `Authorization` header with the `DPoP` authentication scheme as specified in [RFC 9449 Section 7.1](https://datatracker.ietf.org/doc/html/rfc9449#section-7.1) | ||
| 2. Include a fresh DPoP proof in the `DPoP` header |
There was a problem hiding this comment.
nit: fresh is hard to pin down. Does fresh mean one per request? One non-expired proof?
| 2. Include a fresh DPoP proof in the `DPoP` header | |
| 2. Include a valid DPoP proof in the `DPoP` header |
|
|
||
| [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. | ||
|
|
||
| MCP servers are NOT required to track `jti` values, however, MCP servers MAY choose to implement `jti` tracking for additional security, following the guidance in [RFC 9449 Section 11.1](https://datatracker.ietf.org/doc/html/rfc9449#section-11.1). |
There was a problem hiding this comment.
This feels like the riskiest aspect of the extension. In vanilla DPoP, htm and htu add some level of binding to the specific request. An attacker could replay a DPoP proof, but only to the specific endpoint it was originally intended for. That works pretty sorta kinda well for REST, but breaks for RPC style APIs like MCP. htm and htu will always be the same on every request.
Would prefer stronger language here - a RECOMMENDED would go a long way if we don't feel comfortable with the performance implications of SHOULD
There was a problem hiding this comment.
Agree with RECOMMENDED being the stronger language. Our experimental RS tracks jti by default. Entries are keyed by proof tumbprint + jti, so one client cannot block another by guessing a jti and each entry lives only for the iat window. The cost is small next to the replay gap that constant htm/htu leaves open.
|
I snuck in a review! Don't consider any of my comments blocking - happy to iterate on main. |
There was a problem hiding this comment.
+1 to landing this as experimental. Our TypeScript resource server passes all 28 checks of auth/dpop-server-validation (modelcontextprotocol/conformance#529). These notes come from building against this text.
- Before merge: the file doesn't compile as MDX, and two examples contradict the text. Suggestions are inline.
- Non-blocking: my two #33 points (403 step-up, and
algsvs PRM) didn't carry over. I re-linked them inline so they survive #33 closing. Settling them onmainis fine.
Drafted with AI assistance. I checked each point against the file and our implementation.
|
|
||
| ### MCP Server Validation | ||
|
|
||
| MCP servers MUST validate DPoP proofs according to [RFC 9449 Section 4.3](https://datatracker.ietf.org/doc/html/rfc9449#section-4.3). Implementations conforming to this specification MUST reject DPoP proofs whose `iat` claim falls outside ±5 minutes of the server's current time. Servers MAY enforce a narrower acceptance window (see {{proof-validity-window}}). |
There was a problem hiding this comment.
This file doesn't compile as MDX. MDX parses {...} as a JavaScript expression, so {{proof-validity-window}} fails (@mdx-js/mdx 3: "Could not parse expression with acorn" at 83:342). The same break is on lines 93, 250, 252, 256 and 272. CI misses it because it runs only Prettier and the link check. Plain anchor links fix it:
| MCP servers MUST validate DPoP proofs according to [RFC 9449 Section 4.3](https://datatracker.ietf.org/doc/html/rfc9449#section-4.3). Implementations conforming to this specification MUST reject DPoP proofs whose `iat` claim falls outside ±5 minutes of the server's current time. Servers MAY enforce a narrower acceptance window (see {{proof-validity-window}}). | |
| MCP servers MUST validate DPoP proofs according to [RFC 9449 Section 4.3](https://datatracker.ietf.org/doc/html/rfc9449#section-4.3). Implementations conforming to this specification MUST reject DPoP proofs whose `iat` claim falls outside ±5 minutes of the server's current time. Servers MAY enforce a narrower acceptance window (see [Proof Validity Window](#proof-validity-window)). |
|
|
||
| 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} |
There was a problem hiding this comment.
Same MDX fix.
| ### Stateless Operation and DPoP Proof Replay Protection {#stateless-replay-protection} | |
| ### Stateless Operation and DPoP Proof Replay Protection |
| - The baseline MCP Authorization specification security requirements | ||
| - OAuth 2.1 security best practices | ||
|
|
||
| In addition, MCP servers MUST provide DPoP proof replay protection as described in {{stateless-replay-protection}} |
There was a problem hiding this comment.
Same MDX fix.
| In addition, MCP servers MUST provide DPoP proof replay protection as described in {{stateless-replay-protection}} | |
| In addition, MCP servers MUST provide DPoP proof replay protection as described in [Stateless Operation and DPoP Proof Replay Protection](#stateless-operation-and-dpop-proof-replay-protection). |
|
|
||
| In addition, MCP servers MUST provide DPoP proof replay protection as described in {{stateless-replay-protection}} | ||
|
|
||
| ### Proof Validity Window {#proof-validity-window} |
There was a problem hiding this comment.
Same MDX fix.
| ### Proof Validity Window {#proof-validity-window} | |
| ### Proof Validity Window |
|
|
||
| The ±5 minute bound balances security and usability. MCP servers MAY enforce a narrower window within it, but should be aware that overly restrictive windows may cause operational issues due to clock skew in distributed systems. | ||
|
|
||
| For high-security environments, MCP servers SHOULD implement server-provided nonces as described in [RFC 9449 Section 9](https://datatracker.ietf.org/doc/html/rfc9449#section-9) to further limit proof lifetime, even if it is stateless (see {{stateless-replay-protection}}). |
There was a problem hiding this comment.
Same MDX fix.
| For high-security environments, MCP servers SHOULD implement server-provided nonces as described in [RFC 9449 Section 9](https://datatracker.ietf.org/doc/html/rfc9449#section-9) to further limit proof lifetime, even if it is stateless (see {{stateless-replay-protection}}). | |
| For high-security environments, MCP servers SHOULD implement server-provided nonces as described in [RFC 9449 Section 9](https://datatracker.ietf.org/doc/html/rfc9449#section-9) to further limit proof lifetime, even if it is stateless (see [Stateless Operation and DPoP Proof Replay Protection](#stateless-operation-and-dpop-proof-replay-protection)). |
|
|
||
| ### Replay Detection Without State | ||
|
|
||
| Replay protection options for stateless MCP servers are described in {{stateless-replay-protection}}. MCP servers requiring maximum replay protection SHOULD implement `jti` tracking despite the operational complexity. The trade-offs are discussed in detail in [RFC 9449 Section 11.1](https://datatracker.ietf.org/doc/html/rfc9449#section-11.1). |
There was a problem hiding this comment.
Same MDX fix.
| Replay protection options for stateless MCP servers are described in {{stateless-replay-protection}}. MCP servers requiring maximum replay protection SHOULD implement `jti` tracking despite the operational complexity. The trade-offs are discussed in detail in [RFC 9449 Section 11.1](https://datatracker.ietf.org/doc/html/rfc9449#section-11.1). | |
| Replay protection options for stateless MCP servers are described in [Stateless Operation and DPoP Proof Replay Protection](#stateless-operation-and-dpop-proof-replay-protection). MCP servers requiring maximum replay protection SHOULD implement `jti` tracking despite the operational complexity. The trade-offs are discussed in detail in [RFC 9449 Section 11.1](https://datatracker.ietf.org/doc/html/rfc9449#section-11.1). |
| Content-Length: 52 | ||
| Authorization: DPoP eyJhbGciOiJFUzI1NiIsImtpZCI6IkJlQUxrYiJ9.eyJzdWIiOiJzb21lb25lQGV4YW1wbGUuY29tIiwiaXNzIjoiaHR0cHM6Ly9hdXRoLmV4YW1wbGUuY29tIiwiYXVkIjoiaHR0cHM6Ly9tY3AuZXhhbXBsZS5jb20iLCJuYmYiOjE2OTk1NjQyMTEsImV4cCI6MTY5OTU2NzgxMSwiY25mIjp7ImprdCI6IjBaY09DT1JaTll5LURXcHFxMzBqWnlKR0hUTjBkMkhnbEJWM3VpZ3VBNEkifX0.fT0eG8Qa0nKW8P0qT6YZqVhBnb2r5Q0yX7VqA8Zr1Yk | ||
| DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6IkVDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCRnMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5REFLVXJVMENZR1JEQSIsImNydiI6IlAtMjU2In19LnsianlpIjoiZTFqM1ZfYktpYzgtTEFFQiIsImh0bSI6IlBPU1QiLCJodHUiOiJodHRwczovL21jcC5leGFtcGxlLmNvbS9tY3AiLCJpYXQiOjE2OTk1NjQyMTgsImF0aCI6ImZVSHlPMnIyWjNEWjUzRXNOcldCYjB4V1hvYU55NTlJaUtDQXFrc21RRW8ifQ==.mHN0qXKq_EXAMPLE_SIGNATURE_DATA_HERE |
There was a problem hiding this comment.
Implementers will try to verify this example, and it fails:
- The
DPoPproof has two segments, not three. Header and payload are encoded together with the.inside. - The decoded payload has
jyi, notjti. The header'sydiffers from line 189. athis the RFC 9449 example value, not the hash of the token on line 214.- The token's
audishttps://mcp.example.com, but the PRMresourceishttps://mcp.example.com/mcp. The audience check on line 280 rejects it. - The body is 46 bytes, not 52.
Cheapest fix: truncate both tokens, as the first example (lines 60-61) does, and drop Content-Length. A consistent test vector can come later on main.
| Content-Length: 52 | |
| Authorization: DPoP eyJhbGciOiJFUzI1NiIsImtpZCI6IkJlQUxrYiJ9.eyJzdWIiOiJzb21lb25lQGV4YW1wbGUuY29tIiwiaXNzIjoiaHR0cHM6Ly9hdXRoLmV4YW1wbGUuY29tIiwiYXVkIjoiaHR0cHM6Ly9tY3AuZXhhbXBsZS5jb20iLCJuYmYiOjE2OTk1NjQyMTEsImV4cCI6MTY5OTU2NzgxMSwiY25mIjp7ImprdCI6IjBaY09DT1JaTll5LURXcHFxMzBqWnlKR0hUTjBkMkhnbEJWM3VpZ3VBNEkifX0.fT0eG8Qa0nKW8P0qT6YZqVhBnb2r5Q0yX7VqA8Zr1Yk | |
| DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6IkVDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCRnMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5REFLVXJVMENZR1JEQSIsImNydiI6IlAtMjU2In19LnsianlpIjoiZTFqM1ZfYktpYzgtTEFFQiIsImh0bSI6IlBPU1QiLCJodHUiOiJodHRwczovL21jcC5leGFtcGxlLmNvbS9tY3AiLCJpYXQiOjE2OTk1NjQyMTgsImF0aCI6ImZVSHlPMnIyWjNEWjUzRXNOcldCYjB4V1hvYU55NTlJaUtDQXFrc21RRW8ifQ==.mHN0qXKq_EXAMPLE_SIGNATURE_DATA_HERE | |
| Authorization: DPoP eyJhbGciOiJFUzI1NiIsImtpZCI6IkJlQUxrYiJ9... | |
| DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6... |
| WWW-Authenticate: DPoP error="invalid_dpop_proof", | ||
| error_description="Content digest mismatch" |
There was a problem hiding this comment.
Line 41 says this profile adds no request body digests, so this error can't happen. Line 151 also says the 401 challenge SHOULD carry algs. This uses an RFC 9449 §4.3 failure and adds algs:
| WWW-Authenticate: DPoP error="invalid_dpop_proof", | |
| error_description="Content digest mismatch" | |
| WWW-Authenticate: DPoP error="invalid_dpop_proof", | |
| error_description="DPoP proof htu does not match the request URI", | |
| algs="ES256 PS256" |
|
|
||
| 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). |
There was a problem hiding this comment.
Non-blocking, carried over from my #33 review (#33 (comment)). Does "every WWW-Authenticate response" include a 403 insufficient_scope step-up? Scope checks often run outside the auth gate. In the TypeScript SDK, a per-tool requireScopes check answers 403 with a Bearer-only challenge, even after DPoP authentication. One sentence settles it:
| 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). | |
| 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. This includes HTTP 403 responses with the `insufficient_scope` error code, such as responses to per-operation scope checks. 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). |
|
|
||
| ### 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). |
There was a problem hiding this comment.
Non-blocking, carried over from #33 (#33 (comment)). Nothing ties algs to dpop_signing_alg_values_supported, which line 172 calls authoritative. They differ in practice: the TypeScript SDK challenge lists 10 algorithms, while a deployment's PRM can list only ES256. Both conform today.
| 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). If the `algs` parameter is present, it MUST contain the same algorithms as the `dpop_signing_alg_values_supported` field in the server's Protected Resource Metadata. The DPoP challenge MAY appear alongside other challenges, such as a Bearer challenge. Parameters belong to the challenge that carries them (RFC 9110 Section 11.6.1 (https://www.rfc-editor.org/rfc/rfc9110#section-11.6.1)), so a DPoP challenge repeats any resource_metadata or scope parameter that another challenge in the response carries. |
If the PRM is meant to be able to list a subset, one sentence saying the PRM wins when they differ also works.
Brings @PieterKas's DPoP profile to
specification/experimental/dpop.mdx, as an Experimental extension under SEP-3392. The proposal is SEP-1932.pieterkas-dpop-extensionand the heads of DPoP: Update DPoP profile with server requirements from conformance implementation feedback #33, DPoP: Add authorization code binding recommendation (dpop_jkt) #35 and Harmonizing requriements across documents and the conformance suite #36, keeping all 18 of his commits.README.md.@PieterKas feel free to push final tweaks here before it merges. Experimental carries no stability promise, so the rest can be settled on
main. The more serious review milestone comes before promotion tobeta.