modelcontextprotocol / modelcontextprotocol/conformance
Server Auth: DPoP Proof Validation (SEP-1932)
Nessuno ha ancora preso questa issue.
- Lingua principale
- TypeScript
- Stelle
- 127
- Fork
- 101
- Merge medio
- 6g 1h
- PR unite (30g)
- 7
Descrizione
Overview
SEP-1932
adopts OAuth 2.0 Demonstrating Proof of Possession
(RFC 9449) as an optional MCP
authorization extension for sender-constrained access tokens. When a client
presents a DPoP-bound token, the MCP server (resource server) must verify a
DPoP proof on every request before granting access.
This issue covers MCP server conformance only. It validates that a server
acting as an OAuth 2.1 resource server correctly applies the RFC 9449 §4.3 proof
checking steps, enforces the ±5-minute iat acceptance window, returns correct
401 / WWW-Authenticate: DPoP challenges, and continues to enforce the baseline
token audience requirements.
Key properties of the server role:
- The framework drives the server as a DPoP client, presenting valid proofs
for positive checks and deliberately malformed proofs for negative checks. - The proposal adopts DPoP as defined in RFC 9449 — no MCP-specific extensions
to proof validation are expected. - A conformant stateless server provides replay protection via the
iatwindow
and standard claim validation;jtitracking and nonces are optional.
Specification References
- SEP-1932 PR: https://github.com/modelcontextprotocol/modelcontextprotocol/pull/1932
- Detailed proposal: https://github.com/modelcontextprotocol/ext-auth/blob/pieterkas-dpop-extension/specification/draft/dpop-extension.mdx
- RFC 9449 — OAuth 2.0 Demonstrating Proof of Possession (DPoP): https://www.rfc-editor.org/rfc/rfc9449.html
- §4.2 DPoP Proof JWT Syntax, §4.3 Checking DPoP Proofs (the core checklist)
- §6 Public Key Confirmation (
cnf/jkt), §7 DPoP-bound access tokens - §7.1 The DPoP Authentication Scheme and
WWW-Authenticatechallenge - §9 Resource Server-Provided Nonce, §11.1 DPoP Proof Replay
- Baseline MCP Authorization specification (resource-server token validation and
audience binding): https://modelcontextprotocol.io/specification/draft/basic/authorization
Scope
In scope — what the MCP/resource server does:
- Requiring the
DPoPAuthorizationscheme and aDPoPproof header on
protected requests. - Applying every RFC 9449 §4.3 proof-checking step.
- Enforcing the ±5-minute
iatacceptance window. - Confirming the access token is bound to the proof key (
cnf/jktagreement). - Returning correct
401responses with aWWW-Authenticate: DPoPchallenge
(including thealgsparameter and the appropriateerrorcode). - Optional server-provided nonce issuance and enforcement.
- Continuing to enforce baseline token audience validation when DPoP is used.
Not in scope (covered elsewhere or by another role):
- Client proof construction and nonce-retry behaviour — covered by the client
conformance issue. - Authorization-server token binding, metadata, and token-endpoint nonce —
covered by the authorization-server conformance issue. - Cryptographic algorithm policy beyond rejecting
none/symmetric algorithms.
Changes Required
Conformance harness (framework acting as a DPoP client)
- The framework, acting as a DPoP client, presents a DPoP-bound access
token (Authorization: DPoP <token>) plus aDPoPproof to the server under
test. - Fixture generation for: a valid key pair, a DPoP-bound access token whose
cnf.jktmatches the proof key and whose audience matches the server under
test, and a matched valid proof. - A library of crafted invalid proofs, one per §4.3 failure mode, each
designed to trigger a specific rejection so the server's response is
predetermined.
Test authorization server (createAuthServer)
- Mint DPoP-bound access tokens (correct audience,
cnf.jkt) for the server under
test to validate. Only needed to the extent the server requires a trusted,
audience-correct token to reach the proof-validation path.
Helpers (helpers/)
- DPoP proof builder with per-field overrides (so each negative fixture can
perturb exactly one claim/header: wronghtu, wronghtm, stale/futureiat,
missingjti,typ != dpop+jwt,alg=none/symmetric, private key injwk,
bad signature, wrong/absentath, duplicateDPoPheader, mismatched
cnf/jkt). - JWK SHA-256 thumbprint and
athhelpers.
Scenario (src/scenarios/server/)
- A single scenario file implementing all checks below, registered in the server
scenario list.
Acceptance test suite
- Helper unit tests (proof builder field overrides, thumbprint,
ath), and
scenario acceptance tests asserting each check passes for a conformant server
and fails for a deliberately non-conformant one.
Components that do not change
- The MCP protocol/JSON-RPC interaction is unchanged; only the
Authorization
scheme and the addedDPoPproof verification differ.
Checks to Cover
Positive (valid proof accepted)
- A request with a valid DPoP-bound token and matching proof is accepted and
the MCP operation succeeds. - Server accepts a proof whose
iatis within the ±5-minute window.
Negative (RFC 9449 §4.3 — each rejected with 401 + WWW-Authenticate: DPoP error="invalid_dpop_proof" unless noted)
- More than one
DPoPheader field present. -
DPoPheader is not a single, well-formed JWT. - A required claim is missing (
jti,htm,htu,iat). -
typJOSE header is notdpop+jwt. -
algisnoneor a symmetric algorithm (or otherwise unacceptable). - Signature does not verify against the embedded
jwk. -
jwkJOSE header contains a private key. -
htmdoes not match the request method. -
htudoes not match the request target URI (ignoring query/fragment). -
iatis outside the acceptable window (stale and far-future both rejected). -
athis missing or does not equal the hash of the presented access token. - The access token's bound key (
cnf.jkt) does not match the proof's public
key → rejected witherror="invalid_token". - A DPoP-bound token presented with the
Bearerscheme is rejected. - Baseline: a token whose audience is not this server is rejected (
401),
even with an otherwise valid proof.
Optional nonce behaviour (only if the server advertises/requires nonces)
- Server issues
401 ... error="use_dpop_nonce"with aDPoP-Nonceheader
when it requires a nonce and none is present. - Server accepts the subsequent request carrying the matching
nonceclaim. - Server rejects a proof whose
noncedoes not match a recently supplied
value.
Challenge format
-
401responses carryWWW-Authenticate: DPoPand SHOULD include thealgs
parameter listing acceptable JWS algorithms.
Acceptance Criteria
- A single scenario file in
src/scenarios/server/implements all checks
above (one scenario, many checks). - Each §4.3 check has both a passing case (valid proof accepted) and a
deliberate failing case (crafted invalid proof rejected with the correct
status and error code) proven by the automated acceptance test suite. - Helper unit tests cover the proof builder's per-field overrides and the
thumbprint/athhelpers. - The acceptance test suite runs as part of
npm test. - Scenario runs through the standard CLI runner; no parallel entry point is
introduced. - Validated against at least one real SDK server implementation before the PR
is submitted; SDK baseline YAMLs updated where existing SDKs do not yet
support DPoP.
Out of Scope
- Required
jtistate-tracking / global replay store — optional per RFC 9449
§11.1. A stateless server relying on theiatwindow and claim validation is
conformant;jti-tracking is tested only as optional behaviour if advertised. - Server-side nonce cryptographic construction (e.g. AEAD-encrypted
timestamps) — an implementation choice; only the observable nonce challenge/
acceptance protocol is tested. - Client proof construction and authorization-server behaviour — covered by the
separate client and authorization-server conformance issues.
Notes
Prepared with the aid of Claude (Opus 4.8)
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Direzione di ricerca
Inizia con la registrazione degli scenari esistente in src/scenarios/server/, l’area helpers/ e createAuthServer; leggi RFC 9449 §4.3 ed esegui npm test per comprendere il conformance harness. Aggiungi uno scenario server registrato, fixture di proof e token e unit test degli helper che coprano i controlli positivi e negativi elencati. Il lavoro è completato quando il runner CLI standard e npm test passano, con le asserzioni richieste per status, challenge ed errore.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- typescript
- Ambito
- api, authentication, security, testing-qa
- Tipo di issue
- Funzionalità
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Stato di attività
- Tranquilla
- Chiarezza
- Abbastanza chiara
- Idoneità per principianti
- 45/100