Blog
Wild & Free Tools

How to Decode an AWS Cognito JWT: Claims, Groups, and Token Types

Last updated: April 2026 4 min read
Quick Answer

Table of Contents

  1. Cognito Token Types
  2. Decoded Cognito ID Token
  3. Reading Groups for Authorization
  4. Cognito Token Expiry
  5. Frequently Asked Questions

AWS Cognito issues ID tokens and access tokens as JWTs after authentication. Both can be decoded to inspect claims — paste either into the decoder above. The key difference is the token_use claim that tells you which one you are looking at.

Cognito ID Token vs Access Token

Cognito issues three tokens:

Distinguish them by the token_use claim in the decoded payload: "token_use": "id" or "token_use": "access".

What a Cognito ID Token Contains

{
  "sub": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "email_verified": true,
  "iss": "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_POOLID",
  "cognito:username": "janesmith",
  "cognito:groups": ["Admins", "Editors"],
  "aud": "YOUR-APP-CLIENT-ID",
  "token_use": "id",
  "auth_time": 1700000000,
  "exp": 1700003600,
  "iat": 1700000000,
  "email": "[email protected]",
  "custom:plan": "pro",
  "custom:org_id": "org_123"
}

Note the Cognito-specific claim naming: cognito:username and cognito:groups use the cognito: prefix. Custom attributes use the custom: prefix. The standard sub is the user's permanent UUID — use this as your primary user identifier, not the username which can change.

Sell Custom Apparel — We Handle Printing & Free Shipping

Using Cognito Groups for Role-Based Access

// JavaScript: check if user is in an admin group
const payload = decodeJwt(token);
const groups = payload['cognito:groups'] || [];

const isAdmin = groups.includes('Admins');
const isEditor = groups.includes('Editors');

// In an API handler (after verifying signature)
if (!isAdmin) {
  return res.status(403).json({ error: 'Admin access required' });
}

Cognito groups are baked into the token at sign-in. If you add a user to a group and they are already logged in, they will not see the new group until they sign in again or refresh their tokens.

The access token also includes cognito:groups, so you can use either token for group-based authorization.

Cognito Token Lifetimes

Default Cognito token expiry times (configurable in User Pool settings):

Decode your token and check exp to confirm the actual expiry configured for your User Pool. The Amplify SDK and Cognito Identity SDK handle token refresh automatically when using Auth.currentSession().

The issuer format is always https://cognito-idp.REGION.amazonaws.com/POOL_ID — verify this matches your User Pool region and ID if you see signature verification failures.

Decode Your Cognito Token Now

Paste your Cognito ID or access token above — see groups, custom attributes, token_use, and expiry instantly.

Open Free JWT Decoder

Frequently Asked Questions

How do I get my Cognito JWT in JavaScript?

With AWS Amplify: call Auth.currentSession() to get a CognitoUserSession, then session.getIdToken().getJwtToken() or session.getAccessToken().getJwtToken(). Without Amplify, use the amazon-cognito-identity-js library or standard OAuth2 flows.

Why is my Cognito custom attribute missing from the JWT?

Custom attributes must be added to the ID token via the User Pool app client settings. In the AWS console, go to User Pool > App clients > Edit > OpenID Connect scopes and make sure the attribute is mapped in the ID token.

What is the difference between sub and cognito:username?

sub is an immutable UUID assigned at account creation — it never changes. cognito:username is the user's login name which can sometimes change. Always use sub as your primary user key in your database.

Jake Morrison
Jake Morrison Security & Systems Engineer

Jake's conviction that files should never touch a third-party server is the foundation of WildandFree's zero-upload design.

More articles by Jake →
Launch Your Own Clothing Brand — No Inventory, No Risk