How to Decode and Inspect JWT Tokens

If you've worked with APIs, OAuth, or any modern authentication system, you've likely encountered JWT tokens. They show up as long, opaque strings in Authorization headers, cookies, and URL parameters. But they're not actually opaque — they're designed to be readable.

This guide shows you how to crack one open and understand what's inside.

What Is a JWT?

A JSON Web Token (JWT), pronounced "jot", is a compact, URL-safe way to represent claims between two parties. It's commonly used for:

The Three Parts

Every JWT has three parts separated by dots:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkphbmUgRG9lIiwiaWF0IjoxNzA5MDAwMDAwLCJleHAiOjE3MDkwODY0MDB9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Split on the dots, these are:

Header eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Payload eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkphbmUgRG9lIiwiaWF0IjoxNzA5MDAwMDAwLCJleHAiOjE3MDkwODY0MDB9
Signature SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

The header and payload are Base64URL-encoded JSON. They're not encrypted — anyone can decode them. The signature proves the token hasn't been tampered with.

Decoding the Header

The header tells you the token type and signing algorithm:

{
  "alg": "HS256",
  "typ": "JWT"
}

Common algorithms include:

AlgorithmTypeDescription
HS256SymmetricHMAC with SHA-256. Uses a shared secret.
RS256AsymmetricRSA with SHA-256. Uses public/private key pair.
ES256AsymmetricECDSA with P-256. Smaller keys, same security.

Decoding the Payload

The payload contains the claims — the actual data the token carries:

{
  "sub": "1234567890",
  "name": "Jane Doe",
  "iat": 1709000000,
  "exp": 1709086400
}

Registered Claims

These are standard, reserved claim names defined in the JWT spec:

ClaimFull NameDescription
issIssuerWho created the token (e.g., your auth server)
subSubjectWho the token is about (e.g., user ID)
audAudienceIntended recipient (e.g., your API)
expExpirationUnix timestamp when the token expires
iatIssued AtUnix timestamp when the token was created
nbfNot BeforeToken is invalid before this time
jtiJWT IDUnique identifier for the token

Tip: The exp and iat claims are Unix timestamps (seconds since January 1, 1970). To check if a token is expired, compare exp against the current time. BoltKit's EpochTime tool can help you convert these quickly.

Custom Claims

Beyond the registered claims, you can include any custom data:

{
  "sub": "user_42",
  "role": "admin",
  "permissions": ["read", "write", "delete"],
  "org_id": "acme-corp",
  "exp": 1709086400
}

Custom claims are where JWTs get useful — embedding roles, permissions, and context directly in the token so your API doesn't need a database lookup on every request.

Decoding from the Command Line

You can decode a JWT with standard command-line tools. The payload is the second segment:

# Extract and decode the payload (macOS / Linux)
echo 'eyJzdWIiOiIxMjM0NTY3ODkwIn0' | base64 -d 2>/dev/null

# Full pipeline: extract payload, decode, pretty-print
echo 'YOUR.JWT.TOKEN' | cut -d'.' -f2 | base64 -d 2>/dev/null | jq .

Note: JWTs use Base64URL encoding (with - and _ instead of + and /, and no padding). Some base64 commands need the input padded or translated first. A dedicated tool handles this automatically.

The Signature

The third part is the signature, created by signing the header and payload with a secret or private key:

HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret
)

The signature guarantees that:

You cannot verify the signature without the secret key (for HMAC) or the public key (for RSA/ECDSA). Decoding only reveals the claims — it doesn't prove they're trustworthy.

Security Considerations

JWTs are not encrypted by default. Anyone who intercepts a JWT can read its contents. Never put sensitive data (passwords, credit card numbers, PII) in the payload. JWTs provide integrity (tamper-proof), not confidentiality (secret).

When to Use JWTs

JWTs work well for:

JWTs are a poor fit when you need immediate revocation (like banning a user). Since JWTs are self-contained and stateless, the server can't invalidate one without maintaining a blocklist — which defeats the purpose. For those cases, consider opaque tokens with server-side sessions.

Inspect JWTs Instantly

BoltKit's JWTInspect tool decodes any JWT token on your device — showing the header, payload, claims, algorithm, and expiry status at a glance. No data ever leaves your phone.

Get BoltKit Free