Should you use DPoP?
DPoP is opt-in at Flexslot. Set
dpop_bound_access_tokens: true on your OAuth client in the partner admin to require DPoP for all tokens issued to that client.How DPoP works
The key insight: every single API request gets its own short-lived proof JWT, signed by the client’s private key, that names the URL, method, and the hash of the access token. An attacker who steals the access token can’t make the proof.Set up your keypair
DPoP supportsES256 (ECDSA P-256), ES384, EdDSA, and RS256. Use ES256 unless you have a reason not to.
/token and all subsequent API calls.
Building a DPoP proof JWT
A DPoP proof is a JWT with: Header:Helper
Token exchange with DPoP
Add aDPoP header to the /token request:
"token_type": "DPoP" to signal the token is sender-constrained:
DPoP proof and checks it against the bound value. You can confirm the binding out-of-band via the introspection endpoint, whose active response includes a cnf.jkt claim carrying the bound thumbprint (e.g. "cnf": { "jkt": "0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I" }).
Calling the resource server with DPoP
Two changes to every API call:- The
Authorizationscheme isDPoP, notBearer. - Add a
DPoPheader with a fresh proof that includesath.
Refreshing DPoP-bound tokens
Refresh tokens for a DPoP client are also bound to the key. The/token request to refresh must include a DPoP proof signed by the same key as the original token exchange.
DPoP errors
Every DPoP failure uses the single error stringinvalid_dpop_proof — there is no invalid_token, and no nonce challenge.
Flexslot does not implement DPoP nonces (RFC 9449 §8 nonce mode is optional and not enabled), so your proofs never need a
nonce claim and you will never see a DPoP-Nonce response header or a use_dpop_nonce error.Trade-offs
When NOT to use DPoP
- For very low-value reads where the convenience of Bearer outweighs the marginal risk.
- For machine-to-machine flows where mTLS (RFC 8705) is a better fit (continuous mutual auth, not per-request).
- For environments where your TLS terminator strips the
DPoPheader — fix the infra first.
Reference
- RFC 9449 — The DPoP spec.
- RFC 7638 — JWK Thumbprint (how
cnf.jktis computed). - jose for Node — Recommended JOSE library.
- jwcrypto for Python — JWS/JWK support including DPoP.