ID Tokens

Background

Previously we discussed Logout and we will finish our discussion of SPA Session Management by describing the role of ID Tokens, which are designed to be ready by client applications rather than APIs.

ID Token Role

Before OpenID Connect, SAML was often used to secure websites. An ID token represents proof of the authentication event, in the same way as a SAML assertion. This blog’s AWS Cognito ID tokens contain these fields:

Receiving ID Tokens

The key OAuth Messages were summarized earlier. An authorization code is received in a front channel browser response, then sent in a back channel HTTPS POST to the token endpoint of the authorization server, to swap the code for tokens:

In 2021 it is recommended to avoid receiving ID tokens in browser responses, and receive all tokens on the back channel, in the authorization code grant response. This is ensured by running an authorization code flow with the following OpenID Connect parameter:

  • response_type=code

Since the ID token is received over a trusted HTTPS connection, ID token validation is less necessary than in older flows, where the ID token was received in the front channel response. It remains a good practice for the client to use a library that validates the ID token.

ID Tokens v Access Token v Refresh Token

After validation, SAML websites validated an assertion, then started a cookie based application session. An ID token can also be used in this way. In OAuth and OpenID Connect though, other tokens are also received.

The app no longer invents its own back end credential. Instead an access token contains business permissions and is sent to APIs. The session time is represented by the refresh token.

ID Token Access Token Refresh Token
Used At Client API Authorization Server
Used For Proof of Authentication API Message Credential Access Token Renewal
Lifetime Expiry Not Used Short Expiry Long Expiry
Silently Renewable No Yes Yes

The ID token must not be used as an API message credential. It is not designed to be received by APIs, and does not contain business permissions. These are expressed in the access token using scopes and claims, then used by the API to implement its business authorization.

ID Tokens and Privacy

Access and refresh formats can have various formats, though OpenID Connect mandates that ID tokens have the JWT format, since they must be readable by front end code. It is possible to also include personal details such as name and email in ID tokens, or other sensitive data.

It is safer to avoid personal data in ID tokens, which then sits around for the entire authenticated user session, so that there is more risk of sensitive data leaking unintentionally. This can result in a readable JWT being logged to the browser history or server logs.

The Logout blog post describes how an id_token_hint can be sent in a query parameter on the front channel. This is one way in which personal data in ID tokens can leak. Instead,  prefer my client applications to get OAuth personal data from the authorization server’s User Info endpoint.

ID Token Usage

When ID tokens contain only proof of the authentication event, they are rarely used by applications, and of far less significance than access tokens. This blog’s sample applications never use the ID token. It is a best practice to receive an ID token however, and let your app’s security library process it.

One of the main ways to use an ID token, is to take greater control over subsequent authorization code flows. One example is to read the max_age claim from the ID token, then send the ‘prompt=login‘ OpenID Connect parameter if a certain time period has passed, to force a new login.

Where Are We?

We understand the role of ID tokens, which provide verifiable proof of the authentication event to clients. All modern secured UIs should receive an ID token as part of using up to date security.

Next Steps