JWTs in OAuth and OpenID Connect
Introduction
The article on JWT (JSON Web Token) in Wikipedia was incorrect, so on May 9, 2020, I corrected both the English and Japanese versions of the article (the difference between the revisions).
In the previous version of the article, JWT was described as “an internet standard for creating JSON-based access tokens.” However, JWT is a general-purpose data format that is not limited to any specific use case. Using JWT as the format for access tokens is merely one application of JWT. It is also important to note that the format of an access token is not necessarily JWT. (Reference: “Inclusion Relation among JWS, JWE, JWT, ID Token and Access Token”)
When learning OAuth and OpenID Connect without prior knowledge of JWT, it’s common to misunderstand that “JWT is a technology for access tokens” or “JWT is a technology for user authentication.” This is likely because the access token implementation of the authorization server beginners encountered happened to be JWT, or because ID tokens were the first JWT application they learned about.
In this article, I will introduce various use cases of JWT in the context of OAuth and OpenID Connect. As we expand our knowledge in these areas, we will also reaffirm that JWT is a general-purpose format that is not limited to specific use cases.
(The Japanese version of this article is available here.)
ID Token
There is a standard specification called OpenID Connect Core 1.0 (OIDC Core). This specification has existed since at least the early 2010s, and in October 2024, it was also approved as ISO/IEC 26131:2024.
In Section 2 of this specification, titled “ID Token,” the ID token is defined. As stated in the specification, “The ID Token is represented as a JSON Web Token (JWT),” the ID token is a type of JWT.
The specification for JWT is defined in the document RFC 7519: JSON Web Token (JWT), which was approved by the IETF (Internet Engineering Task Force).
JWT is a JWS (JSON Web Signature) or JWE (JSON Web Encryption) that meets certain conditions. The specifications for JWS and JWE are defined in RFC 7515: JSON Web Signature (JWS) and RFC 7516: JSON Web Encryption (JWE), respectively.
The diagram below, which is reproduced from the article “Inclusion Relation among JWS, JWE, JWT, ID Token and Access Token,” illustrates the relationship between JWS, JWE, JWT, and ID tokens.
ID Token Example:
eyJraWQiOiIxZTlnZGs3IiwiYWxnIjoiUlMyNTYifQ.ewogImlzcyI6ICJodHRwczovL3NlcnZlci5leGFtcGxlLmNvbSIsCiAic3ViIjogIjI0ODI4OTc2MTAwMSIsCiAiYXVkIjogInM2QmhkUmtxdDMiLAogIm5vbmNlIjogIm4tMFM2X1d6QTJNaiIsCiAiZXhwIjogMTMxMTI4MTk3MCwKICJpYXQiOiAxMzExMjgwOTcwLAogIm5hbWUiOiAiSmFuZSBEb2UiLAogImdpdmVuX25hbWUiOiAiSmFuZSIsCiAiZmFtaWx5X25hbWUiOiAiRG9lIiwKICJnZW5kZXIiOiAiZmVtYWxlIiwKICJiaXJ0aGRhdGUiOiAiMDAwMC0xMC0zMSIsCiAiZW1haWwiOiAiamFuZWRvZUBleGFtcGxlLmNvbSIsCiAicGljdHVyZSI6ICJodHRwOi8vZXhhbXBsZS5jb20vamFuZWRvZS9tZS5qcGciCn0.NTibBYW_ZoNHGm4ZrWCqYA9oJaxr1AVrJCze6FEcac4t_EOQiJFbD2nVEPkUXPuMshKjjTn7ESLIFUnfHq8UKTGibIC8uqrBgQAcUQFMeWeg-PkLvDTHk43Dn4_aNrxhmWwMNQfkjqx3wd2Fvta9j8yG2Qn790Gwb5psGcmBhqMJUUnFrGpyxQDhFIzzodmPokM7tnUxBNj-JuES_4CE-BvZICH4jKLp0TMu-WQsVst0ss-vY2RPdU1MzL59mq_eKk8Rv9XhxIr3WteA2ZlrgVyT0cwH3hlCnRUsLfHtIEb8k1Y_WaqKUu3DaKPxqRi6u0rN7RO2uZYPzC454xe-mg&state=af0ifjsldkj
{
"kid": "1e9gdk7",
"alg": "RS256"
}
{
"iss": "https://server.example.com",
"sub": "248289761001",
"aud": "s6BhdRkqt3",
"nonce": "n-0S6_WzA2Mj",
"exp": 1311281970,
"iat": 1311280970,
"name": "Jane Doe",
"given_name": "Jane",
"family_name": "Doe",
"gender": "female",
"birthdate": "0000-10-31",
"email": "janedoe@example.com",
"picture": "http://example.com/janedoe/me.jpg"
}
Related Information:
- [article] Understanding ID Token
Request Object
In Section 6 of OIDC Core, titled “Passing Request Parameters as JWTs,” a method for combining a set of authorization request parameters into a single JWT is defined. This JWT is referred to as the request object.
The request object defined in Section 6 of OIDC Core was later extracted into a separate specification, RFC 9101: The OAuth 2.0 Authorization Framework: JWT-Secured Authorization Request (JAR), with some breaking changes introduced.
By using the request object, multiple request parameters like the following:
are combined into a single JWT, which is then specified as the value of the request
request parameter.
Request Object Example:
eyJhbGciOiJSUzI1NiIsImtpZCI6ImsyYmRjIn0.ewogICAgImlzcyI6ICJzNkJoZFJrcXQzIiwKICAgICJhdWQiOiAiaHR0cHM6Ly9zZXJ2ZXIuZXhhbXBsZS5jb20iLAogICAgInJlc3BvbnNlX3R5cGUiOiAiY29kZSBpZF90b2tlbiIsCiAgICAiY2xpZW50X2lkIjogInM2QmhkUmtxdDMiLAogICAgInJlZGlyZWN0X3VyaSI6ICJodHRwczovL2NsaWVudC5leGFtcGxlLm9yZy9jYiIsCiAgICAic2NvcGUiOiAib3BlbmlkIiwKICAgICJzdGF0ZSI6ICJhZjBpZmpzbGRraiIsCiAgICAibm9uY2UiOiAibi0wUzZfV3pBMk1qIiwKICAgICJtYXhfYWdlIjogODY0MDAKfQ.Nsxa_18VUElVaPjqW_ToI1yrEJ67BgKb5xsuZRVqzGkfKrOIX7BCx0biSxYGmjK9KJPctH1OC0iQJwXu5YVY-vnW0_PLJb1C2HG-ztVzcnKZC2gE4i0vgQcpkUOCpW3SEYXnyWnKzuKzqSb1wAZALo5f89B_p6QA6j6JwBSRvdVsDPdulW8lKxGTbH82czCaQ50rLAg3EYLYaCb4ik4I1zGXE4fvim9FIMs8OCMmzwIB5S-ujFfzwFjoyuPEV4hJnoVUmXR_W9typPf846lGwA8h9G9oNTIuX8Ft2jfpnZdFmLg3_wr3Wa5q3a-lfbgF3S9H_8nN3j1i7tLR_5Nz-g
{
"alg": "RS256",
"kid": "k2bdc"
}
{
"iss": "s6BhdRkqt3",
"aud": "https://server.example.com",
"response_type": "code id_token",
"client_id": "s6BhdRkqt3",
"redirect_uri": "https://client.example.org/cb",
"scope": "openid",
"state": "af0ifjsldkj",
"nonce": "n-0S6_WzA2Mj",
"max_age": 86400
}
By using JWT, the authorization server can verify two important aspects: that the request parameters have not been tampered with during transmission from the client to the authorization server, and that the request indeed comes from the intended client. This characteristic is crucial for security, and the use of request objects is mandatory in API ecosystems worldwide, such as the UK’s Open Banking and Brazil’s Open Finance.
- Tamper Detection: If any data is altered, the JWT’s signature becomes invalid, allowing tampering to be detected.
- Non-repudiation: If the JWT’s signature is successfully verified using the signer’s public key, it proves that the JWT was signed with the signer’s private key. Since only the signer possesses the private key, it guarantees that the JWT was generated by that signer. From the opposite perspective, the signer cannot deny having created the JWT.
Related Information:
CIBA Request Object
The OpenID Connect Client Initiated Backchannel Authentication Flow — Core 1.0 (CIBA Core) specification defines a new flow that differs from the basic OAuth flows defined in RFC 6749: The OAuth 2.0 Authorization Framework.
The CIBA flow includes three modes: POLL mode, PING mode, and PUSH mode. In all of these modes, the CIBA flow begins by sending a backchannel authentication request to the backchannel authentication endpoint.
The backchannel authentication endpoint can receive the set of request parameters defined in Section 7.1 of CIBA Core, titled “Authentication Request.”
Then, in Section 7.1.1 of CIBA Core, titled “Signed Authentication Request,” a method is defined for combining those request parameters into a single JWT and sending it. Just as the request
request parameter is used to pass the request object to the authorization endpoint, the request
request parameter is also used when sending a JWT containing the set of request parameters for the backchannel authentication request.
Example of Backchannel Authentication Request with Request Object:
POST /bc-authorize HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
request=eyJraWQiOiJsdGFjZXNidyIsImFsZyI6IkVTMjU2In0.eyJpc3MiOiJz
NkJoZFJrcXQzIiwiYXVkIjoiaHR0cHM6Ly9zZXJ2ZXIuZXhhbXBsZS5jb20iLCJl
eHAiOjE1Mzc4MjAwODYsImlhdCI6MTUzNzgxOTQ4NiwibmJmIjoxNTM3ODE4ODg2
LCJqdGkiOiI0TFRDcUFDQzJFU0M1QldDbk4zajU4RW5BIiwic2NvcGUiOiJvcGVu
aWQgZW1haWwgZXhhbXBsZS1zY29wZSIsImNsaWVudF9ub3RpZmljYXRpb25fdG9r
ZW4iOiI4ZDY3ZGM3OC03ZmFhLTRkNDEtYWFiZC02NzcwN2IzNzQyNTUiLCJiaW5k
aW5nX21lc3NhZ2UiOiJXNFNDVCIsImxvZ2luX2hpbnRfdG9rZW4iOiJleUpyYVdR
aU9pSnNkR0ZqWlhOaWR5SXNJbUZzWnlJNklrVlRNalUySW4wLmV5SnpkV0pmYVdR
aU9uc2labTl5YldGMElqb2ljR2h2Ym1VaUxDSndhRzl1WlNJNklpc3hNek13TWpn
eE9EQXdOQ0o5ZlEuR1NxeEpzRmJJeW9qZGZNQkR2M01PeUFwbENWaVZrd1FXenRo
Q1d1dTlfZ25LSXFFQ1ppbHdBTnQxSGZJaDN4M0pGamFFcS01TVpfQjNxZWIxMU5B
dmcifQ.ELJvZ2RfBl05bq7nx7pXhagzL9R75mUwO-yZScB1aT3mp480fCQ5KjRVD
womMMjiMKUI4sx8VrPgAZuTfsNSvA&
client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3A
client-assertion-type%3Ajwt-bearer&
client_assertion=eyJraWQiOiJsdGFjZXNidyIsImFsZyI6IkVTMjU2In0.eyJ
pc3MiOiJzNkJoZFJrcXQzIiwic3ViIjoiczZCaGRSa3F0MyIsImF1ZCI6Imh0dHB
zOi8vc2VydmVyLmV4YW1wbGUuY29tIiwianRpIjoiY2NfMVhzc3NmLTJpOG8yZ1B
6SUprMSIsImlhdCI6MTUzNzgxOTQ4NiwiZXhwIjoxNTM3ODE5Nzc3fQ.PWb_VMzU
IbD_aaO5xYpygnAlhRIjzoc6kxg4NixDuD1DVpkKVSBbBweqgbDLV-awkDtuWnyF
yUpHqg83AUV5TA
CIBA Request Object Example:
eyJraWQiOiJsdGFjZXNidyIsImFsZyI6IkVTMjU2In0.eyJpc3MiOiJzNkJoZFJrcXQzIiwiYXVkIjoiaHR0cHM6Ly9zZXJ2ZXIuZXhhbXBsZS5jb20iLCJleHAiOjE1Mzc4MjAwODYsImlhdCI6MTUzNzgxOTQ4NiwibmJmIjoxNTM3ODE4ODg2LCJqdGkiOiI0TFRDcUFDQzJFU0M1QldDbk4zajU4RW5BIiwic2NvcGUiOiJvcGVuaWQgZW1haWwgZXhhbXBsZS1zY29wZSIsImNsaWVudF9ub3RpZmljYXRpb25fdG9rZW4iOiI4ZDY3ZGM3OC03ZmFhLTRkNDEtYWFiZC02NzcwN2IzNzQyNTUiLCJiaW5kaW5nX21lc3NhZ2UiOiJXNFNDVCIsImxvZ2luX2hpbnRfdG9rZW4iOiJleUpyYVdRaU9pSnNkR0ZqWlhOaWR5SXNJbUZzWnlJNklrVlRNalUySW4wLmV5SnpkV0pmYVdRaU9uc2labTl5YldGMElqb2ljR2h2Ym1VaUxDSndhRzl1WlNJNklpc3hNek13TWpneE9EQXdOQ0o5ZlEuR1NxeEpzRmJJeW9qZGZNQkR2M01PeUFwbENWaVZrd1FXenRoQ1d1dTlfZ25LSXFFQ1ppbHdBTnQxSGZJaDN4M0pGamFFcS01TVpfQjNxZWIxMU5BdmcifQ.ELJvZ2RfBl05bq7nx7pXhagzL9R75mUwO-yZScB1aT3mp480fCQ5KjRVDwomMMjiMKUI4sx8VrPgAZuTfsNSvA
{
"kid": "ltacesbw",
"alg": "ES256"
}
{
"iss": "s6BhdRkqt3",
"aud": "https://server.example.com",
"exp": 1537820086,
"iat": 1537819486,
"nbf": 1537818886,
"jti": "4LTCqACC2ESC5BWCnN3j58EnA",
"scope": "openid email example-scope",
"client_notification_token": "8d67dc78-7faa-4d41-aabd-67707b374255",
"binding_message": "W4SCT",
"login_hint_token": "eyJraWQiOiJsdGFjZXNidyIsImFsZyI6IkVTMjU2In0.eyJzdWJfaWQiOnsiZm9ybWF0IjoicGhvbmUiLCJwaG9uZSI6IisxMzMwMjgxODAwNCJ9fQ.GSqxJsFbIyojdfMBDv3MOyAplCViVkwQWzthCWuu9_gnKIqECZilwANt1HfIh3x3JFjaEq-5MZ_B3qeb11NAvg"
}
Related Information:
- [article] CIBA, explained by an implementer
JARM
Just as the set of authorization request parameters can be combined into a single JWT called the request object, there is also a standard specification for combining the set of authorization response parameters into a single JWT. This specification is called the JWT Secured Authorization Response Mode for OAuth 2.0 (JARM).
By using JARM, multiple sets of response parameters like the following:
HTTP/1.1 302 Found
Location: https://client.example.com/cb?
iss=https%3A%2F%2Faccounts.example.com&
code=PyyFaux2o7Q0YfXBU32jhw.5FXSQpvr8akv9CeRDSd0QA&
state=S8NJ7uqk5fY4EjNvP_G_FtyJu6pUsvH9jsYni9dMAJw
are combined into a single JWT, which is then returned as the value of the response
response parameter.
HTTP/1.1 302 Found
Location: https://client.example.com/cb?
response=eyJraWQiOiJsYWViIiwiYWxnIjoiRVMyNTYifQ.eyAgImlzcyI6ICJodHRwczovL2F
jY291bnRzLmV4YW1wbGUuY29tIiwgICJhdWQiOiAiczZCaGRSa3F0MyIsICAiZXhwIjogMTMxMT
I4MTk3MCwgICJjb2RlIjogIlB5eUZhdXgybzdRMFlmWEJVMzJqaHcuNUZYU1FwdnI4YWt2OUNlU
kRTZDBRQSIsICAic3RhdGUiOiAiUzhOSjd1cWs1Zlk0RWpOdlBfR19GdHlKdTZwVXN2SDlqc1lu
aTlkTUFKdyJ9.4VdtknVZ9zFYDVLagJpVBD436bjPMcSgOaPDPFgTEkNyCs2uIHYJ2XML6d2w1A
Usm5GBG77DBisZNhLWfug6dA
JARM Example:
eyJraWQiOiJsYWViIiwiYWxnIjoiRVMyNTYifQ.eyAgImlzcyI6ICJodHRwczovL2FjY291bnRzLmV4YW1wbGUuY29tIiwgICJhdWQiOiAiczZCaGRSa3F0MyIsICAiZXhwIjogMTMxMTI4MTk3MCwgICJjb2RlIjogIlB5eUZhdXgybzdRMFlmWEJVMzJqaHcuNUZYU1FwdnI4YWt2OUNlUkRTZDBRQSIsICAic3RhdGUiOiAiUzhOSjd1cWs1Zlk0RWpOdlBfR19GdHlKdTZwVXN2SDlqc1luaTlkTUFKdyJ9.4VdtknVZ9zFYDVLagJpVBD436bjPMcSgOaPDPFgTEkNyCs2uIHYJ2XML6d2w1AUsm5GBG77DBisZNhLWfug6dA
{
"kid": "laeb",
"alg": "ES256"
}
{
"iss": "https://accounts.example.com",
"aud": "s6BhdRkqt3",
"exp": 1311281970,
"code": "PyyFaux2o7Q0YfXBU32jhw.5FXSQpvr8akv9CeRDSd0QA",
"state": "S8NJ7uqk5fY4EjNvP_G_FtyJu6pUsvH9jsYni9dMAJw"
}
To request the authorization server to return the authorization response as a JWT, the response_mode=jwt
request parameter is added to the authorization request. For more details, please refer to the JARM specification.
Client Assertion
When the client type of an OAuth client application is “confidential,” client authentication is required at certain endpoints, such as the token endpoint.
There are several types of client authentication. In RFC 6749, the core specification of OAuth, methods for client authentication using a shared key (client secret) are defined, such as embedding it in the Authorization
HTTP header or passing it as a form parameter.
Additional methods for client authentication can be defined in separate specifications. Section 2.2 of RFC 7523: JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants specifies a method for client authentication using JWTs.
In this method, the necessary information for authentication is encapsulated in a JWT, which is then sent to the server as the value of the client_assertion
request parameter. This JWT is called a client assertion.
(NOTE: While the specification allows the token endpoint URL to be used as the value of the aud
claim in the client assertion, it is recommended to use the identifier of the authorization server instead for security reasons.)
Client Assertion Example:
eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6Ijd5TmhJSFZlYVBGSUJfMGstWXBpRkFUb21DTHB4SXYtZTJBQUZtQ1JCTEUifQ.eyJpc3MiOiJteV9jbGllbnQiLCJzdWIiOiJteV9jbGllbnQiLCJhdWQiOiJodHRwczovL2FzLmV4YW1wbGUuY29tIiwiaWF0IjoxNzMxODM3MzA4LCJleHAiOjE3MzE4NDA5MDgsImp0aSI6ImQzODdiMDk4LTlhNmQtNDFkMy1hNGY4LTJlNTM1NWE4ZGE1NiJ9.wOhun7XI2h6CZoWJ1ae7nwChvtwJ5DC6GLmEQWF6psrUWFW6ul2SmhO9s_pRdo-Ys-uQKlxipHXUrPWPLkJV-g
{
"typ": "JWT",
"alg": "ES256",
"kid": "7yNhIHVeaPFIB_0k-YpiFATomCLpxIv-e2AAFmCRBLE"
}
{
"iss": "my_client",
"sub": "my_client",
"aud": "https://as.example.com",
"iat": 1731837308,
"exp": 1731840908,
"jti": "d387b098-9a6d-41d3-a4f8-2e5355a8da56"
}
Related Information:
- [article] OAuth 2.0 Client Authentication
Client Attestation
In the context of verifiable credentials, a new client authentication method called OAuth 2.0 Attestation-Based Client Authentication has been proposed for performing wallet authentication.
This client authentication method involves specifying two HTTP headers: OAuth-Client-Attestation
and OAuth-Client-Attestation-PoP
. These headers respectively contain the Client Attestation JWT and the Client Attestation PoP JWT.
The following HTTP request is an example of a token request using this client authentication method.
POST /token HTTP/1.1
Host: as.example.com
Content-Type: application/x-www-form-urlencoded
OAuth-Client-Attestation: \
eyJ0eXAiOiJvYXV0aC1jbGllbnQtYXR0ZXN0YXRpb24rand0IiwiYWxnIjoiRVMyNTY\
iLCJraWQiOiJ6WDl4YkpxQnppTVdLNXZtalhIZ1pUbWlZMTZ4Zm5aeHpTRWEwR3FZNV\
9RIn0.eyJpc3MiOiJodHRwczovL2F0dGVzdGVyLmV4YW1wbGUuY29tIiwic3ViIjoid\
HJhY2syX2Z1bGwiLCJpYXQiOjE3MzIyNDY3NzYsImV4cCI6MTczMjMzMzE3NiwiY25m\
Ijp7Imp3ayI6eyJjcnYiOiJQLTI1NiIsImt0eSI6IkVDIiwieCI6IjFBbVZyNEdvSGR\
QZ2s0OExXZFMzVDltNm0xbVA0VlRjajl1c29TQm5DUWsiLCJ5IjoidGUtV0l1VUlxMn\
c4dFhtWHlkbEVYNHBlOWxOZS1QQmNvekE4bjd5OFhURSJ9fX0.vSHXknaA0tGNmK8Ij\
xedEemiRWvODu53sF8dv3cfId0UeggqTVCtLNgWlsqBDvJjp2WmztUV8Q_G2EtbuH2K\
TA
OAuth-Client-Attestation-PoP: \
eyJ0eXAiOiJvYXV0aC1jbGllbnQtYXR0ZXN0YXRpb24tcG9wK2p3dCIsImFsZyI6IkV\
TMjU2Iiwia2lkIjoiN3lOaElIVmVhUEZJQl8way1ZcGlGQVRvbUNMcHhJdi1lMkFBRm\
1DUkJMRSJ9.eyJpc3MiOiJ0cmFjazJfZnVsbCIsImlhdCI6MTczMjI0Njc3OCwiZXhw\
IjoxNzMyMzMzMTc4LCJqdGkiOiI3OTBOSElvQ3pmTnZYa2M4IiwiYXVkIjoiaHR0cHM\
6Ly90cmlhbC5hdXRobGV0ZS5uZXQifQ.8ej09ZnGub_74Sa4bGKlvbyuXXH5bR8v1bG\
ZlkYwcx1zceUDSijEIyN3Ia2ORRs0Yh0P2tsdFc88X6s5P0F9Qg
grant_type=authorization_code&
code=n0esc3NRze7LTCu7iYzS6a5acc3f0ogp4
Client Attestation JWT Example:
eyJ0eXAiOiJvYXV0aC1jbGllbnQtYXR0ZXN0YXRpb24rand0IiwiYWxnIjoiRVMyNTYiLCJraWQiOiJ6WDl4YkpxQnppTVdLNXZtalhIZ1pUbWlZMTZ4Zm5aeHpTRWEwR3FZNV9RIn0.eyJpc3MiOiJodHRwczovL2F0dGVzdGVyLmV4YW1wbGUuY29tIiwic3ViIjoidHJhY2syX2Z1bGwiLCJpYXQiOjE3MzIyNDY3NzYsImV4cCI6MTczMjMzMzE3NiwiY25mIjp7Imp3ayI6eyJjcnYiOiJQLTI1NiIsImt0eSI6IkVDIiwieCI6IjFBbVZyNEdvSGRQZ2s0OExXZFMzVDltNm0xbVA0VlRjajl1c29TQm5DUWsiLCJ5IjoidGUtV0l1VUlxMnc4dFhtWHlkbEVYNHBlOWxOZS1QQmNvekE4bjd5OFhURSJ9fX0.vSHXknaA0tGNmK8IjxedEemiRWvODu53sF8dv3cfId0UeggqTVCtLNgWlsqBDvJjp2WmztUV8Q_G2EtbuH2KTA
{
"typ": "oauth-client-attestation+jwt",
"alg": "ES256",
"kid": "zX9xbJqBziMWK5vmjXHgZTmiY16xfnZxzSEa0GqY5_Q"
}
{
"iss": "https://attester.example.com",
"sub": "track2_full",
"iat": 1732246776,
"exp": 1732333176,
"cnf": {
"jwk": {
"crv": "P-256",
"kty": "EC",
"x": "1AmVr4GoHdPgk48LWdS3T9m6m1mP4VTcj9usoSBnCQk",
"y": "te-WIuUIq2w8tXmXydlEX4pe9lNe-PBcozA8n7y8XTE"
}
}
}
Client Attestation PoP JWT Example:
eyJ0eXAiOiJvYXV0aC1jbGllbnQtYXR0ZXN0YXRpb24tcG9wK2p3dCIsImFsZyI6IkVTMjU2Iiwia2lkIjoiN3lOaElIVmVhUEZJQl8way1ZcGlGQVRvbUNMcHhJdi1lMkFBRm1DUkJMRSJ9.eyJpc3MiOiJ0cmFjazJfZnVsbCIsImlhdCI6MTczMjI0Njc3OCwiZXhwIjoxNzMyMzMzMTc4LCJqdGkiOiI3OTBOSElvQ3pmTnZYa2M4IiwiYXVkIjoiaHR0cHM6Ly90cmlhbC5hdXRobGV0ZS5uZXQifQ.8ej09ZnGub_74Sa4bGKlvbyuXXH5bR8v1bGZlkYwcx1zceUDSijEIyN3Ia2ORRs0Yh0P2tsdFc88X6s5P0F9Qg
{
"typ": "oauth-client-attestation-pop+jwt",
"alg": "ES256",
"kid": "7yNhIHVeaPFIB_0k-YpiFATomCLpxIv-e2AAFmCRBLE"
}
{
"iss": "track2_full",
"iat": 1732246778,
"exp": 1732333178,
"jti": "790NHIoCzfNvXkc8",
"aud": "https://trial.authlete.net"
}
NOTE: Our company’s product, Authlete 3.0 (announcement), supports OAuth 2.0 Attestation-Based Client Authentication (see: 4.5.2.2. Step 2: Client Attestation and Client Attestation PoP). However, there are still many open issues with the specification itself, and discussions surrounding its standardization remain fluid. As a result, the specification is subject to change.
DPoP Proof JWT
When using an access token, mechanisms exist to ensure that only legitimate client applications can use it. Client applications are required to provide proof that they are authorized to use the access token when making use of it. This mechanism ensures that even if a malicious actor steals the access token, the token alone cannot be used.
Such access tokens, tied to a legitimate client application, are called sender-constrained access tokens.
Section 3, Mutual-TLS Client Certificate-Bound Access Tokens, of RFC 8705: OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens (commonly referred to as MTLS) defines a method to bind an access token to the client certificate used in the mutual TLS connection between the client application and the authorization server during the access token issuance. Additionally, RFC 9449: OAuth 2.0 Demonstrating Proof of Possession (DPoP) defines a method to bind an access token to the public key of the client application.
When using DPoP, the client application must provide its public key to the server. The authorization server associates the provided public key with the access token, and the resource server verifies that the access token is bound to the public key. However, the servers do not blindly trust the public key presented by the client. Instead, they confirm that the client presenting the public key also holds the corresponding private key.
To achieve this verification, a JWT called the DPoP proof JWT is used. The client application must generate a DPoP proof JWT signed with its private key and present it to the servers. For more details on DPoP, refer to the article “Illustrated DPoP (OAuth Access Token Security Enhancement).”
Example of Token Request with DPoP proof JWT:
POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik\
VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR\
nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE\
QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIj\
oiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIiwia\
WF0IjoxNTYyMjYyNjE2fQ.2-GxA6T8lP4vfrg8v-FdWP0A0zdrj8igiMLvqRMUvwnQg\
4PtFLbdLXiOSsX0x7NVY-FNyJK70nfbV37xRZT3Lg
grant_type=authorization_code\
&client_id=s6BhdRkqt\
&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb\
&code_verifier=bEaL42izcC-o-xBk0K2vuJ6U-y1p9r_wW2dFWIWgjz-
DPop proof JWT Example:
eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6IkVDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCRnMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JEQSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIjoiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIiwiaWF0IjoxNTYyMjYyNjE2fQ.2-GxA6T8lP4vfrg8v-FdWP0A0zdrj8igiMLvqRMUvwnQg4PtFLbdLXiOSsX0x7NVY-FNyJK70nfbV37xRZT3Lg
{
"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
}
Related Information:
UserInfo Response
Section 5.3, UserInfo Endpoint, of OIDC Core defines the specifications for the UserInfo endpoint. When an access token with the openid
scope is presented to this endpoint, it returns user information in JSON format.
Example of UserInfo Request:
GET /userinfo HTTP/1.1
Host: server.example.com
Authorization: Bearer SlAV32hkKG
Example of UserInfo Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"sub": "248289761001",
"name": "Jane Doe",
"given_name": "Jane",
"family_name": "Doe",
"preferred_username": "j.doe",
"email": "janedoe@example.com",
"picture": "http://example.com/janedoe/me.jpg"
}
However, if the userinfo_signed_response_alg
metadata of the client application is configured with a signature algorithm, the data returned from the UserInfo endpoint will be in JWT format.
Even if the userinfo_signed_response_alg
metadata is not configured, if encryption algorithms are specified in the userinfo_encrypted_response_alg
and userinfo_encrypted_response_enc
metadata, the data returned from the UserInfo endpoint will also be in JWT format.
These metadata that begin with userinfo_
are defined in Section 2, Client Metadata, of OpenID Connect Dynamic Client Registration 1.0 (ISO/IEC 26133:2024).
Signed UserInfo Response Example:
eyJraWQiOiJzaHJySzFCS29WZ254aTlqdlVUWHRRbWlzeXpraXpoT29kQ05mYzhsMGR3IiwiYWxnIjoiRVMyNTYifQ.eyJpc3MiOiJodHRwczovL3RyaWFsLmF1dGhsZXRlLm5ldCIsInN1YiI6IjEwMDQiLCJhdWQiOlsidHJhY2syX2xpZ2h0Il0sImV4cCI6MTczMjAxNTExOCwiaWF0IjoxNzMxOTI4NzE4fQ.YbdfEMXeHMSLoouZcTHIWCfUJvHU3yfDUYdoqEkHwrO2xH9YRp-eW7K1Gekivk5HUS3ZWBCD30NNTKpXqNGHpw
{
"kid": "shrrK1BKoVgnxi9jvUTXtQmisyzkizhOodCNfc8l0dw",
"alg": "ES256"
}
{
"iss": "https://trial.authlete.net",
"sub": "1004",
"aud": [
"track2_light"
],
"exp": 1732015118,
"iat": 1731928718
}
Introspection Response
RFC 7662: OAuth 2.0 Token Introspection defines the specification for the introspection endpoint. When an access token or refresh token is presented to this endpoint, information about the token is returned in JSON format.
Example of Introspection Response:
{
"active": true,
"scope": "openid potential.track2.light.profile",
"client_id": "track2_light",
"token_type": "Bearer",
"exp": 1732014893,
"sub": "1004",
"aud": null,
"iss": "https://trial.authlete.net",
"auth_time": 1731928492
}
However, if the introspection endpoint is implemented to comply with the JWT Response for OAuth Token Introspection specification, the response format will be a JWT.
Example of Introspection Response with Signed Message Body:
HTTP/1.1 200 OK
Content-Type: application/token-introspection+jwt
eyJraWQiOiJ3RzZEIiwidHlwIjoidG9rZW4taW50cm9zcGVjdGlvbitqd3QiLCJhbGc
iOiJSUzI1NiJ9.eyJpc3MiOiJodHRwczovL2FzLmV4YW1wbGUuY29tLyIsImF1ZCI6I
mh0dHBzOi8vcnMuZXhhbXBsZS5jb20vcmVzb3VyY2UiLCJpYXQiOjE1MTQ3OTc4OTIs
InRva2VuX2ludHJvc3BlY3Rpb24iOnsiYWN0aXZlIjp0cnVlLCJpc3MiOiJodHRwczo
vL2FzLmV4YW1wbGUuY29tLyIsImF1ZCI6Imh0dHBzOi8vcnMuZXhhbXBsZS5jb20vcm
Vzb3VyY2UiLCJpYXQiOjE1MTQ3OTc4MjIsImV4cCI6MTUxNDc5Nzk0MiwiY2xpZW50X
2lkIjoicGFpQjJnb28wYSIsInNjb3BlIjoicmVhZCB3cml0ZSBkb2xwaGluIiwic3Vi
IjoiWjVPM3VwUEM4OFFyQWp4MDBkaXMiLCJiaXJ0aGRhdGUiOiIxOTgyLTAyLTAxIiw
iZ2l2ZW5fbmFtZSI6IkpvaG4iLCJmYW1pbHlfbmFtZSI6IkRvZSIsImp0aSI6InQxRm
9DQ2FaZDRYdjRPUkpVV1ZVZVRaZnNLaFczMENRQ3JXRERqd1h5NncifX0.przJMU5Gh
mNzvwtt1Sr-xa9xTkpiAg5IshbQsRiRVP_7eGR1GHYrNwQh84kxOkHCyje2g5WSRcYo
sGEVIiC-eoPJJ-qBwqwSlgx9JEeCDw2W5DjrblOI_N0Jvsq_dUeOyoWVMqlOydOBhKN
Y0smBrI4NZvEExucOm9WUJXMuJtvq1gBes-0go5j4TEv9sOP9uu81gqWTr_LOo6pgT0
tFFyZfWC4kbXPXiQ2YT6mxCiQRRNM-l9cBdF6Jx6IOrsfFhBuYdYQ_mlL19HgDDOFal
eyqmru6lKlASOsaE8dmLSeKcX91FbG79FKN8un24iwIDCbKT9xlUFl54xWVShNDFA
Signed Introspection Response Example:
eyJraWQiOiJ3RzZEIiwidHlwIjoidG9rZW4taW50cm9zcGVjdGlvbitqd3QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwczovL2FzLmV4YW1wbGUuY29tLyIsImF1ZCI6Imh0dHBzOi8vcnMuZXhhbXBsZS5jb20vcmVzb3VyY2UiLCJpYXQiOjE1MTQ3OTc4OTIsInRva2VuX2ludHJvc3BlY3Rpb24iOnsiYWN0aXZlIjp0cnVlLCJpc3MiOiJodHRwczovL2FzLmV4YW1wbGUuY29tLyIsImF1ZCI6Imh0dHBzOi8vcnMuZXhhbXBsZS5jb20vcmVzb3VyY2UiLCJpYXQiOjE1MTQ3OTc4MjIsImV4cCI6MTUxNDc5Nzk0MiwiY2xpZW50X2lkIjoicGFpQjJnb28wYSIsInNjb3BlIjoicmVhZCB3cml0ZSBkb2xwaGluIiwic3ViIjoiWjVPM3VwUEM4OFFyQWp4MDBkaXMiLCJiaXJ0aGRhdGUiOiIxOTgyLTAyLTAxIiwiZ2l2ZW5fbmFtZSI6IkpvaG4iLCJmYW1pbHlfbmFtZSI6IkRvZSIsImp0aSI6InQxRm9DQ2FaZDRYdjRPUkpVV1ZVZVRaZnNLaFczMENRQ3JXRERqd1h5NncifX0.przJMU5GhmNzvwtt1Sr-xa9xTkpiAg5IshbQsRiRVP_7eGR1GHYrNwQh84kxOkHCyje2g5WSRcYosGEVIiC-eoPJJ-qBwqwSlgx9JEeCDw2W5DjrblOI_N0Jvsq_dUeOyoWVMqlOydOBhKNY0smBrI4NZvEExucOm9WUJXMuJtvq1gBes-0go5j4TEv9sOP9uu81gqWTr_LOo6pgT0tFFyZfWC4kbXPXiQ2YT6mxCiQRRNM-l9cBdF6Jx6IOrsfFhBuYdYQ_mlL19HgDDOFaleyqmru6lKlASOsaE8dmLSeKcX91FbG79FKN8un24iwIDCbKT9xlUFl54xWVShNDFA
{
"kid": "wG6D",
"typ": "token-introspection+jwt",
"alg": "RS256"
}
{
"iss": "https://as.example.com/",
"aud": "https://rs.example.com/resource",
"iat": 1514797892,
"token_introspection": {
"active": true,
"iss": "https://as.example.com/",
"aud": "https://rs.example.com/resource",
"iat": 1514797822,
"exp": 1514797942,
"client_id": "paiB2goo0a",
"scope": "read write dolphin",
"sub": "Z5O3upPC88QrAjx00dis",
"birthdate": "1982-02-01",
"given_name": "John",
"family_name": "Doe",
"jti": "t1FoCCaZd4Xv4ORJUWVUeTZfsKhW30CQCrWDDjwXy6w"
}
}
The JWT Response for OAuth Token Introspection specification is not widely known, but it is one of the specifications that make up the FAPI 2.0 Message Signing.
Related Information:
- [article] OAuth Access Token Implementation
JWT Access Token
When choosing JWT as the implementation for access tokens, you can refer to RFC 9068: JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens. However, please be aware that this specification has the following issues.
- The
sub
claim is required. Typically, the value of thesub
claim serves as a unique identifier for the user who authorized the issuance of the access token. However, for access tokens issued under the Client Credentials Flow (RFC 6749, Section 4.4), no specific user is associated, and thus, a unique user identifier cannot be obtained. RFC 9068 states that, in this case, thesub
claim should contain the identifier of the client application. However, during the specification discussion, an opposing view was raised: “If the user identifier cannot be obtained, thesub
claim should be set to null." This opposition, however, was overruled due to some confusion among those involved in the discussion, with some mistakenly believing that thesub
claim is mandatory in the JWT specification (RFC 7519). As a result, thesub
claim was ultimately made required. (NOTE: Thesub
claim is “optional” in the JWT specification.) - The
aud
claim is required. This makes it impossible to issue an access token that does not have an audience restriction. Section 3 of RFC 9068, titled “Requesting a JWT Access Token,” discusses how to determine the value of theaud
claim. It suggests that if theresource
parameter is used (refer to RFC 8707: Resource Indicators for OAuth 2.0), the value specified should be used for theaud
claim. This is good. However, there is an issue with how the value of theaud
claim should be determined when theresource
parameter is not used. The requirement to infer the value ofaud
from thescope
parameter assumes a special relationship betweenscope
andaudience
, which is inappropriate (although some vendors’ implementations may do this). This requirement is also inconsistent with the intended behavior when theresource
parameter is omitted, that is, "if theresource
parameter is omitted, no resource restriction should be applied." - The
client_id
claim is required. This decision was correct during the specification drafting process. However, the introduction of the pre-authorized code flow in the OpenID for Verifiable Credential Issuance specification, where access tokens can be issued without including information to identify the client application (if thepre-authorized_grant_anonymous_access_supported
is set totrue
in the authorization server configuration), has created a situation where access tokens are issued without being tied to a specific client application. In such cases, the value of theclient_id
claim must necessarily benull
, as no client application is associated with the access token.
The specification was drafted despite various objections, so it cannot be assumed that the specification is widely supported. In fact, some individuals went as far as writing articles to express their opposition. Therefore, just because the access token format is JWT, it should not be assumed that the access token necessarily conforms to RFC 9068.
JWT Access Token Example:
eyJhbGciOiJQUzI1NiIsInR5cCI6ImF0K2p3dCIsImtpZCI6ImF1dGhsZXRlLWZhcGlkZXYtYXBpLTIwMTgwNTI0In0.eyJzY29wZSI6Im9wZW5pZCBmYXBpci1hY2NvdW50cyIsImNsaWVudF9pZCI6IjkwNTU1MDk2NzEiLCJleHAiOjE3Mjg5MDc4OTYsImlhdCI6MTcyODkwNjk5Niwic3ViIjoiMTAwMSIsImlzcyI6Imh0dHBzOi8vbmV4dHJldmlldy1hcy5hdXRobGV0ZS5uZXQvIiwianRpIjoiand3aUpVTHdKN2lxcHpsUFBsc240R1BYQ0FlOUJBc3o4bWwxWm9GdkNNWSIsImF1dGhfdGltZSI6MTcyODkwNjk5NiwiZ3JhbnRfdHlwZSI6ImF1dGhvcml6YXRpb25fY29kZSJ9.aUgqqjZSKUy2cjKeWiMLdqg-6ElfDYEo30Jlg4--gMZAJIXRpYsnRBbwxEt7H6QrGrTH5aSAqJkBvgNsN_ekPTNMCc-1HFS65PsSiL4cqXTFly3wPyqq1cDXky7mFKT8WkbmtL6OicLdMIepstID_2rkrEYjXTh8rl_oHnWrjY491iLhUdXWWkoQlrp4QWb3Zqwrthqrdb1ZVK2ybTicPiyhJrA206kFY3UQYSBN6tBT5_YpOTpqkATfVqFrsw9LJazEHrREmIuw-j8aYJ8i87rjkAWjMSTEg0E6t5XZyUgj5OjwlptrWqcm71aybPtH1JyuEp72zrnUNSHWVFdQnw
{
"alg": "PS256",
"typ": "at+jwt",
"kid": "authlete-fapidev-api-20180524"
}
{
"scope": "openid fapir-accounts",
"client_id": "9055509671",
"exp": 1728907896,
"iat": 1728906996,
"sub": "1001",
"iss": "https://nextreview-as.authlete.net/",
"jti": "jwwiJULwJ7iqpzlPPlsn4GPXCAe9BAsz8ml1ZoFvCMY",
"auth_time": 1728906996,
"grant_type": "authorization_code"
}
NOTE: RFC 9068 does not provide examples of JWT access tokens; the above is an example of a JWT access token issued by Authlete. You may notice that the payload does not include the aud
claim, which is required as a mandatory claim by RFC 9068.
Related Information:
- [article] OAuth Access Token Implementation
- [article] Inclusion Relation among JWS, JWE, JWT, ID Token and Access Token
JWT Authorization Grant
RFC 7523: JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants introduces the “JWT authorization grant” in Section 2.1. This flow differs from the basic OAuth 2.0 flows defined in RFC 6749: The OAuth 2.0 Authorization Framework.
The core idea behind the JWT authorization grant is to allow clients to obtain an access token by presenting a JWT at the token endpoint.
However, RFC 7523 does not specify who is responsible for generating the JWT. It in turn means that the specification does not define how to obtain the key used to verify the signature of that JWT. As a result, when using the JWT authorization grant, each implementation must establish its own rules, including at a minimum a rule for identifying the key required for signature verification.
This JWT authorization grant specification might be unfamiliar, but it is actually used in the Japanese construction industry.
Related Information:
- [article] JWT Authorization Grant (RFC 7523 2.1)
Token Exchange
RFC 8693: OAuth 2.0 Token Exchange defines a flow for exchanging one token for another.
This specification is highly abstract, so when implementing it, the details need to be determined. For example, one must decide what type of token to present as input and how to verify its validity.
To specify the type of token to present as input, request parameters such as subject_token_type
and actor_token_type
are defined. Additionally, to specify the type of token to request as output, a request parameter called requested_token_type
is defined. RFC 8693 defines several identifiers for these token types, and among them, urn:ietf:params:oauth:token-type:jwt
is the identifier used to indicate that the token type is JWT.
This token exchange specification might be unfamiliar, but it is actually used in the Japanese construction industry.
Related Information:
- [article] RFC 8693 OAuth 2.0 Token Exchange
Entity Statement
There is a specification called OpenID Federation 1.0, which is one of the most complex specifications in the industry.
This specification defines a mechanism for establishing a trust relationship based on a trust chain between an authorization server and a client application belonging to different networks. This mechanism enables OAuth/OIDC request-response exchanges between an authorization server and a client application without requiring the client application to be pre-registered with the authorization server.
Servers and clients that participate in the trust chain are called federation entities. Each federation entity publishes information about itself at the URL {its identifier}/.well-known/openid-federation
. This information is called the entity configuration, and its format is JWT.
Additionally, third-party organizations known as trust anchors or intermediate authorities assist in building the trust chain by issuing entity statements, which indicate that they authorize other federation entities. The format of the entity statement is also JWT. The entity configuration is considered a type of entity statement.
The following diagram illustrates the structure of a trust chain comprising multiple entity statements.
OpenID Federation 1.0 utilizes JWT in many other places as well. As of draft 41, the following JWT-based media types are defined:
application/entity-statement+jwt
application/trust-mark+jwt
application/resolve-response+jwt
application/trust-mark-delegation+jwt
application/jwk-set+jwt
application/explicit-registration-response+jwt
Entity Configuration Example:
- https://trial.authlete.net/.well-known/openid-federation (too large to paste the content here.)
OpenID Federation 1.0 is in practical use in Italy. Additionally, its adoption is spreading to other countries, such as Australia.
Related Information:
- [article] OpenID Federation 1.0
Software Statement
An authorization server that supports RFC 7591: OAuth 2.0 Dynamic Client Registration Protocol provides a Web API called Client Registration Endpoint. The endpoint accepts JSON including client metadata, registers the metadata into its database, and issues a client ID that corresponds to the registered metadata. The issued client ID can be used as a value for the client_id
request parameter of authorization requests, token requests and so on.
The mechanism for registering clients via a Web API is convenient, but allowing anyone to freely register a client poses a problem. Therefore, real-world systems implement various countermeasures. One such measure is to include a software statement issued by a central authority in the client registration request.
The format of the software statement is defined as a JWT in Section 2.3. Software Statement of RFC 7591. By verifying the validity of the software statement, the client registration endpoint can determine whether the client registration request is legitimate.
Software Statement Example:
eyJhbGciOiJSUzI1NiJ9.eyJzb2Z0d2FyZV9pZCI6IjROUkIxLTBYWkFCWkk5RTYtNVNNM1IiLCJjbGllbnRfbmFtZSI6IkV4YW1wbGUgU3RhdGVtZW50LWJhc2VkIENsaWVudCIsImNsaWVudF91cmkiOiJodHRwczovL2NsaWVudC5leGFtcGxlLm5ldC8ifQ.GHfL4QNIrQwL18BSRdE595T9jbzqa06R9BT8w409x9oIcKaZo_mt15riEXHazdISUvDIZhtiyNrSHQ8K4TvqWxH6uJgcmoodZdPwmWRIEYbQDLqPNxREtYn05X3AR7ia4FRjQ2ojZjk5fJqJdQ-JcfxyhK-P8BAWBd6I2LLA77IG32xtbhxYfHX7VhuU5ProJO8uvu3Ayv4XRhLZJY4yKfmyjiiKiPNe-Ia4SMy_d_QSWxskU5XIQl5Sa2YRPMbDRXttm2TfnZM1xx70DoYi8g6czz-CPGRi4SW_S2RKHIJfIjoI3zTJ0Y2oe0_EJAiXbL6OyF9S5tKxDXV8JIndSA
{
"alg": "RS256"
}
{
"software_id": "4NRB1-0XZABZI9E6-5SM3R",
"client_name": "Example Statement-based Client",
"client_uri": "https://client.example.net/"
}
Related Information:
- [article] Implementer’s note about Open Banking Brasil
- [software] OBBDCRProcessor.java, an example of processing the software statement for the Brazilian Open Finance.
SD-JWT
The specification “Selective Disclosure for JWTs” defines SD-JWT as a data format that enables selective disclosure. Although SD-JWT itself is not a JWT, part of its data structure utilizes JWT.
The specification “SD-JWT-based Verifiable Credentials (SD-JWT VC)” defines a verifiable credential format based on SD-JWT.
SD-JWT VC Example:
eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImRjK3NkLWp3dCJ9.eyJfc2QiOiBbIjBIWm1
uU0lQejMzN2tTV2U3QzM0bC0tODhnekppLWVCSjJWel9ISndBVGciLCAiOVpicGxDN1R
kRVc3cWFsNkJCWmxNdHFKZG1lRU9pWGV2ZEpsb1hWSmRSUSIsICJJMDBmY0ZVb0RYQ3V
jcDV5eTJ1anFQc3NEVkdhV05pVWxpTnpfYXdEMGdjIiwgIklFQllTSkdOaFhJbHJRbzU
4eWtYbTJaeDN5bGw5WmxUdFRvUG8xN1FRaVkiLCAiTGFpNklVNmQ3R1FhZ1hSN0F2R1R
yblhnU2xkM3o4RUlnX2Z2M2ZPWjFXZyIsICJodkRYaHdtR2NKUXNCQ0EyT3RqdUxBY3d
BTXBEc2FVMG5rb3ZjS09xV05FIiwgImlrdXVyOFE0azhxM1ZjeUE3ZEMtbU5qWkJrUmV
EVFUtQ0c0bmlURTdPVFUiLCAicXZ6TkxqMnZoOW80U0VYT2ZNaVlEdXZUeWtkc1dDTmc
wd1RkbHIwQUVJTSIsICJ3elcxNWJoQ2t2a3N4VnZ1SjhSRjN4aThpNjRsbjFqb183NkJ
DMm9hMXVnIiwgInpPZUJYaHh2SVM0WnptUWNMbHhLdUVBT0dHQnlqT3FhMXoySW9WeF9
ZRFEiXSwgImlzcyI6ICJodHRwczovL2V4YW1wbGUuY29tL2lzc3VlciIsICJpYXQiOiA
xNjgzMDAwMDAwLCAiZXhwIjogMTg4MzAwMDAwMCwgInZjdCI6ICJodHRwczovL2JtaS5
idW5kLmV4YW1wbGUvY3JlZGVudGlhbC9waWQvMS4wIiwgImFnZV9lcXVhbF9vcl9vdmV
yIjogeyJfc2QiOiBbIkZjOElfMDdMT2NnUHdyREpLUXlJR085N3dWc09wbE1Makh2UkM
0UjQtV2ciLCAiWEx0TGphZFVXYzl6Tl85aE1KUm9xeTQ2VXNDS2IxSXNoWnV1cVVGS1N
DQSIsICJhb0NDenNDN3A0cWhaSUFoX2lkUkNTQ2E2NDF1eWNuYzh6UGZOV3o4bngwIiw
gImYxLVAwQTJkS1dhdnYxdUZuTVgyQTctRVh4dmhveHY1YUhodUVJTi1XNjQiLCAiazV
oeTJyMDE4dnJzSmpvLVZqZDZnNnl0N0Fhb25Lb25uaXVKOXplbDNqbyIsICJxcDdaX0t
5MVlpcDBzWWdETzN6VnVnMk1GdVBOakh4a3NCRG5KWjRhSS1jIl19LCAiX3NkX2FsZyI
6ICJzaGEtMjU2IiwgImNuZiI6IHsiandrIjogeyJrdHkiOiAiRUMiLCAiY3J2IjogIlA
tMjU2IiwgIngiOiAiVENBRVIxOVp2dTNPSEY0ajRXNHZmU1ZvSElQMUlMaWxEbHM3dkN
lR2VtYyIsICJ5IjogIlp4amlXV2JaTVFHSFZXS1ZRNGhiU0lpcnNWZnVlY0NFNnQ0alQ
5RjJIWlEifX19.dwstJbebupjLSYtA3DGJBjcEDnHrftlVJeeIMwkOePBAcIOq5jC3qG
m-yRcXfvzHY6NQPLtwaIZC76V-p-gQeA~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3Iiw
gImdpdmVuX25hbWUiLCAiRXJpa2EiXQ~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwg
ImZhbWlseV9uYW1lIiwgIk11c3Rlcm1hbm4iXQ~WyI2SWo3dE0tYTVpVlBHYm9TNXRtd
lZBIiwgImJpcnRoZGF0ZSIsICIxOTYzLTA4LTEyIl0~WyJlSThaV205UW5LUHBOUGVOZ
W5IZGhRIiwgInNvdXJjZV9kb2N1bWVudF90eXBlIiwgImlkX2NhcmQiXQ~WyJRZ19PNj
R6cUF4ZTQxMmExMDhpcm9BIiwgInN0cmVldF9hZGRyZXNzIiwgIkhlaWRlc3RyYVx1MD
BkZmUgMTciXQ~WyJBSngtMDk1VlBycFR0TjRRTU9xUk9BIiwgImxvY2FsaXR5IiwgIkt
cdTAwZjZsbiJd~WyJQYzMzSk0yTGNoY1VfbEhnZ3ZfdWZRIiwgInBvc3RhbF9jb2RlIi
wgIjUxMTQ3Il0~WyJHMDJOU3JRZmpGWFE3SW8wOXN5YWpBIiwgImNvdW50cnkiLCAiRE
UiXQ~WyJsa2x4RjVqTVlsR1RQVW92TU5JdkNBIiwgImFkZHJlc3MiLCB7Il9zZCI6IFs
iWEZjN3pYUG03enpWZE15d20yRXVCZmxrYTVISHF2ZjhVcF9zek5HcXZpZyIsICJiZDF
FVnpnTm9wVWs0RVczX2VRMm4zX05VNGl1WE9IdjlYYkdITjNnMVRFIiwgImZfRlFZZ3Z
RV3Z5VnFObklYc0FSbE55ZTdZR3A4RTc3Z1JBamFxLXd2bnciLCAidjRra2JfcFAxamx
2VWJTanR5YzVicWNXeUEtaThYTHZoVllZN1pUMHRiMCJdfV0~WyJuUHVvUW5rUkZxM0J
JZUFtN0FuWEZBIiwgIm5hdGlvbmFsaXRpZXMiLCBbIkRFIl1d~WyI1YlBzMUlxdVpOYT
Boa2FGenp6Wk53IiwgImdlbmRlciIsICJmZW1hbGUiXQ~WyI1YTJXMF9OcmxFWnpmcW1
rXzdQcS13IiwgImJpcnRoX2ZhbWlseV9uYW1lIiwgIkdhYmxlciJd~WyJ5MXNWVTV3ZG
ZKYWhWZGd3UGdTN1JRIiwgImxvY2FsaXR5IiwgIkJlcmxpbiJd~WyJIYlE0WDhzclZXM
1FEeG5JSmRxeU9BIiwgInBsYWNlX29mX2JpcnRoIiwgeyJfc2QiOiBbIldwaEhvSUR5b
1diQXBEQzR6YnV3UjQweGwweExoRENfY3Y0dHNTNzFyRUEiXSwgImNvdW50cnkiOiAiR
EUifV0~WyJDOUdTb3VqdmlKcXVFZ1lmb2pDYjFBIiwgImFsc29fa25vd25fYXMiLCAiU
2Nod2VzdGVyIEFnbmVzIl0~WyJreDVrRjE3Vi14MEptd1V4OXZndnR3IiwgIjEyIiwgd
HJ1ZV0~WyJIM28xdXN3UDc2MEZpMnllR2RWQ0VRIiwgIjE0IiwgdHJ1ZV0~WyJPQktsV
FZsdkxnLUFkd3FZR2JQOFpBIiwgIjE2IiwgdHJ1ZV0~WyJNMEpiNTd0NDF1YnJrU3V5c
kRUM3hBIiwgIjE4IiwgdHJ1ZV0~WyJEc210S05ncFY0ZEFIcGpyY2Fvc0F3IiwgIjIxI
iwgdHJ1ZV0~WyJlSzVvNXBIZmd1cFBwbHRqMXFoQUp3IiwgIjY1IiwgZmFsc2Vd~
The header of the Issuer-signed JWT:
{
"alg": "ES256",
"typ": "dc+sd-jwt"
}
The payload of the Issuer-signed JWT:
{
"_sd": [
"0HZmnSIPz337kSWe7C34l--88gzJi-eBJ2Vz_HJwATg",
"9ZbplC7TdEW7qal6BBZlMtqJdmeEOiXevdJloXVJdRQ",
"I00fcFUoDXCucp5yy2ujqPssDVGaWNiUliNz_awD0gc",
"IEBYSJGNhXIlrQo58ykXm2Zx3yll9ZlTtToPo17QQiY",
"Lai6IU6d7GQagXR7AvGTrnXgSld3z8EIg_fv3fOZ1Wg",
"hvDXhwmGcJQsBCA2OtjuLAcwAMpDsaU0nkovcKOqWNE",
"ikuur8Q4k8q3VcyA7dC-mNjZBkReDTU-CG4niTE7OTU",
"qvzNLj2vh9o4SEXOfMiYDuvTykdsWCNg0wTdlr0AEIM",
"wzW15bhCkvksxVvuJ8RF3xi8i64ln1jo_76BC2oa1ug",
"zOeBXhxvIS4ZzmQcLlxKuEAOGGByjOqa1z2IoVx_YDQ"
],
"iss": "https://example.com/issuer",
"iat": 1683000000,
"exp": 1883000000,
"vct": "https://bmi.bund.example/credential/pid/1.0",
"age_equal_or_over": {
"_sd": [
"Fc8I_07LOcgPwrDJKQyIGO97wVsOplMLjHvRC4R4-Wg",
"XLtLjadUWc9zN_9hMJRoqy46UsCKb1IshZuuqUFKSCA",
"aoCCzsC7p4qhZIAh_idRCSCa641uycnc8zPfNWz8nx0",
"f1-P0A2dKWavv1uFnMX2A7-EXxvhoxv5aHhuEIN-W64",
"k5hy2r018vrsJjo-Vjd6g6yt7AaonKonniuJ9zel3jo",
"qp7Z_Ky1Yip0sYgDO3zVug2MFuPNjHxksBDnJZ4aI-c"
]
},
"_sd_alg": "sha-256",
"cnf": {
"jwk": {
"kty": "EC",
"crv": "P-256",
"x": "TCAER19Zvu3OHF4j4W4vfSVoHIP1ILilDls7vCeGemc",
"y": "ZxjiWWbZMQGHVWKVQ4hbSIirsVfuecCE6t4jT9F2HZQ"
}
}
}
The original payload before being converted to SD-JWT:
{
"vct": "https://bmi.bund.example/credential/pid/1.0",
"given_name": "Erika",
"family_name": "Mustermann",
"birthdate": "1963-08-12",
"source_document_type": "id_card",
"address": {
"street_address": "Heidestraße 17",
"locality": "Köln",
"postal_code": "51147",
"country": "DE"
},
"nationalities": [
"DE"
],
"gender": "female",
"birth_family_name": "Gabler",
"place_of_birth": {
"locality": "Berlin",
"country": "DE"
},
"also_known_as": "Schwester Agnes",
"age_equal_or_over": {
"12": true,
"14": true,
"16": true,
"18": true,
"21": true,
"65": false
}
}
Related Information:
- [article] OpenID for Verifiable Credential Issuance
- [article] Issuing verifiable credentials in the SD-JWT VC and mdoc/mDL formats, mandated in eIDAS 2.0
- [library] Java Library for SD-JWT
Key Proof JWT
To implement the mechanism of key binding, in a verifiable credential issuance request, the requester provides a public key to the verifiable credential issuer. The issuer embeds the received public key into the verifiable credential it issues.
However, the issuer should not blindly trust the received public key. It should verify whether the entity presenting the public key holds the corresponding private key. The verification method used for this is called key proof. The entity presenting the public key signs the data containing the public key with the corresponding private key, and provides this as a key proof to the verifiable credential issuer.
The specification OpenID for Verifiable Credential Issuance defines Key Proof JWT as the format for the Key Proof mechanism, based on JWT.
Key Proof JWT Example:
eyJ0eXAiOiJvcGVuaWQ0dmNpLXByb29mK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoiblVXQW9BdjNYWml0aDhFN2kxOU9kYXhPTFlGT3dNLVoyRXVNMDJUaXJUNCIsInkiOiJIc2tIVThCalVpMVU5WHFpN1N3bWo4Z3dBS18weGtjRGpFV183MVNvc0VZIn19.eyJhdWQiOiJodHRwczovL2NyZWRlbnRpYWwtaXNzdWVyLmV4YW1wbGUuY29tIiwiaWF0IjoxNzAxOTYwNDQ0LCJub25jZSI6IkxhclJHU2JtVVBZdFJZTzZCUTR5bjgifQ.-a3EDsxClUB4O3LeDD5DVGEnNMT01FCQW4P6-2-BNBqc_Zxf0Qw4CWayLEpqkAomlkLb9zioZoipdP-jvh1WlA
{
"typ": "openid4vci-proof+jwt",
"alg": "ES256",
"jwk": {
"kty": "EC",
"crv": "P-256",
"x": "nUWAoAv3XZith8E7i19OdaxOLYFOwM-Z2EuM02TirT4",
"y": "HskHU8BjUi1U9Xqi7Swmj8gwAK_0xkcDjEW_71SosEY"
}
}
{
"aud": "https://credential-issuer.example.com",
"iat": 1701960444,
"nonce": "LarRGSbmUPYtRYO6BQ4yn8"
}
Related Information:
Security Event Token
RFC 8417: Security Event Token (SET) defines a Security Event Token (SET), which is a type of JWT conforming to this specification. As stated in the specification, “A SET is a JWT.”
A SET represents events related to security or identity, such as:
- Password reset (Section 2.1.1. SCIM Example)
- Logout (Section 2.1.2. Logout Example)
- Consent (Section 2.1.3. Consent Example)
- Account deactivation (Section 2.1.4. RISC Example)
The specification that defines the mechanism for sending and receiving Security Event Tokens is OpenID Shared Signals Framework Specification 1.0 (SSF). SSF provides a profiling of SET, meaning it adds additional requirements. For example, a SET compliant with SSF must explicitly specify typ
as secevent+jwt
in the JWS header.
Below is the list of specifications related to Shared Signals.
- OpenID Shared Signals Framework Specification 1.0
- OpenID Continuous Access Evaluation Profile 1.0
- OpenID RISC Profile Specification 1.0
- RFC 8417: Security Event Token (SET)
- RFC 8935: Push-Based Security Event Token (SET) Delivery Using HTTP
- RFC 8936: Poll-Based Security Event Token (SET) Delivery Using HTTP
- RFC 9493: Subject Identifiers for Security Event Tokens
- IANA: Security Event Token (SET)
SET Example:
eyJ0eXAiOiJzZWNldmVudCtqd3QiLCJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJodHRwczovL2lkcC5leGFtcGxlLmNvbS8iLCJqdGkiOiI3NTZFNjk3MTc1NjUyMDY5NjQ2NTZFNzQ2OTY2Njk2NTcyIiwiaWF0IjoxNTIwMzY0MDE5LCJ0eG4iOjg2NzUzMDksImF1ZCI6IjYzNkM2OTY1NkU3NDVGNjk2NCIsInN1Yl9pZCI6eyJmb3JtYXQiOiJwaG9uZSIsInBob25lX251bWJlciI6IisxIDIwNiA1NTUgMDEyMyJ9LCJldmVudHMiOnsiaHR0cHM6Ly9zY2hlbWFzLm9wZW5pZC5uZXQvc2VjZXZlbnQvcmlzYy9ldmVudC10eXBlL2FjY291bnQtZGlzYWJsZWQiOnsicmVhc29uIjoiaGlqYWNraW5nIn19fQ.qV5HuFVpBkpSB1x0uOOPFATHd7fI02exAmpNz0wxuwQT-Gn9VYzqpuhRbyqlbA6Mmo87rvt9Bw2ucxr9LisV5g
{
"typ": "secevent+jwt",
"alg": "ES256"
}
{
"iss": "https://idp.example.com/",
"jti": "756E69717565206964656E746966696572",
"iat": 1520364019,
"txn": 8675309,
"aud": "636C69656E745F6964",
"sub_id": {
"format": "phone",
"phone_number": "+1 206 555 0123"
},
"events": {
"https://schemas.openid.net/secevent/risc/event-type/account-disabled": {
"reason": "hijacking"
}
}
}
Finally
We have explored various use cases of JWT within the OAuth and OpenID Connect domains. This highlights the versatility of JWT as a data format, not restricted to any specific purpose.
For more information and details about commercial offerings, please visit Authlete’s website!