Skip to content

proposal: client DPoP support (SEP-1932 baseline, no nonce) #1139

Description

@gbshankar

Background

SEP-1932 / RFC 9449 DPoP conformance scenarios landed in the conformance suite. #1138 teaches the harness everything-client to pass auth/dpop via a hand-rolled path. That is not SDK support — apps using AuthorizationCodeHandler + StreamableClientTransport still cannot obtain or present DPoP-bound tokens.

Today setMCPHeaders hardcodes Authorization: Bearer (mcp/streamable.go), and OAuthHandler only exposes TokenSource + Authorize — enough for Bearer, not for a fresh per-request DPoP proof (htm/htu/ath/jti).

Proposal (baseline only; no nonce)

Ship one SDK PR that:

  1. Helpers (e.g. under oauthex) — ES256 keypair, proof builder, ath, HTU normalize, RFC-vector tests. No nonce in the public API yet.
  2. Transport — use token.Type() (default Bearer); attach per-request proofs without breaking existing OAuthHandler implementors.
  3. AuthorizationCodeHandler — explicit opt-in DPoP config; proof on token exchange + refresh; implement the per-request hook.
  4. Conformance — rewrite everything-client auth/dpop to use the SDK path (acceptance test). Keep auth/dpop-nonce in baseline.yml.

Hook shape (prefer non-breaking)

Do not add a method to the OAuthHandler interface (breaking for external implementors). Prefer one of:

  • A (preferred): optional interface type-asserted in setMCPHeaders, e.g. handlers that also implement PrepareRequest(ctx, *http.Request) error get called after Authorization is set.
  • B: StreamableClientTransport.PrepareRequest func field set by the app / handler wiring.

AuthorizationCodeHandler with DPoP enabled would implement A (or set B).

Explicit opt-in only — no auto-enable from dpop_bound_access_tokens_required in v1.

Out of scope (follow later, same pattern)

  • auth/dpop-nonce (AS/RS use_dpop_nonce retry)
  • Server RequireDPoP middleware
  • Legacy SSE client OAuth/DPoP

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Nice to haves, rare edge cases

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions