Inspecting a token from your auth provider
Auth0, Firebase, Keycloak, AWS Cognito all return JWTs after login. Paste the access_token to see what claims your app is actually receiving — what's the user ID, what scopes, when does it expire?
Decode any JSON Web Token to see its header, payload, and signature — or sign a new one with HS256/384/512. Verifies HMAC signatures locally. 100% in your browser.
Decode any JSON Web Token to see its header, payload, and signature — or sign a new one with HS256/384/512. Verifies HMAC signatures locally. 100% in your browser.
No. The whole tool is JavaScript inside this page. Paste a token, decode happens in your browser, the bytes never leave the tab. Open DevTools → Network and watch — no requests are sent during decode or verify. That makes it safe to paste real customer or production tokens.
It proves the token was signed by someone holding the secret (HMAC) or the private key (RSA/ECDSA). It does NOT encrypt the payload — the header and payload are just base64url-encoded JSON, anyone with the token can read them. The signature only stops tampering: if you change a single byte of the payload, the signature no longer matches.
A JWT often carries the user ID, email, scopes, and sometimes session cookies' equivalent — exactly the data you must NOT paste into a stranger's server. iKit's decoder runs as JavaScript already loaded in your browser tab. Verifiable in DevTools → Network: no fetch, no XHR, no beacon during decode or verify.
For HS256/384/512 tokens, type the signing secret to verify the signature locally. For RS256/ES256 (RSA/ECDSA), use a server-side library — public-key verification needs a PEM file we don't accept here.
HS256 needs at least 32 bytes (256 bits) for true cryptographic strength. Anything works for testing, but production should use a long random secret.
The fastest way to debug a JWT — no upload, no signup, no third party between you and your token.
Paste a JWT, see the decoded header, payload, and signature side by side. Standard claims (iss, sub, aud, exp, iat) are timestamped and labelled.
For HS256/384/512 tokens, type the secret to verify the signature using the browser's Web Crypto API. The secret never leaves your tab.
Switch to Encode mode, edit the header and payload as JSON, choose the algorithm, type a secret, and get a signed token instantly.
JWT payloads contain user IDs, emails, sometimes scopes — never paste them into a server tool. iKit's decoder runs as JavaScript in your browser. Verifiable in DevTools → Network.
Standard claims like exp, nbf, iat are highlighted with human-readable dates and a clear EXPIRED / valid badge so you can tell at a glance whether the token is still good.
Built on the browser's native Web Crypto API and JSON parser — same algorithms as OpenSSL, libjwt, jose. The behaviour matches every modern JWT library.
A JWT is three base64url-encoded JSON segments separated by dots — that's it.
A JWT looks like aaa.bbb.ccc. We split on the two literal dots, giving the encoded header, payload, and signature. If we don't get exactly three parts, the token is malformed.
Header and payload are base64url-encoded UTF-8 JSON. Base64URL = Base64 with -/_ instead of +//= and no padding. We do atob after replacing characters back, then JSON.parse the resulting string.
Header tells us the algorithm (alg: HS256, RS256, etc.) and type. Payload contains the claims — standard ones (iss, sub, aud, exp, iat, nbf, jti) plus any custom fields. We display each in a labelled section.
For HS256/384/512, we re-compute the HMAC of header.payload using the secret you typed and compare to the signature in the third segment. Same as HMAC(SHA-256, secret, signing_input) base64url-encoded. Match = signature valid.
Real situations where you'll reach for a JWT decoder.
Auth0, Firebase, Keycloak, AWS Cognito all return JWTs after login. Paste the access_token to see what claims your app is actually receiving — what's the user ID, what scopes, when does it expire?
API rejecting your request? Decode the token to check: is it expired (exp in the past)? Is the audience claim (aud) what the API expects? Is the issuer (iss) the right tenant?
Stripe, GitHub Apps, Slack send webhook payloads signed as JWTs. After receiving one, paste it into Decode mode plus the shared secret to confirm the request actually came from them.
Need a fresh signed JWT for an integration test? Switch to Encode mode, edit the payload (custom user ID, custom expiry), pick HS256 + your test secret, get a token in milliseconds. No backend round-trip.
A JWT often carries the user ID, email, scopes, and sometimes session cookies' equivalent — exactly the data you must NOT paste into a stranger's server. iKit's decoder runs as JavaScript already loaded in your browser tab. Verifiable in DevTools → Network: no fetch, no XHR, no beacon during decode or verify.
Deep-dive tutorials and tool comparisons from the iKit blog.
JWT segments are base64url-encoded JSON — understand the encoding before you debug a token.
JWT signatures are HMAC-SHA hashes — the same family of cryptographic hashes used to verify file integrity.
No. The whole tool is JavaScript inside this page. Paste a token, decode happens in your browser, the bytes never leave the tab. Open DevTools → Network and watch — no requests are sent during decode or verify. That makes it safe to paste real customer or production tokens.
It proves the token was signed by someone holding the secret (HMAC) or the private key (RSA/ECDSA). It does NOT encrypt the payload — the header and payload are just base64url-encoded JSON, anyone with the token can read them. The signature only stops tampering: if you change a single byte of the payload, the signature no longer matches.
Three common causes: (1) wrong secret — JWT secrets are case-sensitive and any whitespace mismatch breaks verification. (2) Algorithm mismatch — the header says HS256 but the secret was used with HS512 originally. (3) Token was modified after signing — even one byte breaks the signature. Check the header.alg matches what you expect.
iKit currently supports HMAC verification (HS256/384/512) only. RS256 and ES256 use public-key cryptography — verification needs the issuer's public key in PEM format, which is a more involved UI. For now, decoding still works (the header/payload/signature parts display correctly), but the Verify button will tell you it's unsupported. RSA/ECDSA verification is planned.
Same idea, different defaults. iKit's decoder runs entirely in your browser (jwt.io does too, but iKit's code is open to view-source and our domain has no third-party trackers). We add a clear EXPIRED / valid badge for the exp claim, structured claim notes (iat / nbf / iss / sub / aud / jti as readable rows), and a copy-everything-decoded button that gives you the full structured output for paste into a bug report.