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.