What is DPoP in Keycloak?

What is DPoP in Keycloak?

A regular access token works for whoever holds it — steal the token, steal the access. DPoP changes the rule: the token only works in the hands of the exact device that originally requested it.

Imagine a train ticket that works for anyone holding it versus a ticket that’s only valid when scanned alongside the exact fingerprint of the person who bought it. The first kind is convenient but risky — drop it, and a stranger rides for free. The second kind is dramatically harder to misuse, because possession of the paper alone isn’t enough anymore. Standard OAuth access tokens behave like the first kind of ticket: a “bearer” token, usable by anyone who has a copy of it, regardless of how they got it. DPoP — Demonstrating Proof of Possession — is how Keycloak upgrades a token to behave like the second kind, cryptographically binding it to the specific device that requested it. This guide explains what DPoP actually is, how Keycloak implements it, what happens internally on every request, and how real deployments decide when the extra protection is worth the extra complexity. No prior background in tokens or cryptography is assumed.

1Core Concepts

Before DPoP makes sense, you need to understand the specific weakness it was designed to fix: how ordinary “bearer” tokens work, and why that’s a problem.

What is a bearer token?

The standard access token Keycloak issues by default is called a bearer token. The name describes its behavior exactly: whoever “bears,” or holds, the token is treated as authorized, full stop. An API receiving a bearer token checks that it’s genuinely signed by Keycloak and hasn’t expired, but it never asks “did the entity presenting this token right now actually get it originally?” This is efficient and simple, but it means a bearer token is exactly as dangerous to lose as cash — if it’s copied or stolen, whoever has it can spend it, with no further questions asked.

What problem does DPoP solve?

If an attacker manages to intercept or steal a bearer token — through a compromised browser extension, a poorly secured mobile app, a leaked server log, or a network-level attack — they can replay that exact token against the API and be treated as the legitimate user, with no way for the API to tell the difference. DPoP closes this gap by requiring the client to prove, on every single request, that it actually possesses the specific private key associated with that token — not just that it happens to have a copy of the token text itself.

Analogy

Think of a hotel safe-deposit box that requires both a physical key and a second key held only by the hotel manager, used together to open it. A bearer token is like a system with only the physical key — copy the key, and you’re in. DPoP is like requiring the person opening the box to also prove, right there in front of the manager, that they know a secret only the original key-holder would know. Simply having a copy of the physical key is no longer enough on its own.

How does DPoP actually prove possession?

DPoP works using public-key cryptography, the same general technique behind WebAuthn. The client generates a key pair — a private key it keeps secret and never sends anywhere, and a public key it can share freely. When requesting a token, the client tells Keycloak about its public key. Keycloak then cryptographically ties the issued token to that specific public key. On every subsequent request to an API, the client must attach a small, freshly signed proof, created using its private key, demonstrating it still controls the matching key — something a thief who only stole the token text, but not the private key, simply cannot produce.

i
Where you’d meet this

Financial APIs, healthcare systems, and any application handling especially sensitive actions where a stolen token alone should never be enough to gain access are the natural places to find DPoP enabled in a Keycloak deployment.

Key vocabulary, explained simply

Term

Bearer Token

A standard access token usable by anyone who holds a copy of it, with no further proof of legitimate possession required.

Term

DPoP Proof

A small, freshly signed JWT the client creates and attaches to each request, demonstrating it holds the private key tied to the token being used.

Term

Key Binding

The process of cryptographically associating an issued token with a specific client-held public key, so the token only “works” alongside proof from the matching private key.

Term

Token Theft / Replay Attack

An attack where a stolen or intercepted token is reused by someone other than its original, legitimate holder — exactly what DPoP is designed to defeat.

Term

JWK (JSON Web Key)

A standard JSON format for representing a cryptographic key, used to describe the client’s public key both during token issuance and inside each DPoP proof.

Term

Access Token Hash (ath)

A claim inside a DPoP proof containing a hash of the access token itself, tying the proof specifically to that one token rather than any token from the same client.

2Architecture & Components

Adding DPoP to a login flow introduces a few new moving parts on both the client side and the Keycloak server side, working together to establish and later verify the key binding.
graph TB
    C[Client] --> KG[Generates Key Pair
private + public key] C -->|token request + DPoP proof| KC[Keycloak Token Endpoint] KC --> BIND[Binds token to
client's public key] BIND --> TOK["DPoP-bound
Access Token"] TOK --> C C -->|API call + token + fresh DPoP proof| API[Resource Server] API --> VER[Verifies proof signature
matches token's bound key] VER --> DEC{Match?} DEC -->|yes| ALLOW[Request Processed] DEC -->|no| REJECT[Request Rejected]
FIG 1 — Key generation, token binding at issuance, and proof verification at every API call

Component breakdown

Component

Client-Side Key Generation

The application itself (a browser-based app, a mobile app, a backend service) is responsible for generating and securely storing its own DPoP key pair, since the private key must never leave the client.

Component

Keycloak’s DPoP Support

Realm and client-level settings that enable DPoP enforcement, controlling whether it’s required, optional, or disabled for a given client’s tokens.

Component

Token Endpoint Binding Logic

The part of Keycloak’s token issuance process that reads the client’s supplied public key (via an initial DPoP proof) and embeds a reference to it into the issued token.

Component

Resource Server Verification

The backend API code responsible for checking, on every request, that the attached DPoP proof is fresh, correctly signed, and matches the key the presented token was bound to.

Where this is configured in the admin console

Inside the Keycloak Admin Console, DPoP support is typically configured at the client level, under a client’s advanced or security-related settings, where an administrator can require DPoP for that specific client’s tokens. Realm-wide policy settings may also influence whether DPoP is available or mandatory across multiple clients, depending on the deployment’s overall security posture.

A common real setup

A banking application’s mobile app is configured as a Keycloak client with DPoP required. The app generates a device-specific key pair on first launch, stores the private key in the device’s secure hardware enclave, and includes a DPoP proof with every token request and every subsequent API call — meaning a stolen access token extracted from the app’s memory or network traffic is useless without also somehow extracting the private key from the device’s secure hardware.

Why isn’t DPoP just turned on for everyone by default?

Adding DPoP introduces real complexity — clients must generate, securely store, and correctly use cryptographic keys, and every resource server must add proof verification logic. For lower-sensitivity applications, this overhead may not be justified, since ordinary token security controls (short expiry, HTTPS, secure storage) are often sufficient. Keycloak makes DPoP an opt-in capability specifically so organizations can apply the extra protection where the risk genuinely warrants it.

3Internal Working

Two distinct moments matter: how a token first becomes bound to a key when it’s issued, and what a client and API must do together on every single request afterward to actually use that binding.

Binding a token to a key at issuance

When a DPoP-enabled client requests a token, it includes a specially crafted proof — a small, signed JWT containing its public key, a timestamp, a unique identifier, and details about the specific request being made. Keycloak verifies this proof is well-formed and freshly generated, then, upon issuing the access token, embeds a reference to the client’s public key directly into the token itself (typically as a thumbprint or hash of the key, inside a confirmation claim). From that moment on, this specific token is permanently, cryptographically tied to that specific public key.

Proving possession on every subsequent request

Every time the client wants to use the token against a resource server, it must generate a brand-new DPoP proof for that specific request — signed with the same private key, including a hash of the access token being presented, the HTTP method and URL of the request, and a fresh timestamp and unique identifier. The resource server checks this proof’s signature against the public key embedded in the token’s confirmation claim; if they match, and the proof is fresh and correctly tied to this exact request, the token is accepted as genuinely being used by its rightful holder.

“The token alone proves nothing under DPoP — it’s the token plus a fresh, correctly signed proof, together, that proves legitimate possession.”

Why a fresh proof is needed for every request, not just once

If a single DPoP proof could be reused indefinitely, an attacker who captured one specific proof-token pair could simply replay both together forever, defeating much of the point. Requiring a brand-new, uniquely identified proof for every single request — checked against a short validity window and a record of recently used proof identifiers — prevents this kind of replay, ensuring that even a captured, valid proof from one moment in time cannot be reused later.

!
Gotcha

Because each DPoP proof includes a timestamp and must fall within a tight validity window, significant clock drift between a client’s device and the Keycloak server (or resource server) can cause otherwise legitimate requests to be incorrectly rejected — accurate time synchronization becomes an operational requirement, not just a nicety.

Step-by-step: from key generation to a verified API call

1

Key pair generated

The client generates a private and public key pair, ideally stored in secure, tamper-resistant storage.

2

Initial DPoP proof created

The client builds a signed proof containing its public key, to accompany the token request.

3

Token issued and bound

Keycloak verifies the proof and issues an access token with the client’s public key thumbprint embedded inside it.

4

New proof generated per API call

Before each request, the client signs a fresh proof specific to that exact request’s method, URL, and the token being used.

5

Resource server verifies both together

The API checks the token’s validity as usual, plus verifies the accompanying proof matches the token’s bound key and is fresh.

6

Request accepted or rejected

Only requests passing both the standard token check and the DPoP proof check are processed.

4Data Flow & Lifecycle

Seeing the complete flow from key creation through repeated API use highlights exactly how much extra cryptographic work happens compared to a standard bearer-token flow, and why that extra work buys real protection.
sequenceDiagram
    participant Client
    participant Keycloak
    participant API as Resource Server

    Client->>Client: Generates key pair (once)
    Client->>Keycloak: Token request + DPoP proof (public key)
    Keycloak->>Keycloak: Binds token to public key
    Keycloak-->>Client: Issues DPoP-bound access token
    loop Every API call
        Client->>Client: Creates fresh DPoP proof
        Client->>API: Sends token + fresh proof
        API->>API: Verifies proof matches bound key
        alt Valid
            API-->>Client: Processes request
        else Invalid or stolen token alone
            API-->>Client: Rejects request
        end
    end
    
FIG 2 — A fresh proof required for every single API call, not just at token issuance

Notice the loop in this diagram: unlike a bearer token, which is checked once per request purely by its own signature and expiry, a DPoP-bound token requires this extra proof-generation-and-verification cycle on literally every single API call. This is the direct cost of the added security — more cryptographic work happening continuously, in exchange for meaningfully closing the token-theft gap that plain bearer tokens leave open.

The lifecycle of a DPoP key pair

A

Generated once per client instance

A key pair is typically created once when an application first initializes, not regenerated for every single login.

B

Reused across multiple tokens

The same key pair can be used to bind multiple tokens obtained over time by the same client instance, as long as it persists.

C

Persisted securely on the device

The private key is stored, ideally in hardware-backed secure storage, for as long as the client application remains installed and active.

D

Retired on uninstall or reset

If the application is uninstalled or the user resets it, the key pair is lost, and any future login requires generating a fresh one.

i
Worth noting

Because the key pair, not the token, is what actually persists across a client’s lifetime, losing the private key (through a device reset, for example) simply means the client needs to generate a new one and go through the binding process again on its next login — it does not compromise any previously issued tokens.

5Advantages, Disadvantages & Trade-offs

DPoP meaningfully raises the bar against token theft, but that protection is bought with real added complexity on both the client and server sides.

Advantages

  • Dramatically reduces the value of a stolen token alone, since it’s useless without the matching private key
  • Works without requiring specialized hardware, unlike some alternative token-binding approaches that depend on specific network-layer features
  • Standardized, meaning DPoP-aware clients and servers can interoperate across different implementations, not just within Keycloak
  • Can be applied selectively, only to the clients and APIs that genuinely need this stronger protection

Disadvantages & Trade-offs

  • Requires every client application to correctly generate, securely store, and consistently use cryptographic keys
  • Every resource server must add proof verification logic, not just accept a token check as before
  • Adds computational overhead to every single API request, not just at login
  • Sensitive to clock synchronization issues, since proof freshness depends on accurate timestamps
Analogy

Upgrading from a simple door lock to a lock requiring both a key and a live fingerprint scan is a real security improvement, but it also means every door needs a fingerprint reader installed, and every key must be paired correctly with its owner’s fingerprint data ahead of time. The security gain is genuine, but so is the added infrastructure and operational complexity required to make it actually work correctly everywhere it’s deployed.

6Security

DPoP is, at its core, a security feature — but like any cryptographic mechanism, its actual strength depends entirely on correct implementation of a few specific details.

The specific threat DPoP defends against

DPoP is specifically designed to defend against token exfiltration — scenarios where an attacker gains access to a copy of a valid access token through means other than legitimately obtaining it, such as a cross-site scripting vulnerability, a misconfigured logging system that accidentally records tokens, or network interception. Without DPoP, such an attacker can simply replay the stolen token. With DPoP correctly implemented, the same stolen token is useless without also somehow extracting the private key, which never travels over the network and, ideally, lives in hardware-backed secure storage.

SEC-08Recommended
Context

DPoP’s protection depends entirely on the private key genuinely staying private; storing it in easily accessible application memory or unencrypted local storage significantly undermines the whole mechanism.

Decision

Store DPoP private keys in the strongest secure storage available on the client platform — a hardware security module, a mobile device’s secure enclave, or an equivalent — rather than plain application memory or ordinary file storage.

Consequence

An attacker who compromises the application’s general memory or storage still cannot easily extract the private key, preserving DPoP’s core protection even in a partially compromised environment.

Replay protection and proof freshness

Resource servers must track recently seen DPoP proof identifiers within their validity window, rejecting a proof that’s been seen before — otherwise, an attacker who captures a single valid proof-and-token pair could replay it repeatedly within that brief validity window. Correctly implementing this replay-detection logic, alongside strict timestamp checking, is essential to DPoP actually delivering its intended protection rather than only appearing to.

!
Common mistake

Implementing DPoP verification that checks the proof’s signature and timestamp but forgets to track and reject reused proof identifiers, leaving a narrow but real replay window open within the proof’s validity period.

DPoP does not replace other token security practices

DPoP specifically addresses token theft and replay — it does not, on its own, address other concerns like short expiry times, proper session revocation, or transport security. A complete token security posture still requires HTTPS everywhere, sensible expiry times, and the revocation mechanisms covered elsewhere; DPoP is a powerful additional layer, not a replacement for these fundamentals.

7Monitoring, Logging & Metrics

Because DPoP adds a whole new verification step to every request, monitoring its health and catching failures early is essential to avoid both silent security gaps and confusing, hard-to-diagnose request failures.
2
checks every DPoP-protected request must pass: token validity and proof validity
1
private key compromise is enough to fully defeat DPoP’s protection for that client
0
tolerance for reused proof identifiers within the validity window
Metric

DPoP proof rejection rate

Tracking how often proofs fail verification, since a rising rate can indicate clock synchronization issues, a client-side bug, or active attack attempts using stolen tokens without a valid matching key.

Metric

Clock skew incidents

Logging rejections specifically attributable to timestamp validity failures, helping distinguish legitimate infrastructure issues from genuine security concerns.

Metric

Replayed proof detection count

Monitoring how often a resource server catches and rejects a reused proof identifier, since any non-zero rate here deserves investigation as a potential active token-theft attempt.

Metric

DPoP-enabled client coverage

Tracking what proportion of an organization’s sensitive clients actually have DPoP enabled and correctly configured, as an ongoing security-posture measurement.

A practical monitoring habit

Security teams operating DPoP-protected APIs often build a specific dashboard panel tracking proof rejection reasons broken down by category — expired timestamp, key mismatch, replayed identifier — since each category points to a different root cause, from a simple infrastructure clock issue to a genuinely serious security event worth immediate investigation.

8Design Patterns & Anti-patterns

Teams adopting DPoP for real, sensitive applications tend to reach for the same handful of dependable implementation patterns, and repeatedly encounter the same avoidable configuration mistakes.

Proven patterns

Pattern

Selective DPoP adoption

Enable DPoP specifically for the clients and APIs handling the most sensitive actions, rather than applying it universally where the added complexity isn’t justified by the actual risk.

Pattern

Hardware-backed key storage wherever available

Prefer platform-provided secure storage (a device’s secure enclave, a hardware security module) for the DPoP private key over plain in-memory or file-based storage.

Pattern

Centralized proof verification logic

Build DPoP proof verification into a shared library or middleware used across all resource servers, rather than letting each team implement subtly different, potentially inconsistent verification logic.

Pattern

Robust time synchronization

Ensure all clients, Keycloak, and resource servers rely on accurate, synchronized time sources, given how sensitive DPoP proof validation is to clock drift.

Anti-patterns to avoid

Anti-pattern

  • Storing the DPoP private key in easily accessible, unencrypted application storage
  • Verifying only a proof’s signature and timestamp while ignoring replay protection for proof identifiers
  • Applying DPoP universally across every client regardless of actual sensitivity, adding complexity without proportional benefit everywhere
  • Assuming DPoP alone is sufficient security, neglecting other fundamentals like short token expiry and proper session revocation

Instead, do this

  • Use the strongest available secure storage for private keys on each client platform
  • Implement full proof verification, including replay-identifier tracking, consistently across every resource server
  • Reserve DPoP for genuinely sensitive clients and APIs where the added protection is worth the complexity
  • Treat DPoP as one layer among several complementary token security practices, not a standalone solution

9Best Practices & Common Mistakes

Getting DPoP right in production is less about the cryptography itself, which is well standardized, and more about disciplined implementation and operational habits around key management and verification.

Best practices

1

Use well-tested DPoP libraries

Rely on established, widely reviewed libraries for generating and verifying DPoP proofs rather than implementing the cryptographic details from scratch.

2

Test clock synchronization across environments

Verify that client devices, Keycloak, and resource servers all maintain accurate, closely synchronized time, especially across distributed or mobile deployments.

3

Plan for key loss scenarios

Design the client application’s login flow to gracefully handle a lost or reset private key, generating a fresh key pair and re-establishing a new token binding as needed.

4

Regularly audit which clients actually enforce DPoP

Periodically confirm that DPoP remains correctly enabled and enforced for every client it was intended to protect, since configuration drift over time is a real risk.

Common mistakes

!
Mistake

Enabling DPoP on the client side but forgetting to implement corresponding proof verification on the resource server, meaning tokens are correctly bound but the API never actually checks the binding, providing a false sense of security.

!
Mistake

Regenerating a fresh key pair on every single app launch instead of persisting it, unnecessarily forcing a full re-binding process far more often than needed and adding friction without any real security benefit.

!
Mistake

Underestimating the operational impact of strict timestamp validation, only discovering in production that a subset of devices with meaningfully inaccurate clocks are being incorrectly rejected.

10Real-world & Industry Examples

DPoP is a relatively recent, targeted enhancement adopted specifically by organizations facing genuine risk of token theft, rather than a blanket standard applied everywhere.
Industry

Open banking and financial APIs

Financial services standards increasingly favor sender-constrained tokens like those DPoP provides, specifically to protect high-value transaction APIs from token theft scenarios that plain bearer tokens can’t defend against.

Industry

Healthcare data platforms

Systems handling sensitive patient data adopt DPoP for APIs where a stolen token could otherwise expose protected health information, adding a meaningful extra barrier beyond standard token controls.

Industry

Mobile-first applications with secure hardware

Applications on modern smartphones, which typically include hardware-backed secure key storage, are well-positioned to adopt DPoP with strong private-key protection built directly into the device itself.

Industry

Government and defense-adjacent systems

Organizations subject to strict security requirements around credential and token handling use DPoP as part of a broader defense-in-depth strategy against token exfiltration risks.

A representative scenario

A healthcare technology company handling patient records discovered, during a security review, that a third-party JavaScript library used on one of their pages had a vulnerability that could allow an attacker to read tokens stored in browser memory. Rather than relying solely on shortening token lifetimes, they enabled DPoP for their most sensitive API, requiring proof of key possession on every call — meaning even if the vulnerable library did leak a token, an attacker still couldn’t use it without also somehow extracting a private key that never left the browser’s secure key-storage mechanism.

11FAQ

Q1Is DPoP the same as mutual TLS (mTLS) client authentication?
No, though both achieve a similar goal of binding a token to a specific client. DPoP works at the application layer using signed JWT proofs, while mutual TLS relies on the underlying network connection’s own certificate exchange — they’re different mechanisms with different infrastructure requirements.
Q2Does DPoP replace the need for HTTPS?
No. HTTPS remains essential for protecting data in transit generally. DPoP specifically addresses what happens if a token is stolen despite HTTPS, such as through a compromised client application rather than network interception.
Q3Can DPoP be used with any Keycloak client, or only certain types?
DPoP requires the client to be capable of generating and securely managing cryptographic keys, which is realistic for most modern application types, but the security benefit is strongest when genuinely secure key storage, like hardware-backed storage, is available.
Q4What happens if a device’s clock is significantly out of sync?
DPoP proofs include a timestamp checked against a validity window, so significant clock drift can cause otherwise legitimate proofs to be incorrectly rejected, making accurate time synchronization an operational requirement.
Q5Does enabling DPoP slow down API requests noticeably?
There is some added cryptographic overhead for generating and verifying proofs on every request, though for most applications this overhead is small compared to typical network latency; the actual impact depends on implementation and the specific systems involved.
Q6If DPoP is so much more secure, why isn’t it used everywhere by default?
The added complexity in key management, secure storage, and verification logic isn’t justified for every application; Keycloak makes DPoP an opt-in capability so organizations can apply it specifically where the risk of token theft genuinely warrants the extra protection.

12Summary and Key Takeaways

Key Takeaways

  • DPoP cryptographically binds an access token to the specific client that requested it, upgrading it from a “bearer” token to a “sender-constrained” one.
  • It defends specifically against token theft and replay attacks, where a stolen token alone would otherwise be enough for an attacker to gain access.
  • Every request requires a fresh, signed DPoP proof, generated with the client’s private key and verified by the resource server against the token’s bound public key.
  • The protection is only as strong as the secrecy of the private key — hardware-backed secure storage significantly strengthens DPoP’s real-world security value.
  • Resource servers must implement full verification, including replay-identifier tracking, not just signature and timestamp checks, for the protection to be complete.
  • DPoP adds real complexity and overhead — key management, verification logic, and sensitivity to clock synchronization — making it best suited to genuinely sensitive clients and APIs rather than universal adoption.
  • It is a complementary layer, not a replacement, for other token security fundamentals like HTTPS, short expiry, and proper session revocation.
  • Real-world adoption concentrates in high-sensitivity domains — financial services, healthcare, government systems — where the consequences of token theft justify the added implementation effort.