Demonstrating Proof of Possession (DPoP) overview and how it can be used to enhance the security of public clients.

Demonstrating Proof of Possession Overview

On this page

Demonstrating Proof of Possession (DPoP) is a relatively simple mechanism for sender-constraining access tokens. It gives you a way to tie an access token to the client that originally receives it from the authorization server. This means that the access token is no longer a bearer token. The client must provide a proof of possession in order to use the token.

The DPoP mechanism is a standard published as RFC 9449. It has been designed for use in scenarios where you cannot leverage stronger means of proof of possession. For example, when the client is not able to utilise mutual TLS.

Overview

DPoP relies on a simple principle: first, the client presents their public key to the authorization server, which is then incorporated into the access token. Next, the client sends the public key, encoded as a JWT, together with the access token to the resource server (RS). Thanks to this the RS can verify that the client is in possession of a private key and that it is the same key that was used when issuing the access token.

DPoP proofs are JWTs that must be signed by the client using a private key. What is important, asymmetric signing must be used for DPoP, otherwise the mechanism would be insecure.

Tying an Access Token to a Proof of Possession

When sending a request to the /token endpoint, the client adds a DPoP header, which is a signed JWT containing the following information:

  • the public key that can be used to verify the signature
  • jti claim, which is a unique identifier of the JWT
  • htm and htu claims, which contain respectively the HTTP method and the URL to which the client sends the request
  • iat claim, which has the time when the token was issued (authorization servers should only accept fairly fresh DPoP tokens)

The header and payload of DPoP token sent to a /token endpoint can look something like this:

json
12345678910111213141516
{
"typ": "dpop+jwt",
"alg": "ES256",
"jwk": {
"kty": "EC",
"x": "l8tFrhx-34tV3hRICRDY9zCkDlpBhF42UQUfWVAWBFs",
"y": "9VE4jf_Ok_o64zbTTlcuNJajHmt6v9TDVrU0CdvGRDA",
"crv": "P-256"
}
}
{
"jti": "-BwC3ESc6acc2lTc",
"htm": "POST",
"htu": "https://myidsvr.com/token",
"iat": 1598524639
}

The authorization server should validate the JWT - the signature and claims contained in the token. If DPoP is deemed valid the AS adds a confirmation claim to the access token which is a Base64 urlencoding of the SHA-256 Thumbprint of the public key used to sign the DPoP token.

This claim can look similar to this in the resulting access token JWT:

json
123
"cnf": {
"jkt": "0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I"
}

jkt claim is used to indicate that the DPoP mechanism was used.

Proving Possession in Requests to a Resource Server

Once the client receives an access token with a confirmation claim it must provide a proof of possession whenever the token is used to access resources. The client must send a DPoP token for every request it makes to the RS. The token must be constructed in the same way as for the /token endpoint. In particular, the htm and htu claims must have the values conforming to each request being made.

The client sends the access token using the DPoP scheme and a DPoP header containing the DPoP token minted for the concrete request:

bash
1234
GET /resource HTTP/1.1
Host: api.example.com
Authorization: DPoP eyJhbGci...hF1MQ
DPoP: eyJ0eXAi...4UCbQ

The resource server, should verify a few things when receiving a DPoP token:

  • Verify the signature of the DPoP token with the public key contained in the header of that token.
  • Verify the claims of the DPoP token: whether the HTTP method and URL match the called endpoint and whether the token is not expired.
  • Verify whether the public key used to sign the DPoP token matches the thumbprint from the jkt claim of the access token.

The resource server rejects requests which fail the verification of the proof of possession.

DPoP in the Curity Identity Server

In the Curity Identity Server, DPoP is required for clients which want to use the Hypermedia Authentication API. DPoP is required when using the API to further increase the security of communication between the client and the authorization server.

Conclusion

The DPoP mechanism provides a new way for sender-constraining access tokens. It's great for scenarios where clients are not able to use a different method for proving the possession of an access token.

Photo of Michal Trojanowski

Michal Trojanowski

Product Marketing Engineer at Curity

Join our Newsletter

Get the latest on identity management, API Security and authentication straight to your inbox.

Start Free Trial

Try the Curity Identity Server for Free. Get up and running in 10 minutes.

Start Free Trial