DPoP and Nonces#
The HAAPI access token is a DPoP-bound token rather than a traditional bearer token. Every request that uses the access token must also carry a fresh DPoP proof — a short-lived JWT signed with a private key held on the device. the Curity Identity Server verifies the proof’s signature, the proof’s covered HTTP method and URL, and the proof’s freshness before honoring the request.
How It Works#
The client generates an asymmetric key pair once per HAAPI session. For each outgoing request:
- The client constructs a DPoP JWT containing the HTTP method, target URL, issuance timestamp, and a unique
jti. It signs the JWT with the private key. - The client sends the proof in the
DPoPheader alongside the access token inAuthorization: DPoP <token>. - The server validates the proof’s signature against the public key bound to the access token, then checks that the method and URL match the request being made.
Server-Issued Nonces#
To mitigate clock skew and protect against replay across boundaries, the Curity Identity Server can require a server-issued nonce inside every DPoP proof. The server emits the nonce in a DPoP-Nonce response header; the client must include it in the next proof. When the nonce becomes stale, the server returns a 401 with error="use_dpop_nonce" and a fresh nonce, and the client retries with the updated value.
Nonce-based DPoP is enabled when the HAAPI client’s use-legacy-dpop setting is false (the default for new clients). When true, the server uses the older nonce-less DPoP behavior, kept for backward compatibility with older SDK versions that pre-date auto-managed nonces.
Nonce Management Is Automatic — for the Authorization Server#
The Curity HAAPI iOS and Android SDKs manage the DPoP nonce lifecycle internally for their own traffic to the authorization server. The framework’s URL session tracks the latest DPoP-Nonce header from each response and applies it to subsequent requests. Application code that previously had to extract and re-pass the nonce can be simplified — see the upgrade guide for migration details.
A resource server is a different matter. When your application calls its own API with a DPoP-bound access token, that server issues nonces in a space of its own that the SDK never sees: it is not the authorization server, and its nonce must never be reused for one. Read the DPoP-Nonce from its responses, keep the latest value per server, and pass it when you sign each proof — see OAuthTokenManager for the iOS and Android patterns.
How to implement this: HaapiTokenManager · Upgrade — DPoP Nonce Auto-Management · Token Binding