51

Just reading the docs, they seem very similar to me so I can't really discern why to use one over the other. Although identity token seems better since it has custom attributes on it from the user pool (eg: custom:blah and the default ones like name and email).

Right now, I am working with an app that passes the access token back down to the browser so it can use it for making ajax REST calls (there is an auth filter that expects this access token and validates it). Could I just switch out the access token with the id token? The current validation logic is to just get the sub field (the uuid) from the access token, but this sub field is also present in the identity token (as well as practically every other attribute except the aud which I don't need). I just want to make sure I am understanding this right as it is confusing to me why both tokens exist and seem so similar.

Zombies
  • 25,039
  • 43
  • 140
  • 225
  • 1
    There's a great article on the differences in general between Access and ID tokens here: [Auth0 - ID Token and Access Token: What's the Difference?](https://auth0.com/blog/id-token-access-token-what-is-the-difference/) – NiMux Jun 22 '22 at 14:57

3 Answers3

73

The id_token is for your application to process, so you can get all the personal details for your user, like their name, age, email address etc. Generally speaking you shouldn't send this token anywhere else as it contains sensitive user data.

The access_token is used to call other 'external' services (and by external I include other AWS services - these are often called over http). It provides service access authorisation for your user without having to include their personal details.

On the face of it this appears slightly confusing as you can actually use the id_token to access services in the same way as the access_token. However, good practise is to use the access_token in this circumstance and if backend services need user data, they should look it up themselves in Cognito.

EDIT: If you need to authenticate an api call based on claims in the identity token, there are circumstances when this is perfectly valid. But be aware of what details are in the identity token, and whether those claims are suitable to send to the particular API. If you don't need to use any claims from the id_token, use the access_token as this reduces the amount of potentially sensitive data you are sending.

F_SO_K
  • 13,640
  • 5
  • 54
  • 83
  • Thanks I understand the difference, questions is answered. But I do wonder now, should I not send back access/id tokens back to the browser (for it to make ajax rest calls) ? That is generally a bad practice? – Zombies Jan 31 '18 at 14:33
  • 2
    The weird thing is that in Amazon's conference presentations, they explain that they use the Id_token to retrieve credentials from IAM (despite having all 3)..on multiple occasions so I'm pretty sure it isn't a mistake. https://youtu.be/VZqG7HjT2AQ?t=9m50s This is the reason why I came looking at this question. – Michael Du May 11 '18 at 21:51
  • 13
    I ran into this as well. AWS explicitly state to use the ID token when calling an API endpoint when integrated with a user pool. https://docs.aws.amazon.com/en_pv/apigateway/latest/developerguide/apigateway-invoke-api-integrated-with-cognito-user-pool.html – Brennan Oct 01 '19 at 04:13
  • regarding "should look it up themselves in Cognito" - is it actually possible to look up everything one can get from and id token? specifically I'd like to look up the identity id for federated identities which I can get from the id token but not sure how to get it from the access token. – Andreas Mar 05 '20 at 18:31
  • 7
    i just tried testing my ApiGateway user pool authorizer via the aws UI. idToken.jwtToken works. accessToken.jwtToken does *not* work – stuart May 14 '20 at 23:54
  • 1
    @MichaelDu It is a mistake, or rather they have been too specific when they should have said 'whichever token you are going to verify'. This document asserts you can use either token https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-integrate-with-cognito.html – F_SO_K Mar 06 '21 at 09:46
  • @F_SO_K I think the reason they specifically state everywhere that you should use the ID token to make requests to resources is that the costume scopes feature for the access token is very limited in Cognito. You can't set them on a per user basis whereas you can easily add costume, per user scopes to the ID token trough the pre token generation trigger. This is a pretty key feature of OAuth2 and a very big limitation in the access token of the Cognito system. – Mercury Jul 23 '21 at 08:30
0

The thing that wasn't obvious from documentation for me about the difference:
If you are using pretoken trigger function and want to add additional information to the claims with claimsToAddOrOverride , you need to use an id token because this information doesn't exist in the access token. For ex:

event.response = {
  claimsOverrideDetails: {
    claimsToAddOrOverride: {
      'userProfileID': id,
    }
  },
}

I've expected it in the AppSync resolver with lambda function as source

Pavlo Naumenko
  • 561
  • 5
  • 15
0

Speaking about AWS User Pool tokens:

Identity token is used to authenticate users to your resource servers or server applications. For example, if you use Cognito as authorizer in AWS API Gateway you need to use Identity token to call API.

The purpose of the access token is to authorize API operations in the context of the user in the user pool. For example, you can use the access token to grant your user access to add, change, or delete user attributes.

The header for the access token has the same structure as the ID token. However, the key ID (kid) is different because different keys are used to sign ID tokens and access tokens.

a5zima
  • 84
  • 1
  • 6