AWS Cognito Support

Validating Amazon Cognito JWT tokens correctly.

Cognito issues signed JSON Web Tokens, and your backend must verify them properly before trusting any claim. Many 401 errors and several security holes come from skipping a check or mixing up the ID token and the access token. We implement validation correctly and test it.

JWKSPublic keys per user pool
token_useid or access
iss and aud/client_idMust match your pool and client
expReject expired tokens

When You Need This

The situations where this work pays for itself.

Signs it is time

  • API returns 401 even though sign-in works
  • You are writing your own verification in a Lambda or service
  • You are not sure whether to send the ID token or the access token
  • A Cognito authorizer rejects tokens with the wrong scopes
  • You need to check groups, scopes or custom claims server-side

What you get

  • A validation module or authorizer config with tests
  • A table of which token goes to which API
  • Tests for expired, tampered and wrong-pool tokens
  • A note on token lifetimes and refresh handling

How we do it

A clear, safe process you can follow along with.

1. Decide which token goes where

The ID token carries identity claims for your app. The access token authorizes API calls and holds scopes and groups. We choose one per API and document it, because they have different claims for the audience.

2. Fetch and cache the signing keys

Each user pool publishes its public keys at https://cognito-idp.REGION.amazonaws.com/POOL_ID/.well-known/jwks.json. We select the key by the token header's kid, and cache the key set rather than fetching on every request.

3. Verify the signature and algorithm

We verify with the pool's RS256 key and reject any token using none or another algorithm. We prefer a maintained library such as aws-jwt-verify over hand-written code.

4. Verify claims

We check exp is in the future, iss equals the user pool's issuer URL, token_use matches what you expect, and the app client ID matches: aud on ID tokens and client_id on access tokens.

5. Authorize with scopes and groups

We use scope or cognito:groups claims for permissions, and never trust claims the client could set, such as custom attributes the user can write.

6. Use managed authorizers where they fit

API Gateway REST APIs have a Cognito user pool authorizer, and HTTP APIs have a JWT authorizer with issuer and audience. We configure and test both, including expired and wrong-client tokens.

Mistakes we help you avoid

Common ways this goes wrong, and what we do instead.

Decoding without verifying

Base64 decoding a JWT is not validation. Anyone can forge an unsigned payload.

Skipping the issuer or client check

Tokens from another pool or app would be accepted.

Sending the ID token to a resource server

Use the access token for API authorization.

Fetching JWKS on every request

It slows requests and can hit rate limits. Cache it.

Frequently Asked Questions

What is the difference between the ID token and the access token?

The ID token proves who the user is and carries profile claims. The access token grants access to APIs and carries scopes and groups.

Where do I find the Cognito public keys?

At the user pool's JWKS URL under .well-known/jwks.json for your Region and pool ID.

How do I revoke a Cognito token?

Refresh tokens can be revoked, and signing a user out globally invalidates them. Already-issued access tokens stay valid until they expire unless you add your own checks.

Want Help With Validating Amazon Cognito JWT tokens correctly?

Schedule an appointment. Tell us about your environment and we will outline the safest, highest-value approach.

Schedule Appointment › No commitment required