Overview
SEP-1932
adopts OAuth 2.0 Demonstrating Proof of Possession
(RFC 9449) as an optional MCP
authorization extension. For sender-constrained tokens to work, the OAuth
authorization server must accept a DPoP proof at the token endpoint, bind the
issued access token to the client's public key, and advertise its DPoP support.
This issue covers authorization server conformance only. It validates that an
authorization server advertises dpop_signing_alg_values_supported, validates the
token-endpoint DPoP proof, issues a DPoP-bound token (token_type=DPoP with a
cnf.jkt confirmation), honours the optional nonce mechanism, and enforces
dpop_bound_access_tokens client registration.
Key properties of the authorization-server role:
- The framework drives the authorization server as a DPoP client at the token
endpoint, presenting valid and invalid proofs.
- DPoP is adopted as defined in RFC 9449 — no MCP-specific extensions to the
token-endpoint exchange.
- This is distinct from client and resource-server conformance even though all
three involve OAuth; the authorization server is tested in isolation.
Specification References
Scope
In scope — what the authorization server does:
- Advertising
dpop_signing_alg_values_supported (asymmetric algorithms only; no
none) in its authorization server metadata.
- Validating the DPoP proof presented on the token request (§4.3 as applicable to
the token endpoint: typ, alg, signature, jwk without private key,
htm=POST, htu=token endpoint, jti, iat window, nonce when required).
- Issuing a DPoP-bound access token:
token_type of DPoP and a cnf.jkt
confirmation equal to the base64url JWK SHA-256 thumbprint of the proof key.
- Token-endpoint nonce mechanism:
400 use_dpop_nonce + DPoP-Nonce, then
accepting the retried request.
- Honouring
dpop_bound_access_tokens=true client registration by rejecting token
requests that lack a DPoP proof.
- Binding refresh tokens to the same key for public clients.
Not in scope (covered elsewhere or by another role):
- Resource-server proof validation and
ath/cnf agreement at resource access —
covered by the server conformance issue.
- Client proof construction and nonce-retry behaviour — covered by the client
conformance issue.
Changes Required
Conformance harness (framework acting as a DPoP client at the token endpoint)
- The framework, acting as a DPoP client, performs a token request with a
DPoP proof against the authorization server under test, then inspects the
metadata, the token response (token_type), and the issued token's cnf.jkt.
- Fixture generation for a valid proof keyed to a generated key pair, plus crafted
invalid proofs (one per token-endpoint failure mode).
Helpers (helpers/)
- DPoP proof builder with per-field overrides (reused from / shared with the
server scenario helpers where practical).
- JWK SHA-256 thumbprint helper to assert
cnf.jkt equals the proof key
thumbprint.
- Metadata fetch/parse helper for
dpop_signing_alg_values_supported.
Scenario (src/scenarios/authorization-server/)
- A single scenario file implementing all checks below, registered in the
authorization-server scenario list.
Acceptance test suite
- Helper unit tests and scenario acceptance tests asserting each check passes for
a conformant authorization server and fails for a deliberately non-conformant
one.
Components that do not change
- The resource-server (MCP server) path — the grant/token type does not change how
a resource server validates an access token's audience.
- OIDC discovery infrastructure beyond surfacing the new metadata field.
Checks to Cover
Positive
Negative (token-endpoint proof failures → 400 invalid_dpop_proof unless noted)
Nonce behaviour (if the authorization server requires nonces)
Client registration enforcement
Acceptance Criteria
Out of Scope
- Nonce cryptographic construction (e.g. AEAD-encrypted timestamps) — an
implementation choice; only the observable use_dpop_nonce protocol is tested.
- Full OAuth 2.1 / token-endpoint conformance unrelated to DPoP (PKCE, resource
indicators, etc.) — covered by existing baseline authorization conformance.
- Resource-server and client behaviour — covered by the separate server and
client conformance issues.
Notes
Prepared with the help of Claude (Opus 4.8)
Overview
SEP-1932
adopts OAuth 2.0 Demonstrating Proof of Possession
(RFC 9449) as an optional MCP
authorization extension. For sender-constrained tokens to work, the OAuth
authorization server must accept a DPoP proof at the token endpoint, bind the
issued access token to the client's public key, and advertise its DPoP support.
This issue covers authorization server conformance only. It validates that an
authorization server advertises
dpop_signing_alg_values_supported, validates thetoken-endpoint DPoP proof, issues a DPoP-bound token (
token_type=DPoPwith acnf.jktconfirmation), honours the optional nonce mechanism, and enforcesdpop_bound_access_tokensclient registration.Key properties of the authorization-server role:
endpoint, presenting valid and invalid proofs.
token-endpoint exchange.
three involve OAuth; the authorization server is tested in isolation.
Specification References
cnf/jkt)dpop_signing_alg_values_supported, §5.2dpop_bound_access_tokensScope
In scope — what the authorization server does:
dpop_signing_alg_values_supported(asymmetric algorithms only; nonone) in its authorization server metadata.the token endpoint:
typ,alg, signature,jwkwithout private key,htm=POST,htu=token endpoint,jti,iatwindow,noncewhen required).token_typeofDPoPand acnf.jktconfirmation equal to the base64url JWK SHA-256 thumbprint of the proof key.
400 use_dpop_nonce+DPoP-Nonce, thenaccepting the retried request.
dpop_bound_access_tokens=trueclient registration by rejecting tokenrequests that lack a DPoP proof.
Not in scope (covered elsewhere or by another role):
ath/cnfagreement at resource access —covered by the server conformance issue.
conformance issue.
Changes Required
Conformance harness (framework acting as a DPoP client at the token endpoint)
DPoP proof against the authorization server under test, then inspects the
metadata, the token response (
token_type), and the issued token'scnf.jkt.invalid proofs (one per token-endpoint failure mode).
Helpers (
helpers/)server scenario helpers where practical).
cnf.jktequals the proof keythumbprint.
dpop_signing_alg_values_supported.Scenario (
src/scenarios/authorization-server/)authorization-server scenario list.
Acceptance test suite
a conformant authorization server and fails for a deliberately non-conformant
one.
Components that do not change
a resource server validates an access token's audience.
Checks to Cover
Positive
dpop_signing_alg_values_supportedas a JSON array ofasymmetric JWS
algvalues;noneis not present.typ=dpop+jwt, asymmetricalg,embedded public
jwk,htm=POST,htu=token endpoint,jti,iatinwindow) and issues a token.
token_typetoDPoP.cnf.jktequal to the base64url JWK SHA-256thumbprint of the proof's public key.
Negative (token-endpoint proof failures →
400 invalid_dpop_proofunless noted)jwk.typis notdpop+jwt.algisnoneor a symmetric algorithm.jwkcontains a private key.htm/htudo not match the token endpoint request.iatis outside the acceptable window.jti,htm,htu,iat).Nonce behaviour (if the authorization server requires nonces)
400 use_dpop_nonce+DPoP-Noncewhen a nonce is required andabsent.
nonceclaim.noncedoes not match a recently supplied value.Client registration enforcement
dpop_bound_access_tokens=true, the authorization server rejects atoken request that does not include a DPoP proof.
Acceptance Criteria
src/scenarios/authorization-server/implementsall checks above (one scenario, many checks).
deliberate failing case (crafted invalid proof / missing field) proven by the
automated acceptance test suite — no check is vacuously passing.
npm test.introduced.
before the PR is submitted; SDK/AS baseline YAMLs updated where existing
implementations do not yet support DPoP.
Out of Scope
implementation choice; only the observable
use_dpop_nonceprotocol is tested.indicators, etc.) — covered by existing baseline authorization conformance.
client conformance issues.
Notes
Prepared with the help of Claude (Opus 4.8)