DPoP · RFC 9449

Sender-constrained tokens, proof construction, key binding.

DPoP (Demonstrating Proof-of-Possession, RFC 9449) binds an access token to a key the client holds. A stolen token is inert without the matching private key — the single most important property for agent tokens that travel between services.

The binding claim

When a client requests a token with a DPoP proof, the issued token carries a confirmation claim (cnf.jkt) — the SHA-256 thumbprint of the client’s public key:

{
  "sub": "agent:research-bot",
  "scope": "mcp:tools.invoke",
  "cnf": { "jkt": "sha256(client_pubkey)" },
  "exp": 1750000000
}

Prove possession on every call

Each request includes a freshly-signed DPoP proof JWT over the method, URL, and a nonce:

POST https://tools.acme.com/mcp
  Authorization: DPoP <access_token>
  DPoP: <proof-jwt>     # signed by the client's private key

The resource server checks that the proof’s key thumbprint matches cnf.jkt. No key, no call.

Defense in depth

DPoP pairs with refresh-token reuse detection (RFC 9700): if a refresh token is replayed, the whole token family is revoked. Sender-binding stops theft; reuse detection cleans up after it.