DPoP explained: binding OAuth tokens to a client key
Duende's Halloween-themed walkthrough explains DPoP, the RFC 9449 extension that binds access tokens to a client's key pair. Binding stops a stolen bearer token from being replayed against an API. The post follows the token request, the cnf.jkt claim and the proof check on the API side, and it maps each step to Duende's .NET libraries.
Key points
- Access tokens carry a cnf.jkt claim holding the thumbprint of the client's public key.
- Each API request sends a fresh DPoP proof JWT signed with the private key, with htm, htu, iat and ath claims.
- The API checks ath, cnf.jkt and iat, and rejects proofs whose jti was already seen.
- Duende.AccessTokenManagement handles client-side key generation and proof signing.
- Duende.AspNetCore.Authentication.JwtBearer.Extensions validates DPoP proofs in .NET APIs without custom middleware.
Duende Software has published a playful walkthrough of DPoP, the OAuth extension from RFC 9449 that binds access tokens to a client's key pair. A plain bearer token works for anyone who holds it, so a token leaked from a proxy log can be replayed. With DPoP, the client signs a proof with its private key, and the authorization server records the key's thumbprint in the token's cnf.jkt claim.
On each API call, the client sends the token with the DPoP scheme plus a fresh proof. The API checks the htm and htu values, the iat timestamp, the ath hash of the token, and that the proof key matches cnf.jkt, while tracking jti values to catch replays. A thief without the private key fails. The article closes by pointing to Duende's libraries for the client, IdentityServer and the ASP.NET Core JwtBearer extensions.
Real-world use
- An ASP.NET Core API that serves sensitive data to SPAs or mobile clients and must resist stolen tokens.
- A .NET worker or client app calling a protected API that needs proof-of-possession tokens from IdentityServer.
- Gateway or reverse-proxy setups where access tokens may land in logs.
Why it matters
If your APIs accept bearer tokens, a leaked token is enough for an attacker; DPoP makes it useless without the client's private key, and .NET libraries can add the checks without hand-written crypto.
Related stories
- A secure enterprise chat with React, .NET 10 and Microsoft FoundryDEV Community: #dotnet1 d ago
- ASP.NET Core Authentication & Authorization Explained: What to Use, When, and How to Ship It SafelyDEV Community: #aspnetcore1 d ago
- Mastering Rate Limiting and Resource Governance for MCP Servers at ScaleDEV Community: #aspnetcore1 d ago