Skip to content
Version v3.0.0

DPoP Token Binding

ProAuth supports OAuth 2.0 Demonstrating Proof of Possession (DPoP) according to RFC 9449. DPoP binds issued access tokens to a client-held asymmetric key. A stolen token cannot be used unless the caller can also sign a valid DPoP proof JWT with the same key.

DPoP-bound access tokens satisfy the sender-constrained-token requirement for FAPI 2.0 Security Profile.

Configure DPoP per client application with the v2 Management API resource api/management/v2/ClientAppAuthenticationConfiguration.

FieldDescription
dpopBoundAccessTokensWhen true, token requests for the client must include a valid DPoP proof and issued access tokens use token_type DPoP.
requireDpopNonceWhen true, ProAuth requires a rotating server-managed nonce and returns it in the DPoP-Nonce response header.

The tenant option DpopProofTimeWindow controls the accepted iat window for token endpoint proofs. The default is 00:05:00.

Supported DPoP proof signing algorithms are advertised in discovery as dpop_signing_alg_values_supported: RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384, and ES512.

Token Requests

Clients send a DPoP HTTP header at the token endpoint. The header value is a signed JWT with:

  • typ header dpop+jwt
  • public jwk header
  • asymmetric alg
  • htm claim matching the HTTP method
  • htu claim matching the token endpoint URI without query or fragment
  • numeric iat
  • unique jti
  • optional nonce when ProAuth requires nonces

Authorization-code token request:

http
POST /connect/token HTTP/1.1
Host: idp.example.com
Content-Type: application/x-www-form-urlencoded
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7...}

grant_type=authorization_code&
client_id=...&
code=...&
redirect_uri=https%3A%2F%2Fclient.example.com%2Fcallback

Client-credentials token request:

http
POST /connect/token HTTP/1.1
Host: idp.example.com
Content-Type: application/x-www-form-urlencoded
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IlBTMjU2IiwiandrIjp7...}

grant_type=client_credentials&
client_id=...&
client_secret=...&
scope=api

Refresh-token request:

http
POST /connect/token HTTP/1.1
Host: idp.example.com
Content-Type: application/x-www-form-urlencoded
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7...}

grant_type=refresh_token&
client_id=...&
refresh_token=...

Successful DPoP-bound responses use token_type DPoP and the access token contains:

json
{
  "cnf": {
    "jkt": "base64url-sha256-jwk-thumbprint"
  }
}

For public clients, refresh tokens issued during a DPoP-bound flow are also bound to the same cnf.jkt. Refresh grants must prove possession of the same key.

Authorization Requests

For authorization-code flows, clients can bind the authorization code to a DPoP key with dpop_jkt. The value is the base64url-encoded SHA-256 JWK thumbprint of the client's public key.

http
GET /connect/authorize?response_type=code&client_id=...&redirect_uri=...&scope=openid%20api&dpop_jkt=... HTTP/1.1
Host: idp.example.com

The same parameter is supported in pushed authorization requests (PAR). When dpopBoundAccessTokens is enabled for the client, authorization-code requests must include dpop_jkt, and the token endpoint proof must use the same key.

Nonce Flow

When requireDpopNonce is enabled, a token request without a valid nonce is rejected with use_dpop_nonce and one DPoP-Nonce response header. The client retries with the nonce claim in the next DPoP proof. On success, ProAuth rotates the nonce and returns the next value in DPoP-Nonce.

Resource Server Verification

Resource requests for DPoP-bound access tokens use:

http
Authorization: DPoP <access-token>
DPoP: <proof-jwt>

The resource server must validate the proof signature and check htm, htu, iat, unique jti, optional nonce, and ath. The ath claim is the base64url SHA-256 hash of the access token. The proof JWK thumbprint must match the access token cnf.jkt.

ProAuth validates these rules for its own protected OIDC resource endpoints, including UserInfo.

Interactions

DPoP and mTLS certificate binding can both appear in the access token cnf claim. mTLS uses x5t#S256; DPoP uses jkt.

Reference tokens and encrypted access tokens remain supported. ProAuth stores and introspects the protected token metadata and exposes cnf.jkt in introspection responses for active DPoP-bound access tokens.