ID Token != JWT Access Token

Why can’t I just use ID Token instead of Access Token

--

I was encouraged to write this post because, I’ve seen many people who don’t really understand the conceptual differences between ID Tokens in OpenID Connect and JWT access tokens in OAuth2, and use both of them interchangeably.

The ID Token is a security token that contains claims about the authentication of an end-user by an authorization server when using a client, and potentially other requested claims. The ID Token is represented as a JSON Web Token (JWT) [1].

On the other hand a JWT access token is a kind of self-contained access token that can be issued by an OAuth2 authorization server based on the policies of the authorization server [2]. A JWT access token has the advantage of not having to store the entire token in the authorization server’s storage, reducing its storage requirements, and also doesn’t have to be validated against the authorization server for each resource access, reducing the network latency of the resource access.

Although both these tokens are JWT tokens, the audience and the purpose of the tokens are different.

The ‘aud’ attribute of the JWT specifies the audience that are intended to process the JWT. The audience of the ID Token is the OpenID Connect client, where as the audience of a JWT access token is the OAuth2 resource servers. Which means that the OpenID Connect client that receives the ID Token is not supposed to pass it to downstream services, and the OAuth2 client that receives the JWT access token is not meant to process it, but simply consider it as an opaque token and pass it along with calls to the resource server.

This raises two important questions.

  1. What if the OpenID Connect client passes the ID Token along with each resource access to downstream services?
  2. What if the OAuth2 client deliberately or inadvertently processes the JWT access token?

Before answering the questions, following are some implementations I have seen over time where the recommendations we’ve discussed above are violated.

  1. Using the ID Token to encode information that is meant for the OAuth2 resource server
  2. Using the JWT access token to encode information that is meant for the OAuth2 client
  3. Using the ID Token to encode information that is meant for the downstream services of the OAuth2 resource server
  4. Using the JWT access token to encode information that is meant for the downstream services of the OAuth2 resource server

Now to answer the questions, following are the negative outcomes not following the recommended practices.

  1. Using ID Token to encode information that is meant for both OpenID Connect client and OAuth2 resource server means that, in addition to the OpenID Connect client, now the OAuth2 resource server is also relying on the semantics and content of the ID Token, which introduces more coupling between the participants of the OpenID Connect flow.
  2. If the ID Token contains sensitive information that is intended to be used only by the OpenID Connect client, that information is going to be revealed to the OAuth2 resource server. As a solution to that, if you decide to encrypt the sensitive data in the JWT by using a shared secret between the OAuth2 authorization server and the OpenID Connect client, that will increase the resource requirements to decrypt that data in the OpenID Connect client.
  3. Using the JWT access token to encode information that is meant for the OAuth2 client means that, in addition to the resource server, now the OAuth2 client is also relying on the semantics and content of the JWT access token, which introduces more coupling between the participants of the OAuth2 flow.
  4. If the JWT access token contains sensitive information that is intended to be used only by the resource server, that information is going to be revealed to the OAuth2 client. As a solution to that, if you decide to encrypt the sensitive data in the JWT by using a shared secret between the OAuth2 authorization server and the OAuth2 resource server, that will increase the resource requirements to decrypt that data in the OAuth2 resource server.
  5. None of these tokens are meant to be directly passed on to the downstream services of the OAuth2 resource server as they can contain sensitive information to both OpenID Connect clients and OAuth2 resource servers. I have written a separate post on implementing a trusted subsystem solution pattern to address this requirement [3].

[1] http://openid.net/specs/openid-connect-core-1_0.html#IDToken

[2] https://tools.ietf.org/html/rfc6749#section-1.4

[3] https://medium.com/@johann_nallathamby/identity-propagation-in-a-gateway-architecture-e898b9eec5ca

--

--

Johann Dilantha Nallathamby
Johann Dilantha Nallathamby

Written by Johann Dilantha Nallathamby

IAM Enthusiast, Solutions Architect @ WSO2

No responses yet