AWS Cognito Finally Supports Custom Claims for Access Tokens

5 minute read
Content level: Intermediate
0

A new, long-awaited feature that makes possible to customize access tokens

A very long-awaited Amazon Cognito feature was released a few months ago (December 2023): as per the title, Cognito now supports customisation of access tokens via a Lambda trigger! Pre token generation Lambda trigger

Wait a minute. Why is this important, and why are people literally rejoicing over it?

A bit of history

Amazon Cognito has been praised for its cost effectiveness and its seamless integration with other AWS services, mostly the Serverless ones such as API Gateway and Lambda.

On the other hand, it seems like AWS has neglected the Cognito product, based on the overall social media reaction to the release and its document history without any significant updates: Document history for Amazon Cognito

An example of a desperate user, including myself, who asked or watched for GitHub pull requests almost four years ago is shown below:

Enter image description here

Modify AccessToken via cognito trigger · Issue #4015 · aws-amplify/amplify-js

So you get the idea of how much this release means for the cloud community, even though probably some gave up and switched to different IDPs.

Why access token custom claims matter

Let’s look at some (not exhaustive) examples of why one would add custom claims to an access token:

  • Internal compliance. Sometimes companies define own standards to incorporate additional authentication and/or application factors or security-related information as part of access tokens.

    {
      "company_id": "your_company_id",
      "compliance_level": "high"
    }
  • Localization. Custom claims can include language or regional preferences, allowing your global application to tailor functionality based on the user’s preferred language or location.
    {
      "country_id": "uk"
    }
  • Fine-Grained Authorization. Augment tokens with specific permissions or attributes, providing a more specific and secure approach to controlling access to resources based on a company's security posture and app requirements.
    {
      "roles": {
        "owner": {
          "document_permission": "full_control"
        },
        "contributor": {
          "document_permission": "edit"
        }
      }
    }
  • Integration with external clients/systems. For seamless integration with external systems or services, these claims can provide the information required by third-party components in a standardized manner.
    {
      "external_partner_id": "your_partner_id"
    }

Do not use Identity tokens for API calls

Up until now, the lambda trigger allowed the customisation of an identity or ID token. Despite this possibility, using identity tokens as a means of authorisation flow when calling an API is a very bad idea.

ID tokens contain personal user information (name, family name, email, etc..) that prove that user is authenticated, meaning they verify the identity of the user. Using the ID token

Access tokens are designed to authorize users by granting access to specific resources or performing actions on behalf of the user through scope claims. Using the access token

By using ID tokens as bearer tokens in an API call, an attacker may get access to personal identifiable information (PII) and rely on a token which does not have an authorisation purpose.

According to the OpenID Connect specification, the id token’s audience (claim aud) must match the client_id of the client that initiated the authentication request.

Unless you have control over both the client and the API, transmitting an ID token poses a security risk.

This release will greatly reduce security concerns and push anybody using ID tokens with custom claims, to switch over access token ones, if used in the context of API authorisation.

The release

Please find the full article below for more information. Pre token generation Lambda trigger

Biggest facts:

  • It is based on the pre-generate token Lambda trigger, so additional costs (invocation) apply.

  • It’s not free, as available only on Cognito advanced security tier. Pricing | Amazon Cognito | Amazon Web Services (AWS)

  • Choose User pool trigger version of V2_0 to send specific event to the lambda

  • Not all claims can be overriden

  • You can add, edit or suppress claims and scopes

  • IAM group configuration can be overriden

An example can be seen below (version 1)

const handler = async (event) => {
  event.response = {
    claimsOverrideDetails: {
      claimsToAddOrOverride: {
        country_id: "uk",
        external_partner_id: "your_partner_id"
      },
      claimsToSuppress: ["email"]
    },
  };

  return event;
};

export { handler };

While version 2 should look like this:

const handler = async (event) => {
  event.response = {
        claimsAndScopeOverrideDetails: {
            accessTokenGeneration: {
                claimsToAddOrOverride: {
                    country_id: "uk",
                    external_partner_id: "your_partner_id"
                },
                claimsToSuppress: ["email", "string"]
            }
        }
  }

  return event;
};

export { handler };

Conclusion

I welcome this release, and while Iam looking forward to try it out, my main concern remains: does AWS believe in this product and eventually invest more in it?

Do they have any plan within the IDP space or Cognito is gonna be the real antagonist of other more established IDPs such as AzureAD?

Time will tell.

profile picture
EXPERT
published 2 months ago2085 views