paste by you - page memory only, never sent anywhere, never written to the URL · reload clears it
Keys this verifier trusts - the lab issuer keys (2 active keys) (configuration - folded by default)
The attacker set is shown so the kid tamper has a visible target. A real issuer never publishes another party's keys, and a pinned verifier never resolves keys by following the token (RFC 8725 sections 3.8 and 3.10). Private halves are published on purpose - these keys protect nothing.
the empty state is the proof: every entry is a key-set URL fetch or a note about local work - token bytes never appear.
RFC 9068 · JWT ACCESS TOKENS · THE RS CHECKLIST
The JWT inspector
Paste or mint a token and watch a resource server think: parse, header policy, key selection, a real WebCrypto signature check, and the claims policy - with six tamper buttons that teach both ways a token dies.
Most tools decode a JWT and call it verified. This console is the other end of the pipe: theresource server's verification, step by step. The signatures are genuine WebCrypto over real fixture keys, the checks are the ones RFC 9068 section 4 makes mandatory, and the six tamper buttons split into the only two classes that matter: tokens whose signature breaks, and tokens whose signature is fine but whose claims are not. The wire view records every fetch - the only kind of network call this page can make is a key-set URL fetch, and it never carries token bytes.
- Decoding is not verifying. Steps 01-02 you can do by eye; only step 04 needs the key, and only step 05 needs the key and the context (who issued this, which API is it for?).
- The verifier pins its algorithms and its keys. It never takes an
algfrom the header it is checking, and never followsjku/x5u- keys belong to the issuer you pinned, via discovery (RFC 8725 sections 3.1, 3.8, 3.10). alg=noneand the RS256-to-HS256 confusion are history, not folklore: both are quoted in RFC 8725, and the confusion shipped as CVE-2015-9235.- A valid signature proves the issuer vouched for these claims once - not that they still hold. Expiry and audience are the resource server's own checks, and skipping them serves stale and misrouted tokens all the same.
- Every failure ends the same way: the RS answers
401withWWW-Authenticate: Bearer error="invalid_token"(RFC 6750 section 3.1).
The console verifies against checked-in demo keys: one RSA-2048 and one P-256 keypair, published as a JWKS, plus a second "attacker" key set the kid tamper can name. Sample tokens are minted in your browser with liveiat/exp; an expired token and an alg=none token ship as static fixtures.
The private halves are published on purpose - these keys protect nothing. They are exhibits, the same standing as jwt.io's published sample secret: the lab is the one place where seeing the private key is the point.
- RFC 9068: JWT Profile for OAuth 2.0 Access Tokensthe REQUIRED claim set (section 2.2), the at+jwt typing, and the section 4 validation checklist the console runs
- RFC 8725: Best Current Practice for JWTs (JOSE)algorithm pinning, the alg=none and confusion attacks in its own words, audience validation, and the jku/x5u warning
- RFC 7519: JSON Web Token (JWT)the registered claims - iss, sub, aud, exp, nbf, iat, jti - and the duplicate-claim rule
- RFC 6750: Bearer Token Usagethe invalid_token error grammar every failure in the console ends with
- Critical vulnerabilities in JWT libraries (Auth0)the contemporary write-up of the algorithm-confusion family, including CVE-2015-9235
- The PKCE consolethe token it issues at step 06, opened up here - and the device console runs the other grant with its own tamper bench
- The ID-JAG validatorthe agent-auth lab-site's rule-by-rule console; its Mint tab opens this inspector with the minted grant loaded, and the RS checks here report it as what it is - a grant, not an access token