Skip to main content

Sender-Constrained Tokens (DPoP / mTLS) and Refresh Token Rotation

Overview

A normal Bearer token can be used by "anyone who holds it," so if stolen, an attacker can use it directly. The mechanism that prevents this is the sender-constrained token, which binds the token to a specific client's key. There are two ways to achieve it: DPoP and mTLS.

For long-lived refresh tokens, rotation is used in combination. OAuth 2.1 / the Security BCP requires refresh tokens for public clients that hold tokens in the browser/device to be either rotated or sender-constrained.

Not needed if tokens are kept server-side

If tokens are kept server-side (as in the BFF pattern), there is no token on the client to steal, so neither DPoP nor mTLS is needed. Sender-constraining matters for public clients that must hold tokens on the device (native mobile apps, etc.).

The weakness of Bearer tokens

Bearer tokens assume "possession = right to use" and carry no binding of "whose token this is." Sender-constrained tokens add a "proof of key possession" here.

mTLS (Mutual TLS) — RFC 8705

The client presents a TLS client certificate and binds the token to it. The token embeds the certificate thumbprint (x5t#S256 in the cnf claim), and the resource server verifies that it matches the certificate presented on the TLS connection.

  • Pros: completes at the TLS layer; robust.
  • Cons: requires PKI (certificate issuance, distribution, revocation), which is operationally heavy. Unsuitable for public clients.

DPoP (Demonstrating Proof-of-Possession) — RFC 9449

The client generates its own key pair and attaches a signed DPoP proof (JWT) in the DPoP header on every request. The token is bound to the public-key thumbprint (cnf.jkt), and the resource server verifies that the proof was signed with the key bound to that token.

POST /resource
Authorization: DPoP <access_token>
DPoP: <proof-jwt> # contains htm(method), htu(URL), iat, jti; signed with the client's private key

access_token cnf: { "jkt": "<SHA-256 thumbprint of the public key>" }
  • Pros: no PKI, lightweight. Suitable for SPAs, mobile, public clients.
  • Cons: requires proof generation/validation on both client and server.

DPoP vs. mTLS comparison

AspectDPoP (RFC 9449)mTLS (RFC 8705)
Binding targetApp-generated key pairTLS client certificate
PKINot requiredRequired
Implementation weightLightweight (app layer)Heavy (infra/cert management)
Suited clientsPublic (mobile/SPA)System-to-system / high assurance
General recommendationLightweight, good for publicRobust but high operational cost

Refresh token rotation

Each time a refresh token is used, a new refresh token is issued and the old one is invalidated.

  • If an old (already-used) refresh token is re-presented, it is treated as a sign of leakage/copy, and the entire token family is invalidated (reuse detection).
  • It is not sender-constraining, but it minimizes the window of damage from a leak.

Requirements for public clients (OAuth 2.1)

OAuth 2.1 / the Security BCP requires one of the following for a public client's refresh token.

  1. Rotation (with reuse detection)
  2. Sender-constraining (DPoP or mTLS)

When to use what

  • Web (browser) apps: keep tokens server-side via BFF → no binding needed (the simplest).
  • Native mobile / SPA (public): tokens are on the device, so use rotation as a baseline and consider DPoP-based sender-constraining to harden further.
  • High-assurance system-to-system: consider mTLS.

Summary

  • Bearer tokens are "possession = right to use," so a stolen token is replayable.
  • Sender-constrained tokens bind the token to a key and prevent replay on theft. DPoP (no PKI, lightweight) and mTLS (high assurance, heavy) are the two methods.
  • Refresh token rotation minimizes leak damage via reuse detection.
  • Keep tokens server-side and no binding is needed. Rotation/DPoP matter for public clients that hold tokens on the device.

References