openid-key-binding | July 2025 | |
Hardt & Heilman | Standards Track | [Page] |
OpenID Key Binding specifies how to bind a public key to an OpenID Connect ID Token using mechanisms defined in RFC 9449, OAuth 2.0 Demonstrating Proof of Possession (DPoP).¶
Some applications use proof of possession of a private key for authentication. OpenID Connect provides a protocol to delegate authentication and obtain identity claims to another service. This document specifies an extension to OpenID Connect to bind a public key to an OpenID Connect ID Token by profiling OpenID Connect 1.0, RFC8628 - OAuth 2.0 Device Authorization Grant, and RFC9449 - OAuth 2.0 Demonstrating Proof of Possession (DPoP).¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in {{RFC2119}}.¶
In the .txt version of this specification, values are quoted to indicate that they are to be taken literally. When using these values in protocol messages, the quotes MUST NOT be used as part of the value. In the HTML version of this specification, values to be taken literally are indicated by the use of this fixed-width font.¶
This specification uses the following terms:¶
OP: The OpenID Provider as defined in [OpenID Connect].¶
RP: The Relying Party as defined in [OpenID Connect].¶
The parameters dpop_jkt and DPoP as defined in [RFC9449]¶
This specification profiles how to bind a public key to an ID Token by:¶
adding the dpop_jkt
parameter to the OpenID Connect Authentication Request¶
receiving the authorization code
as usual in the Authentication Response¶
adding the DPoP
header that includes the code
as a claim to the Token Request to the OP token_endpoint
¶
adding the cnf
claim containing the public key to the returned ID Token¶
+------+ +------+ | |-- Authentication Request --->| | | RP | (1) dpop_jkt parameter | OP | | | | | | |<-- Authentication Response --| | | | (2) authorization code | | | | | | | |-- Token Request ------------>| | | | (3) DPoP header | | | | | | | |<-- Token Response -----------| | | | (4) cnf claim containing | | | | the public key in ID Token | | +------+ +------+¶
On successful authentication of, and consent from the user, the OP returns an authorization code
.¶
Following is a non-normative example of response:¶
Generate a DPoP
header that includes the authorization code
, that then binds the DPoP
header to the code
in the body of the token request.
To do this we set the nonce
claim of DPoP
header to the authorization code
.
The nonce
claim in the DPoP
is specified in [RFC9449] section 4.2 and is not the same as the ID Token nonce
claim defined in [OpenID Connect] 3.1.¶
Non-normative example:¶
POST /token HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW DPoP: eyJhbGciOiJFUzI1NiJ9.eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkV\ TMjU2IiwiandrIjp7ImNydiI6IlAtMjU2Iiwia3R5IjoiRUMiLCJ4IjoibWptR\ m1MZm9wVmkwZXRfYTZmZFhUTnJqYVUwR1dlZFN0Y3NfRzU4OEkyMCIsInkiOiJ\ sMFZwRXlSYzdTdUpfdHFhd2NaQ2VLLXVUOEVPVnF4N3NqTHJGeUJTUllZIn0sI\ m5vbmNlIjoiU3BseGxPQmVaUVFZYllTNld4U2JJQSJ9.cp8uN3kHAMS9fhGH7T\ vTSKwH5oNJzAeMhIrgD_HQHGhgt_N1xQHdHiMkn7AMj3UDkwoNOW4Qqak grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb¶
If a DPoP header is included in the token request to the RP, and the dpop_jkt
parameter was not included in the authentication request, the OP MUST NOT include the cnf
claim in the ID Token.¶
This prevents an existing deployment using DPoP for access token from having them included in ID Tokens accidentally.¶
The OP MUST perform all verification steps as described in [RFC9449] section 5.¶
In addition, the OP MUST also confirm the code
in the DPoP token nonce
claim matches the code
in the token request.¶
If the token request was successful, the OP MUST return an ID Token containing the cnf
claim as defined in [7800] set to the jwk of the user's public key and with typ
set to dpop+jwt
in the ID Token's protected header.¶
Non-normative example of the ID Token payload:¶
{ "iss": "https://server.example.com", "sub": "24400320", "aud": "s6BhdRkqt3", "nonce": "n-0S6_WzA2Mj", "exp": 1311281970, "iat": 1311280970, "cnf": { "jwk": { "alg":"ES256", "crv": "P-256", "kty": "EC", "x": "mjmFmLfopVi0et_a6fdXTNrjaU0GWedStcs_G588I20", "y": "l0VpEyRc7SuJ_tqawcZCeK-uT8EOVqx7sjLrFyBSRYY" } } }¶
To be completed.¶
Proof of possession authentication provides a greater level of security than bearer token authentication. To authenticate with a bearer token, the authentication secret must be sent over the internet to the authenticating party. This presents a risk that the authentication secret be stolen is transit or stolen at the server endpoint and replayed. With proof of possession, the authentication secret, i.e. the private key, never needs to leave the client. This reduces the chance of exposure and allows the client to use additional security mechanisms to protect the private key such as HSMs (Hardware Security Modules) or web browser based SSMs (Software Security Modules).¶
Public key bound ID Tokens provide a higher level security than bear ID Tokens by using proof of possession rather than bearer authentication. For this reason public key bound ID Tokens MUST NOT be accepted as a form of bearer token authentication.If bearer token authentication is desired, bearer ID Tokens should be used instead.¶
Within a closed ecosystem, the private key associated with a public key bound ID Token MAY be used to sign and authenticate the content of message. This use REQUIRES that the user's agent enforce secure domain separation via some other protocol between signatures on messages and proof of possession signatures on challenges. Domain separation is need to enforce that the user's signature on a proof of possession challenge message is not replayed in other contexts.¶
The content of such signed messages MUST NOT be treated as authenticated outside of that ecosystem.¶
No new registrations.¶
IANA JSON Web Token Claims Registry, available at https://www.iana.org/assignments/jwt/jwt.xhtml.¶
IANA OAuth Parameters, available at https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#client-metadata.¶
To be completed.¶
To be completed if adopted.¶
[[ To be removed from the final specification ]]¶
-00¶
initial draft¶