Skip to content
Ashish.
All posts
Diagram illustrating the difference between standard bearer tokens and sender-constrained tokens with cryptographic key binding.

Understanding Token Binding and Sender-Constrained Tokens

An examination of token binding and sender-constrained tokens including proof of possession, DPoP, and mTLS for enhanced token protection.

By Ashish Srivastava

Standard OAuth 2.0 access tokens function as stateless bearer credentials, creating a fundamental vulnerability where possession equals authority. If an attacker intercepts such a token, they can use it exactly like a found $20 bill, granting them full access to the resource. Sender-constrained tokens solve this by cryptographically linking the token to a specific client instance at issuance. This mechanism ensures that even if the token string is stolen, it remains useless without the corresponding private key bound to the original request context.

The Bearer Vulnerability

The core weakness of standard OAuth 2.0 lies in the "bearer" designation. In this model, the Resource Server (RS) trusts anyone presenting a valid token string. It performs no check on who is holding the token, only that the token is unexpired and signed by the Authorization Server (AS).

Consider a scenario where an attacker, Eve, intercepts a token issued to Alice. In a standard bearer flow, Eve copies the token string into her own request headers. The RS sees the valid signature and grants Alice's data to Eve. The token functions exactly like a $20 bill found on the street; possession equals authority.

To fix this, we introduce sender-constrained tokens. These mechanisms bind the token to a specific client instance, usually by requiring the client to prove possession of a cryptographic key during the token request and subsequent API calls. If Eve steals the token string but lacks the private key bound to it, the RS rejects the request.

Proof of Possession: The Core Mechanism

The general mechanism for sender constraint is Proof of Possession (PoP). PoP requires the client to generate a key pair (public/private) and prove it holds the private key when using the token.

In a PoP flow, the AS issues the token but includes a reference to the client's public key or a thumbprint of that key within the token metadata. When the client makes an API call, it must sign a portion of the request (typically the HTTP method, URI, and token) using its private key. The RS verifies the signature.

This creates a dependency:

  1. Key Generation: Client generates Ephemeral_Key.
  2. Token Request: Client sends Ephemeral_Key (or public part) to AS.
  3. Token Issuance: AS binds Ephemeral_Key to the token (e.g., via a jkt claim).
  4. API Call: Client signs the request with Ephemeral_Key.
  5. Validation: RS checks if the signature matches the key bound to the token.

If Eve steals the token, she cannot sign the request because she does not possess Ephemeral_Key. The mechanism shifts security from "who has the token" to "who has the token AND the key."

DPoP: A Standardized PoP Implementation

DPoP (RFC 8617) is the modern, standardized implementation of PoP specifically designed for OAuth 2.0. It avoids the complexity of custom token extensions and integrates directly into the HTTP protocol.

Consider a client named mobile-app interacting with a bank-api.

Key Generation and Token Request

The mobile-app generates an RSA or ECDSA key pair. It keeps the private key secure in the device keystore. The client creates a DPoP JWT (JSON Web Token) called the dpop header. This JWT contains:

  • jti: A unique ID for the DPoP key.
  • ath: An assertion about the authorization code (if exchanging a code).
  • typ: Set to dpop+jwt.
  • jwk: The client's public key.
  • iss/sub: The client ID.
  • aud: The token endpoint URL.
  • exp: Expiration time.

The client signs this JWT with its private key and sends it in the DPoP header alongside the standard OAuth request.

POST /token HTTP/1.1
Host: auth.bank-api.com
Authorization: Basic ...
Content-Type: application/x-www-form-urlencoded
 
grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&scope=read+write
DPoP: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjEyMzQ1Njc4OTAiLCJqdGkiOiJhYmNkZWYxMjM0NTY3ODkwIn0...

Token Issuance and Binding

The AS validates the DPoP JWT. Crucially, it calculates the thumbprint of the public key provided in the DPoP header. The AS then includes this thumbprint in the jkt (JWT Key Thumbprint) claim of the issued access token.

{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "read write",
  "jkt": "7b9b1e4c8f2a3d5e6g7h8i9j0k1l2m3n4o5p6q7r" 
}

The jkt value is the JWK thumbprint (SHA-256) of the client's public key. This binds the token to that specific key.

The API Call

When mobile-app calls the bank API, it must present a new DPoP JWT (for the current request) and the access token. The ath claim in the new DPoP JWT must be a base64url-encoded SHA-256 hash of the access token string itself, proving the client holds the specific access token being used.

GET /accounts HTTP/1.1
Host: api.bank-api.com
Authorization: Bearer <access_token>
DPoP: <new_dpop_jwt>

The bank-api validates the signature using the public key provided directly in the DPoP header and verifies that this key's thumbprint matches the jkt claim in the access token. If the signatures don't match the bound key, the API returns 401 Unauthorized.

This prevents token theft. Even if Eve has the access_token, she cannot generate a valid DPoP header without the private key. Furthermore, DPoP includes a replay protection mechanism via the jti (ID) and iat (issued at) timestamp. Specifically, jti prevents replay of the DPoP header itself, while the primary protection against token theft is the cryptographic binding via the ath claim.

mTLS: Binding at the Transport Layer

While DPoP operates at the application layer (HTTP), mTLS (Mutual TLS) binds the token at the transport layer. This is often preferred in high-security environments like banking or enterprise APIs.

In mTLS, the client presents a certificate during the TLS handshake. The server validates this certificate. If the certificate is valid, the connection is established.

The Mechanism

  1. Client Certificate: The client possesses a certificate issued by a trusted CA, containing a public key.
  2. Token Request: The client connects via TLS, presenting the certificate. The AS validates the certificate.
  3. Token Binding: The AS extracts the public key from the client certificate and embeds its thumbprint into the access token's jkt claim (or a specific cnf claim).
  4. API Call: The client makes the API request over a new TLS connection, presenting the same client certificate.

The Resource Server (RS) does not just check the token signature; it checks the TLS handshake. It verifies that the certificate presented in the TLS layer matches the jkt embedded in the access token.

# Example curl command with mTLS
curl --cert client-cert.pem --key client-key.pem \
     -H "Authorization: Bearer <access_token>" \
     https://api.bank-api.com/accounts

If an attacker steals the token but tries to use it from a different machine (which has a different TLS certificate), the RS sees a mismatch. The token says "User A with Key X," but the TLS connection says "User B with Key Y." The RS rejects the request.

This approach offloads the cryptographic verification of the client's identity to the TLS stack, which is highly optimized. However, it requires managing a Public Key Infrastructure (PKI) for client certificates, which adds operational overhead.

Operational Tradeoffs

Choosing between DPoP and mTLS depends on the client environment and operational maturity.

DPoP is application-layer agnostic. It works with any HTTP client, including mobile apps, single-page applications, and IoT devices that might not support full TLS client authentication easily. It is the recommended standard for modern OAuth deployments where PKI management is difficult. The tradeoff is that the application must implement the DPoP logic (generating keys, signing headers, validating responses), adding complexity to the client code.

mTLS moves the burden to the infrastructure. The TLS termination proxy or the API gateway handles the heavy lifting. This is excellent for server-to-server communication (e.g., microservices) where certificates are easy to manage via internal PKI. However, it is often impractical for consumer-facing mobile apps or browsers, where distributing and rotating client certificates is cumbersome.

Opinion: For most public-facing consumer applications, DPoP is the superior choice. The overhead of managing client certificates for millions of mobile devices is prohibitive, whereas generating ephemeral keys in a mobile keystore is trivial. For internal microservice architectures, mTLS remains the gold standard due to its simplicity in configuration and robustness at the network layer.

Security Note: Neither mechanism replaces the need for short-lived tokens and refresh token rotation. They merely ensure that if a token is stolen, it is useless without the corresponding bound key.

Common Pitfalls

Implementing sender-constrained tokens introduces specific operational risks that must be managed:

  1. Key Storage Security: The security of the entire flow relies on the private key remaining secret. If an attacker gains access to the client's keystore or server-side key store, they can generate valid DPoP headers or present valid mTLS certificates, rendering the binding ineffective.
  2. Clock Skew and Token Freshness: DPoP relies heavily on timestamps (iat in the DPoP header, exp in the token). Significant clock skew between the client and server can cause valid requests to be rejected as expired or invalid, leading to availability issues if NTP synchronization is poor.
  3. JKT Mismatch Scenarios: If a client rotates keys or if the AS issues a token with a jkt that doesn't align with the current client certificate (in mTLS) or DPoP key, legitimate requests will fail. Proper key lifecycle management and clear error handling for invalid_token vs invalid_client are critical to avoid user friction.

Practical Takeaways

  • DPoP for Flexibility: Choose DPoP for client applications (mobile, SPA) where managing a full PKI is too heavy, accepting the need for application-level cryptographic implementation.
  • mTLS for Infrastructure: Prefer mTLS for server-to-server communication where the infrastructure can handle certificate provisioning and rotation efficiently.
  • Defense in Depth: Never rely solely on binding; always combine these mechanisms with short token lifetimes and strict refresh token policies to minimize the window of opportunity for attackers.

FAQ

What happens if the private key is lost? If the private key is lost, the client cannot generate valid DPoP headers or present the correct certificate. The client must revoke the associated credential, obtain a new key pair, and re-register with the Authorization Server to receive new tokens bound to the new key.

Does DPoP work with mobile apps? Yes, DPoP is well-suited for mobile apps. It leverages the secure storage capabilities of modern mobile OS keychains (like Android Keystore or iOS Keychain) to protect the ephemeral private keys, making it more practical than mTLS for this environment.

Can I use DPoP with existing OAuth flows? Yes, DPoP is designed to be backward compatible with existing flows like Authorization Code and Client Credentials. It simply adds the DPoP header and the jkt claim to the standard exchange without breaking existing token endpoints.

Conclusion

Sender-constrained tokens transform the security model of OAuth from "trust the bearer" to "trust the bound key." Whether implemented via the application-layer DPoP header or the transport-layer mTLS handshake, the mechanism ensures that the identity of the token holder is cryptographically verified against the token itself. This prevents the most common attack vector in OAuth: token interception and replay. As the ecosystem matures, the adoption of these mechanisms becomes critical for protecting sensitive user data against increasingly sophisticated credential theft.

Related posts