skip to Main Content

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


  1. "distributor": "Company A", // ctx.identity.claims[‘custom:distributor’]

    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:

    The ID token can contain OIDC standard claims that are defined in OIDC standard claims. The ID token can also contain custom attributes that you define in your user pool. Amazon Cognito writes custom attribute values to the ID token as strings regardless of attribute type.

    One question, why do you need the distributor field to be returned in your query if you already have it?

    Hope it helps.

    Login or Signup to reply.
  2. 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

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search