DPoP proof header

Introduction

DPoP proof is a JWT created by the client and sent with an HTTP request using the DPoP header field. Each HTTP request requires a unique DPoP proof.

A valid DPoP proof demonstrates to the server that the client holds the private key that was used to sign the DPoP proof JWT. This enables authorization servers to bind issued tokens to the corresponding public key and for resource servers to verify the key-binding of tokens that it receives, which prevents said tokens from being used by any entity that does not have access to the private key.

A DPoP proof header consists of a JWT that adheres to the following structure, and consists of

  • a JWT header
  • a JWT payload
  • a JWT signature

JWT Header

The header of a DPoP JWT contains at least the following parameters:

  • typ: type header, value dpop+jwt.
  • alg: a digital signature algorithm identifier as defined in RFC7518 (REQUIRED). MUST NOT be none or an identifier for a symmetric algorithm (MAC).
  • jwk: representing the public key chosen by the client, in JWK format, as defined in RFC7515 (REQUIRED). MUST NOT contain the private key.

JWT payload

The payload of a DPoP proof contains at least the following claims:

  • jti: Unique identifier for the DPoP proof JWT (REQUIRED). The value MUST be assigned such that there is a negligible probability that the same value will be assigned to any other DPoP proof used in the same context during the time window of validity. Such uniqueness can be accomplished by encoding (base64url or any other suitable encoding) at least 96 bits of pseudorandom data or by using a version 4 UUID string. The jti can be used by the server for replay detection and prevention.
  • htm: The HTTP method for the request to which the JWT is attached (REQUIRED).
  • htu: The HTTP URI to which the request is directed, without query and fragment parts (REQUIRED).
  • iat: Time at which the JWT was created (REQUIRED).

When the DPoP proof is used in conjunction with the presentation of an access token, as defined in Section 7, the DPoP proof MUST also contain the following claim:

  • ath: hash of the access token (REQUIRED). The value MUST be the result of a base64url encoding (with no padding) the SHA-256 hash of the ASCII encoding of the associated access token’s value.

A DPoP proof MAY contain other headers or claims as defined by extension, profile, or deployment specific requirements.

Example:

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

JWT signature

The header and payload need to be signed by a private and public key as defined in RFC7518. The signature is calculated using the private key and the algorithm specified in the header.

From here on out these keys should always be used with all DPoP proofs that are included with the access token you use.


Source: OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer
(DPoP)