Skip to content

auth/mcp: client DPoP support (SEP-1932 baseline, no nonce) - #1140

Open
gbshankar wants to merge 3 commits into
modelcontextprotocol:mainfrom
gbshankar:dpop-2-sdk-client
Open

auth/mcp: client DPoP support (SEP-1932 baseline, no nonce)#1140
gbshankar wants to merge 3 commits into
modelcontextprotocol:mainfrom
gbshankar:dpop-2-sdk-client

Conversation

@gbshankar

Copy link
Copy Markdown

Summary

Stacked on / blocked by #1138 (harness). Design: #1139.

Adds real SDK baseline DPoP (RFC 9449 / SEP-1932) so apps can opt in via AuthorizationCodeHandlerConfig.DPoP:

  • oauthex: ES256 keypair, proof builder, ath, HTU helpers, RFC-vector tests (no nonce in the public API)
  • mcp: Authorization uses token.Type(); optional auth.RequestPreparer type-assert for per-request DPoP proofs (non-breaking for existing OAuthHandler implementors)
  • auth: opt-in DPoP on token exchange/refresh via DPoPRoundTripper; AuthorizationCodeHandler implements RequestPreparer
  • conformance: auth/dpop everything-client rewritten to use the SDK path

Out of scope: auth/dpop-nonce, server RequireDPoP, metadata auto-enable.

Test plan

  • go test ./oauthex/ ./auth/ ./mcp/
  • conformance auth/dpop → 12/12 via SDK path
  • CI client suite with baseline.yml (auth/dpop-nonce still expected-fail)
  • Rebase onto main after conformance: pass auth/dpop (SEP-1932 baseline) #1138 merges (this PR currently includes that commit)

Made with Cursor

gbshankar and others added 3 commits August 3, 2026 18:03
Wire the everything-client to the DPoP baseline scenario with a
hand-rolled OAuth + per-request proof path so CI stops expecting
auth/dpop to fail. Nonce posture (auth/dpop-nonce) remains deferred;
this is harness coverage, not SDK DPoP support.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add opt-in DPoP for AuthorizationCodeHandler and StreamableClientTransport:
proof helpers in oauthex, token.Type() for the Authorization scheme, and
an optional RequestPreparer hook for per-request proofs. Migrate the
conformance auth/dpop client onto this path. Nonce handling remains out
of scope (see modelcontextprotocol#1139).

Co-authored-by: Cursor <cursoragent@cursor.com>
Avoid scheme/proof split after refresh when AS token_type is empty or
Bearer: the preparer sets Authorization and DPoP together from client
DPoP mode instead of trusting token.Type().

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant