Go look at any online JWT tool. Somewhere on the page there's a line telling you not to paste production tokens.
Nobody listens. The whole reason you opened the tool is that a token is broken, and the broken one is a real one. So you paste it, and now a live session token is sitting in some stranger's server logs.
I got annoyed enough about this to build the alternative. It's called TokenBench.
The rule I gave myself
Nothing you type ever leaves the page.
Not "we don't store it." Not "we delete it after 30 seconds." It never goes anywhere in the first place, because there's nothing on the other end to receive it.
Everything runs through WebCrypto in the browser. Decoding, signature verification, key parsing, token generation — all client-side. You can open devtools, sit on the Network tab, paste a token, and watch nothing happen.
Then close the tab. Still nothing.
That last part matters more than it sounds like it should, and I'll come back to it.
Two verdicts, not one
The thing that actually pushed me to build this wasn't privacy, it was a bad afternoon.
A token was failing. The tool I was using showed me a red banner. Red banner means bad signature, right? So I went and checked the signing key. Rotated it. Checked the deploy config. Checked whether staging and prod were sharing secrets.
The signature was fine. The token was expired.
Those are two completely different failures with two completely different fixes, and collapsing them into one red banner cost me an hour. So TokenBench always shows both rows separately:
- Signature: does it match the key you supplied
-
Time: is it inside its
exp/nbfwindow
A correctly signed, expired token is the single most common real-world state, and it should not look like a forgery.
Algorithm confusion, and refusing to help
If you hand TokenBench an HS256 token and a public key, it won't verify it. It stops and explains why.
Quick version: RS256 signs with a private key, verifies with a public one. The public key is public. If your server reads the algorithm out of the token's own header and dispatches on it, an attacker flips the header to HS256, signs the token using your public key's bytes as the HMAC secret, and your code cheerfully verifies a forgery using information anyone can download.
// don't
const header = JSON.parse(base64url.decode(token.split('.')[0]));
jwt.verify(token, publicKey, { algorithms: [header.alg] });
// do
jwt.verify(token, publicKey, { algorithms: ['RS256'] });
The algorithm is your decision, not the token's. A tool that quietly performs the confused operation is teaching the bug, so this one won't do it.
There's a generator too, which can deliberately emit tampered signatures and alg: none tokens - so you can point them at your own server and confirm it actually rejects them.
The part I got wrong
Original build had analytics. Not third-party - my own, first-party, and deliberately careful: counters only, hardcoded allowlist of event names, nothing token-derived could physically get into the payload. It held everything in memory and sent one small beacon when you closed the page, specifically so that pasting a token fired nothing.
I was pleased with that design. It was defensible.
Then I did a final pass before launch, sat on the Network tab, and watched the beacon go out.
The page says nothing is sent. Something was sent. Doesn't matter that it was harmless. The whole pitch is "don't trust me, check" - and the first person to actually check would find a claim that needed a footnote.
So it's gone. No analytics, no beacon, no cookies. I get page-view counts from my host's server logs like it's 2004, and the claim is now just true with no asterisk.
Weirdly this is the part I'd defend hardest. Privacy claims that need explaining aren't privacy claims, they're marketing.
What's in it
Four tools: decoder, validator, generator, secret key generator. All the JOSE algorithms - HS/RS/PS/ES 256/384/512 and EdDSA. Keys accepted as raw secrets, PEM (SPKI and PKCS#1), X.509 certs, JWK or JWKS. Bearer prefixes, line breaks, and URL-encoding get stripped for you because tokens never arrive clean.
There's security linting throughout: weak secrets, alg: none, missing exp, well-known tutorial secrets.
Works offline once loaded. Free, no signup.
tokenbench.dev — source at github.com/kalisada/tokenbench if you want to verify any of the above rather than take my word for it.
Happy to hear where it falls short.