FIRST CH TOOLS / 24 JWT DECODER

JWT Decoder & Expiry Checker

Paste a JSON Web Token and its header and payload appear as formatted JSON, with the time left before exp drawn on a bar. The traps that cost the most debugging time — an expired token, a clock difference, alg: none, milliseconds used where seconds belong — are called out as you paste. Add the secret or public key and the signature is verified as well. Neither the token nor the key leaves this device.

JWT
Status
Time left
Algorithm
Signature

Header and payload as formatted JSON

Header — how it is signed
Paste a JWT above and the header appears here.
Payload — the claims
Paste a JWT above and the payload appears here.
Signature

Notes

How to Use

  1. Paste the tokenDrop the JWT in as it is. An Authorization: Bearer … header, surrounding quotes and line breaks inside the token are all stripped for you.
  2. Read the statusThe expiry status and the time left appear at the top. The bar shows where you are between issue (iat) and expiry (exp); the Claims tab explains each claim and turns the timestamps into dates.
  3. Check the signatureOn the "Verify signature" tab, enter the shared secret (HS256 and friends) or the public key (RS256 and friends) and the signature is verified on the spot. Decoding alone tells you nothing about tampering.

About This Tool

A JWT is three base64url segments — header, payload and signature — joined by dots. base64url is not encryption. Anyone holding the token can read what is inside, which is exactly why passwords, API keys and card numbers must never be put in a payload. This page takes advantage of that same property: it decodes everything locally, with no network request at all.

Decoding is not verification. Anybody can decode a token; proving it has not been altered since it was signed needs the key. The "Verify signature" tab uses the browser's built-in Web Crypto to check HS256/384/512 (shared secret), RS256/384/512, PS256/384/512, ES256/384/512 (public key) and EdDSA. The key you type stays on this device — but getting into the habit of pasting production private keys anywhere is itself the risk, so use test keys here.

exp is counted in seconds since 1 January 1970. JavaScript's Date.now() returns milliseconds, and forgetting to divide by 1000 is one of the most common JWT bugs there is — the token then expires tens of thousands of years from now. This page detects timestamps whose magnitude is wrong and says so. The opposite symptom, a token being rejected while it still looks valid, is usually a clock difference between machines; switch the tolerance (leeway) to see which side of the boundary you are on.

alg: none is the most famous JWT vulnerability there is. An attacker strips the signature, rewrites alg to none, and a library that trusts the header treats the token as needing no signature. The same family includes taking an RS256 token, changing it to HS256 and making the server use its public key as an HMAC secret. The rule is that the receiving side decides which algorithm it accepts: never trust the alg written in the token.

iss (issuer), aud (audience), exp, nbf, iat, sub and jti are the registered claims defined by RFC 7519. Skipping the aud check lets a token minted for one service be replayed against another that trusts the same key. The Claims tab also explains the OpenID Connect additions such as azp, nonce, auth_time and amr.

A string with five segments is a JWE — an encrypted token — and only its header can be read. Decrypting the body requires the recipient's private key, so this page cannot open it (if it could, the encryption would be pointless).

Nothing leaves the browser. The page can be called directly with URL parameters: /en/jwt/?token=eyJhbGciOi… or /en/jwt/?token=…&tab=claims. Be aware that putting a real token in a URL leaves it in browser history and anywhere the link is shared — keep this route for development tokens and automation.

From AI Agents

The same decoding, expiry checking and signature verification is available as the jwt_decode tool of the MCP (Model Context Protocol) server @first-ch/tools-mcp, so an AI agent can call it directly without driving a browser. See using these tools from AI agents for setup.

Install

claude mcp add firstch-tools -- npx -y @first-ch/tools-mcp

Examples

# Decode and check the expiry
jwt_decode(token="eyJhbGciOiJIUzI1NiJ9...")

# Verify the signature with a shared secret
jwt_decode(token="eyJ...", key="your-256-bit-secret")

# Verify with a public key (PEM / JWK / JWKS)
jwt_decode(token="eyJ...", key="-----BEGIN PUBLIC KEY-----\n...")

# Allow up to 60 seconds of clock skew
jwt_decode(token="eyJ...", clockTolerance=60)

Other Tools