In this article
May 20, 2026
May 20, 2026

Bearer tokens vs sender-constraining tokens: Why possession alone isn't enough

Stolen tokens should be worthless. Here's how to make them so.

Explore with AI
Open in ChatGPT
Open in Claude
Open in Perplexity

For decades, bearer tokens have been the workhorse of web authorization. Hand over the right token, get access. Simple, stateless, widely supported. But that simplicity hides a serious flaw: anyone who gets their hands on a bearer token can use it as freely as the person it was issued to. Sender-constraining tokens fix that problem by binding a token to a specific cryptographic key, so possession of the token alone is never enough.

This article explores how both approaches work, where they differ, and when it makes sense to reach for the stronger guarantee that sender-constraining provides.

What is a bearer token?

A bearer token is exactly what it sounds like: whoever bears (carries) the token is granted access. The authorization server issues a string, typically a JSON Web Token (JWT) or an opaque random value, and the client presents it in the Authorization header on every request.

  
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
  

The resource server validates the token, checks its claims (expiry, scope, audience), and either grants or denies access. At no point does it ask whether the entity presenting the token is the same entity that originally received it.

This is both the strength and the weakness of the model. It is easy to implement, requires no client-side cryptography, and works seamlessly across languages and frameworks. But it also means that a leaked token is fully usable by an attacker until it expires. Network interception, log scraping, browser history exposure, and open redirects are all viable paths to token theft.

What is a sender-constraining token?

A sender-constraining token is bound to a specific cryptographic key at issuance time. The authorization server records a public key (or a thumbprint of it) as part of the token's claims. When the client presents the token to a resource server, it must also prove it holds the corresponding private key, typically by signing part of the request.

The resource server then verifies two things: that the token itself is valid, and that the request was signed by the key embedded in the token. A stolen token is useless without the private key, which never leaves the client.

Two main standards implement this pattern today.

DPoP (Demonstrating Proof of Possession)

Defined in RFC 9449, DPoP is the most widely adopted sender-constraining mechanism for OAuth 2.0. The client generates an asymmetric key pair and, for each request, creates a short-lived signed JWT called a DPoP proof. This proof includes the HTTP method, the request URI, a timestamp, and a unique nonce. The authorization server embeds a thumbprint of the client's public key inside the access token itself.

  
Authorization: DPoP eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
DPoP: eyJhbGciOiJFUzI1NiIsInR5cCI6ImRwb3Arand...
  

The resource server validates both the access token and the DPoP proof, confirming they share the same key thumbprint. Because each proof is bound to a specific URI and timestamp, replaying it elsewhere is not possible.

mTLS-constrained tokens

Mutual TLS (mTLS) takes a different approach. Rather than adding an application-layer proof, it uses the TLS layer itself. The client presents a client certificate during the TLS handshake, and the authorization server encodes a thumbprint of that certificate in the token (defined in RFC 8705). Every resource server request requires the same certificate to be present at the TLS layer.

mTLS is common in high-assurance environments, particularly financial services and APIs governed by open banking regulations like FAPI (Financial-grade API). It provides very strong binding guarantees but requires PKI infrastructure and is harder to adopt in browser-based clients.

How the two models compare

The two approaches are not direct competitors so much as they are different points on a security-versus-simplicity spectrum. Bearer tokens win on ease of adoption: no key management, no extra headers, no changes to your TLS stack. Sender-constraining tokens win on resilience: a stolen token becomes an inert string the moment it is separated from the private key that was used to bind it.

The table below captures the most important practical differences. Note that "medium" complexity for sender-constraining tokens reflects DPoP specifically. mTLS-constrained tokens carry higher operational overhead and are not suitable for browser-based public clients without significant infrastructure investment.

Property Bearer token Sender-constraining token
Token theft risk High Very low
Implementation complexity Low Medium
Browser support Full DPoP supported; mTLS limited
Proof of possession None Cryptographic
Replay resistance No Yes (DPoP nonces)
Infrastructure requirements Minimal Key management or PKI
Suitable for public clients Yes Yes (DPoP)

The real-world impact of token theft

Bearer token theft is not theoretical. Several well-documented attack vectors remain relevant today.

Cross-site request forgery and open redirects can expose tokens stored in browser memory or sent in query parameters. Misconfigured logging pipelines frequently capture authorization headers verbatim. In multi-tenant environments, bugs in token validation logic have allowed tokens issued for one tenant to be accepted by another. Compromised third-party scripts with access to the DOM can exfiltrate tokens from localStorage.

With a bearer token, any of these exposures translates directly into account takeover for the duration of the token's lifetime. With a sender-constraining token, the attacker has a token but no private key, leaving them with an artifact that produces only 401 responses.

When to use each approach

Bearer tokens remain a reasonable default for many use cases. Internal service-to-service calls over private networks, low-sensitivity APIs, and developer tooling where operational simplicity matters more than adversarial robustness are all fine candidates. Short token lifetimes and rotation policies can reduce the blast radius of a stolen bearer token considerably.

Sender-constraining tokens become important when any of the following apply.

  • The access token crosses trust boundaries. If the token flows through a browser, a mobile app, or any environment where you cannot fully control the channel, binding the token to a key reduces the attack surface dramatically.
  • Regulatory requirements demand it. FAPI 2.0, the successor to the Financial-grade API profile, mandates DPoP or mTLS for all access tokens. If you are building for open banking or regulated financial services, sender-constraining is not optional.
  • Token lifetimes need to be long. Short-lived tokens are the standard mitigation for bearer token theft, but some use cases require longer-lived credentials. Binding those credentials to a key makes their longer lifetimes less dangerous.
  • You are issuing tokens to machine clients with stable key material. Backend services that can reliably manage private keys are good candidates for mTLS-constrained tokens, particularly in zero-trust architectures where lateral movement is a concern.

Implementing DPoP in practice

For most teams adopting sender-constraining today, DPoP is the right starting point. It works over standard HTTPS without changes to the TLS stack, is supported by major identity providers including Microsoft Entra ID and Okta, and has growing library support across ecosystems.

At a high level, the implementation involves three steps.

  1. The client generates an EC or RSA key pair and stores the private key securely (in a hardware-backed keystore on mobile, or in memory for server-side clients).
  2. At authorization time, the client includes its public key in the token request. The authorization server embeds a JWK thumbprint in the resulting access token.
  3. On every resource request, the client generates a fresh DPoP proof JWT, signs it with its private key, and sends it alongside the access token. The resource server validates both.

Libraries like oauth2-client (Python), node-openid-client (Node.js), and spring-security-oauth2 (Java) already handle DPoP proof generation. The main operational burden is key storage and rotation, which is manageable for most teams.

A note on phantom token patterns

It is worth mentioning that some architectures use reference tokens at the network edge and introspect them into JWTs at the API gateway. This pattern can coexist with sender-constraining: the introspected token can carry a key thumbprint just as a directly issued JWT can. The critical point is that whatever token reaches the resource server needs to be the one carrying the binding claim.

Conclusion

Bearer tokens are not broken, but they require careful handling to be safe. Short lifetimes, HTTPS everywhere, and strict storage discipline can make them workable in many scenarios. But they will always carry the fundamental risk that a stolen token is a usable token.

Sender-constraining tokens change that equation. By requiring the presenter to prove possession of a private key on every request, they make stolen tokens inert. DPoP has matured to the point where adoption is practical for most teams, and the ecosystem of libraries, identity providers, and specifications supporting it is solid.

For any new API handling sensitive data, or any system operating under financial or healthcare regulation, the question is no longer whether to adopt sender-constraining tokens, but which mechanism fits the deployment context best.