Encoded Token

HEADERAlgorithm: RS256
{
  "kid": "abcdef0123456789",
  "alg": "RS256"
}
PAYLOADIssued: Oct 25, 2025, 08:00:00 · Expired
{
  "sub": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
  "cognito:groups": [
    "admin",
    "editors"
  ],
  "iss": "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_AbCdEfGhI",
  "client_id": "7m1234abcdefghijklmnopqrst",
  "origin_jti": "f5e6d7c8-b9a0-1234-5678-90abcdef1234",
  "event_id": "e1f2a3b4-c5d6-e7f8-a9b0-c1d2e3f4a5b6",
  "token_use": "access",
  "scope": "aws.cognito.signin.user.admin email openid profile",
  "auth_time": 1761379200,
  "exp": 1761465600,
  "iat": 1761379200,
  "jti": "j1k2l3m4-n5o6-p7q8-r9s0-t1u2v3w4x5y6",
  "username": "jdoe@example.com"
}
SIGNATUREPresent
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret
)

This tool decodes JWT tokens for inspection only. No signature verification is performed. Never trust unverified tokens in production.

Cognito Issues Three Token Types — Know Which One You Have

AWS Cognito user pools issue three distinct tokens at sign-in: an ID token (identity claims), an access token (API authorization), and a refresh token (opaque, used to renew the other two). The first two are JWTs; the refresh token is an opaque string. The decoder here works on either JWT — just paste it and inspect the claims.

The single most important claim to check first is token_use. It's either id or access. Confirm you're sending the right type to the right endpoint — Cognito's User Info endpoint requires the access token, while your app's authentication needs the ID token.

Cognito-Specific Claims

  • token_useid or access. Always confirm before passing the token to a downstream service.
  • iss — Format https://cognito-idp.<region>.amazonaws.com/<userPoolId>. The user pool ID is embedded — verify it matches your expected pool.
  • client_id (access token) — The Cognito app client that obtained the token. If you have multiple app clients (web + mobile + admin), each issues tokens with a different client_id.
  • aud (ID token only) — Equals the app client ID. Only present in ID tokens, not access tokens.
  • sub — The user's immutable UUID. Use this as the foreign key in your database, not username or email (both can change).
  • cognito:groups — Array of group names the user belongs to. Maps to your IAM roles via Cognito Identity Pools or custom logic.
  • cognito:username — The user's pool-level username. Often the email, but configurable per-pool.
  • scope (access token) — Space-separated list of OAuth scopes. aws.cognito.signin.user.admin grants self-service operations like password change.
  • auth_time — When the user actually authenticated. Distinct from iat, which is when the token was issued (could be after a refresh).
  • jti — Unique token ID. Stored in your database to allow per-token revocation.

Common Cognito Debugging Scenarios

"My API Gateway authorizer rejects the token." API Gateway by default validates token_use=access. If you're sending an ID token, the authorizer rejects it even though the signature is valid. Switch the client to send the access token instead.

"I can't see custom attributes." Cognito custom attributes appear with the custom: prefix (e.g., custom:tenant_id). They're only included in ID tokens by default. Access tokens require explicit configuration to include custom attributes (and only post-OAuth 2.0 token customization, available since 2024).

"cognito:groups is missing." The user isn't in any group. Confirm via Cognito Console → User Pools → Users → [User] → Groups, or by querying the AdminListGroupsForUser API.

Related Tools

Common Use Cases

Related Articles