There is many topics in Access vs ID token and even the protocol documentation says
ID tokens should never be sent to an API. Access tokens should never be read by the client. Source
Now I’m having a very weird and wrong behavior using AppSync, I’m making the use in FE side of the Access Token, everything was working well so far until now. I checked the AppSync console and it was working as expected. The only difference, the console uses the ID token.
The issue is as follow:
query MyQuery {
Get {
buildVersion
distributor
user {
userID
firstName
lastName
}
}
}
// The resolver is a lambda and returns the following:
{
"Get": {
"buildVersion": 42666,
"distributor": "Company A", // ctx.identity.claims['custom:distributor']
"user": {
"userID": "xxxxx-yyyy-zzzzzzzz", // ctx.identity.sub
"firstName": "Hello",
"lastName": "World",
}
}
}
// Now the AWS AppSync console (with ID token) returns the same object
{
"data": {
"Get": {
"buildVersion": 42666,
"distributor": "Company A",
"user": {
"userID": "xxxxx-yyyy-zzzzzzzz",
"firstName": "Hello",
"lastName": "World",
}
}
}
}
// And the FE (with Access token) has an issue
{
"data": {
"Get": {
"buildVersion": 42666,
"distributor": null, // How come this is null???
"user": {
"userID": "xxxxx-yyyy-zzzzzzzz",
"firstName": "Hello",
"lastName": "World",
}
}
}
}
My first question is actually Why this is a thing? I mean okey, using ID token is not great but why not supporting it. Now why the results are different?
Extra note, I copied the two request as curl, executed them and got same as browser env. Then I reversed the tokens and this is really tied to the token; the query that was returning null with the Access token is returning the value with the ID token 🤦
The lambda is logged before returning, and this weird "filtering" is happening on AppSync side and there is no chaching neither any exotic config 😕
I dont really want to use ID token on my communication FE <> AppSync for the different reason that you can find around, so if there is something I miss, I would be happy to be highlighted on a solution 🙏
Thanks in advance 🙏
2
Answers
The quid here is it seems that access_token can’t contain custom claims (it wasn’t clear enough in documentation) -though it can contain custom scopes.
So "distributor" will be null in that case.
About ID tokens:
One question, why do you need the
distributor
field to be returned in your query if you already have it?Hope it helps.
The AppSync console uses the IdToken while Amplify uses the AccessToken by default. This has been confirmed on this GitHub issue.
This causes problems, because the available claims are different between these two tokens.
To still use the AccessToken on the frontend, you can use a Pre Token Generation Lambda to add you necessary claims to your AccessToken when it is being generated on the backend. See this great post on Medium for detailed information: Multi-Tenant AWS Amplify: Method 3: Virtual Cognito Groups