VibeSecurity

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.

ClaimMeaning
issIssuer: who created the token
subSubject: usually the user ID
audAudience: which service should accept it
expExpiry time, in seconds since 1 January 1970 UTC
nbfNot valid before this time
iatWhen it was issued
jtiUnique 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.

Terminal (needs Node.js)
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.

Sources

  1. 1.RFC 7519: JSON Web Token (JWT)
  2. 2.RFC 8725: JSON Web Token Best Current Practices
  3. 3.OWASP JSON Web Token Cheat Sheet
  4. 4.Supabase docs: Understanding API keys
  5. 5.Firebase docs: Verify ID tokens
  6. 6.MDN: SubtleCrypto.verify()