Validating DPoP proofs

This document outlines how an API should handle the use of DPoP, both in terms of general security measures and the handling and validation of DPoP tokens and proofs.

General Security Measures

When an API endpoint is set up for authorization using DPoP tokens, it shall not accept Bearer tokens in the Authorization header, but should only accept DPoP tokens. In other words: when the header Authorization: DPoP [token] is used in calls against the API endpoint, calls with the header Authorization: Bearer [token] should not be accepted.

The reason for this is that a DPoP token is backward compatible with traditional Bearer tokens, which makes the API vulnerable to attacks if the same endpoint accepts both types of tokens. To secure an API with both Bearer and DPoP tokens, the API may accept Bearer tokens at a (different) endpoint that does not accept DPoP tokens.

If an API wishes to secure different endpoints with both Bearer and DPoP tokens, it shall use a separate scope to distinguish between resources protected by DPoP and resources protected by traditional Bearer tokens.

API Validation of DPoP proofs

In addition to the normal validation of an Access token, an API using DPoP must also perform specific validations for the mechanism to provide value. If a library is used for DPoP proof validation, this will be functionality contained in the library code. If not, the following validations must be performed:

  1. Ensure that the Authorization header contains a DPoP token by checking that the value in the header starts with the text DPoP.

  2. Verify that the Access token is valid according to the general validation rules for Access tokens as described here.

  3. Confirm that the Access token is a DPoP token by ensuring it contains the cnf claim.

  4. Check that a DPoP proof is included in the DPoP header. Note that header names are not case-sensitive, so for example, DPOP and dpop are also valid names.

  5. Verify that there is no more than one DPoP header in the HTTP request.

  6. Ascertain that the DPoP proof is structured as a JWT as described in this appendix.

  7. Ensure that the DPoP proof's signature matches the public key found in the cnf claim in the DPoP proof's header.

  8. Ensure that the jwk header in the DPoP proof does not contain a symmetric key.

  9. Confirm that the htm and htu claims in the DPoP proof match the HTTP method and URL of the API call being made.

  10. Verify that the iat claim in the DPoP proof points to a time that is no more than 10 seconds in the past.

  11. Ensure that the jti claim in the DPoP proof has a value that is unique within the lifetime of a DPoP proof (10 seconds).

  12. Confirm that the value of the ath claim in the DPoP proof matches a cryptographic hash of the Access Token. The value is calculated as follows: The base64url encoded SHA-256 hash of the ASCII encoding of the associated access token's value.

  13. Verify that the value of the cnf claim in the Access token matches the public key of the DPoP proof.