Free tool, runs in your browser
Decode and check a JWT, without it leaving your browser
Paste a JSON Web Token to read its header and claims, see when it expires, and get a plain-English warning if it is a Supabase service_role key, uses alg none or carries data it should not. Optionally verify the signature with your secret or public key.
Decoding happens in your browser.
Never paste a production token into a website you don't trust, including this one; rotate it if in doubt. This page makes no network requests with what you paste and does not store it: reload and it is gone.
Paste a token, or load the sample, to see what is inside.
A JWT is readable by anyone who has it
A JSON Web Token has three parts separated by dots: a header, a payload of claims and a signature. The header and payload are only base64url encoded, not encrypted. Anyone who holds the token can read every claim, which is exactly what this tool does.
The signature is what makes a token trustworthy. It proves the token was created by someone holding the signing key and has not been edited since. Decoding a token tells you nothing about whether it is genuine; only verifying the signature does, and your server must do that on every request.
| Claim | Meaning |
|---|---|
| iss | Issuer: who created the token |
| sub | Subject: usually the user ID |
| aud | Audience: which service should accept it |
| exp | Expiry time, in seconds since 1 January 1970 UTC |
| nbf | Not valid before this time |
| iat | When it was issued |
| jti | Unique token ID, useful for revocation |
Supabase keys: anon versus service_role
Supabase's legacy API keys are JWTs, which is why they decode here. The role claim tells you which one you have.
- role: anon is the public key. It is designed to be shipped in your frontend, and it is only safe when Row Level Security is enabled on every table with policies that limit what anonymous users can do.
- role: service_role bypasses Row Level Security completely. Anyone who has it can read, change or delete all of your data. It belongs only on a server. If you find it in client code, a public env variable, a mobile app or a git history, rotate it immediately.
- role: authenticated is a signed-in user's session token. Your policies decide what it can reach.
Mistakes this tool flags
- alg set to none: the token is unsigned. A server that accepts it lets anyone impersonate any user. Servers must only accept the algorithm they expect.
- HS256, HS384 or HS512 with a weak secret: the same secret signs and verifies, and a short one can be guessed offline from a single captured token.
- No exp claim, or a lifetime of months: a leaked token keeps working. Access tokens are usually kept to minutes or hours.
- Passwords, API keys, secrets or card numbers in the payload: all readable by anyone who holds the token.
- A header that carries its own key (jku, x5u or jwk): servers must never trust a key chosen by the token.
Decode a token in the terminal instead
If you would rather not paste a token into any website, you can read the payload locally. This decodes the middle part only and does not verify anything.
node -e 'console.log(Buffer.from(process.argv[1].split(".")[1], "base64url").toString())' "$TOKEN"Frequently asked questions
Is my token sent to your server?
No. Decoding and signature verification run entirely in your browser, using its built-in WebCrypto. The token, secret and key are not sent, stored or logged, and they are gone when you reload the page. Even so, do not paste a live production token into any website; use a test token or rotate afterwards.
Does decoding a token prove it is valid?
No. Anyone can create a token with any claims. Only verifying the signature with the right key shows it is genuine, and your server must also check exp, nbf, iss and aud.
Is it safe to have the Supabase anon key in my frontend?
Yes, it is designed for that, but only if Row Level Security is enabled on every table with correct policies. Without RLS, the anon key gives anyone read and write access to your tables.
Which algorithms can this tool verify?
HS256, HS384 and HS512 with a shared secret, and RS256/384/512, PS256/384/512 and ES256/384/512 with a public key as a PEM (SPKI format), a JWK or a JWKS. It picks the JWKS key whose kid matches the token header.
Why does my base64 secret fail to verify?
Some providers show the signing secret base64 encoded, others as plain text. Tick "Secret is base64 encoded" to decode it before verifying, or untick it to use the text as typed.
Can I decode an encrypted token?
No. An encrypted token (JWE) has five parts instead of three, and its contents cannot be read without the decryption key. The tool tells you when it sees one.