OAuth DPoP | FusionAuth Docs/Docs
Light<br>Dark<br>System
Log In
Get a demo<br>Open main menu
Light<br>Dark<br>System
Log In
Get a demo
🤖 For AI agents: The complete documentation index is available at /docs/llms.txt. A markdown version of this page is available at /docs/lifecycle/authenticate-users/oauth/dpop.md.<br>OAuth DPoP
EditMDCopy
This feature is only available in the Enterprise plan. To learn more, see our pricing page.
Demonstrating Proof-of-Possession (DPoP) is an application-level mechanism for sender-constraining OAuth 2.0 Access and Refresh Tokens. It ensures that a token can only be used by the client that requested it, by binding the token to a cryptographic key pair held by that client.
Unlike standard bearer tokens, which can be used by any party in possession of the token, DPoP-bound tokens require the client to prove possession of a private key for every request. This provides strong defense-in-depth against token theft and replay attacks.
DPoP is defined in RFC 9449.
When To Use DPoP#
Consider using DPoP in the following scenarios:
Securing APIs : APIs that require strict assurance that the sender of the token is the same entity to which the token was issued.
Multi Domain : DPoP is compatible with CORS, and allows you to securely use tokens between multiple domains.
FAPI 2.0 : This specification defines DPoP as one of the methods for sender-constrained access tokens.
Alternative to mTLS : In environments where Mutual TLS (mTLS) is difficult to implement or not supported by the infrastructure, DPoP provides similar sender-constraining benefits at the application layer.
When you use DPoP, the APIs receiving the access token will need to take additional steps to validate that the access token was sent by the correct client. FusionAuth doesn't yet have SDK support for this, but it's coming. For now, you can implement the checks outlined in the RFC:
For such an access token, a resource server MUST check that a DPoP proof was also received in the DPoP header field of the HTTP request, check the DPoP proof according to the rules in Section 4.3, and check that the public key of the DPoP proof matches the public key to which the access token is bound per Section 6.
note<br>DPoP is not a substitute for TLS; always use DPoP with HTTPS to ensure request confidentiality.
FusionAuth Support And Scope#
FusionAuth acts as the Authorization Server (AS) in the DPoP flow. When a client includes a DPoP proof in a token request, FusionAuth:
Extracts the DPoP proof, public key, and signature from the DPoP request header.
Verifies the signature using the provided public key and validates the proof according to RFC 9449 § 5.
Calculates the JWK SHA-256 thumbprint (jkt) of the public key provided in the proof.
Binds the issued access token (and refresh token) to this thumbprint by adding a cnf claim.
Returns a token_type of DPoP in the token response.
Token Binding Semantics#
When DPoP is used, the issued access token contains a Confirmation (cnf) claim as defined in RFC 9449 § 6.1.
"cnf": {<br>"jkt": "0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I"<br>This thumbprint is the immutable anchor that your Resource Server (RS) will use to verify that the client presenting the Token is the legitimate owner.
caution<br>FusionAuth handles the binding of Tokens during issuance. However, the validation of DPoP proofs when accessing your protected resources occurs in your own APIs (the Resource Server).
The DPoP Flow#
The following diagram illustrates the DPoP flow using the Authorization Code grant with PKCE.
sequenceDiagram<br>participant User as Client/Browser<br>participant App<br>participant FusionAuth as FusionAuth (AS)<br>participant API as API (RS)
Note left of User: User Logs In<br>rect rgb(230, 245, 255, .1)<br>Note over User: Generate cryptographic Key Pair<br>User ->> App : View Initial PageClick Login<br>App ->> User : Redirect User To Authorization Server With Scopes<br>User ->> FusionAuth : Request Login Page<br>FusionAuth ->> User : Return Login Page<br>User ->> FusionAuth : Provides Credentials<br>FusionAuth ->> FusionAuth : Validate Credentials<br>FusionAuth ->> User : Redirect With Authorization Code<br>end
Note left of User: Start DPoP Token Issuance
rect rgb(230, 245, 255, .1)<br>Note over User: Construct & Sign DPoP Proof 1<br>User ->> App : Request Redirect URI<br>App ->> FusionAuth : Request TokensDPoP Header (Proof 1)<br>rect rgb(230, 245, 255, .1)<br>Note over FusionAuth: Extract Proof 1, Public Key & Signature<br>FusionAuth->>FusionAuth: Verify Proof 1 Signature & Claims<br>FusionAuth->>FusionAuth: Bind Token to Public Key Thumbprint (jkt)<br>end<br>FusionAuth ->> App : Return sender-constrainedAccess & Refresh Tokens<br>App ->> User : Store Tokens(e.g., in memory or secure storage)<br>end
Note left of User: Access Protected Resource
rect rgb(230, 245, 255, .1)<br>Note over User: Construct & Sign DPoP Proof 2
User->>API: API Request (Access Token)DPoP Header (Proof 2)<br>rect rgb(230, 245, 255, .1)<br>Note over API: Extract Proof 2, Public Key & Signature<br>API->>API:...