The debugging habit that leaks credentials
When an SSO flow fails, the instinct is to paste the failing token into the first online decoder that Google surfaces. That instinct is a data breach in miniature: a production JWT carries user claims, internal identifiers, and sometimes entitlements; a SAML assertion carries the full identity record your IdP asserted — attributes, groups, NameID. The decoder site receives all of it, logs an unknown fraction of it, and is operated by parties you have no contract with.
The fix is not "use a reputable decoder." The fix is structural: decode where the token already is — your browser. A JWT is three Base64URL segments; a SAML response is Base64 (often deflated) XML. Both parse with zero network I/O, which means a client-side decoder is not a convenience feature, it is the correct architecture.
Decoding a JWT: what to actually look for
Split the token on dots; base64url-decode the first two segments. The header declares the algorithm; the payload carries the claims. When debugging, check in this order:
- alg — is it what your backend expects? Mismatched algorithm expectations are the alg-confusion exploit's habitat. If the verifier only implements RS256 but honors a header claiming HS256 with the public key as the HMAC secret, an attacker forges tokens.
- exp / nbf / iat — expiry, not-before, issued-at, in epoch seconds. The classic failure: clock skew between issuer and verifier makes fresh tokens "not yet valid." The classic vulnerability: a verifier that decodes claims but never checks exp at all.
- iss / aud — issuer and audience. A token minted for service A accepted by service B is a token-reuse vulnerability; these two claims are the boundary.
- scope / roles / custom claims — where entitlement bugs live. Most authorization flaws are right here: a role claim that the backend trusts but the issuer never intended to be authoritative.
Decoding is safe anywhere. Verification needs the key and must happen where you trust the key — your backend for HS256's shared secret, or anywhere for RS256's public key. Never paste the secret into a web tool alongside the token; that combination is full forgery capability.
Decoding a SAML response: the flow, minus the upload
A SAML SSO POST carries the response as a Base64 SAMLResponse form field. To inspect it locally:
- Copy the field value from your browser's dev tools (Network tab → the login POST → form data).
- Base64-decode it. If the result is not XML, it was deflated — inflate it (raw DEFLATE, no zlib header) and XML appears.
- Pretty-print and read: the
<Subject>'s NameID (who logged in),<AttributeStatement>(groups, emails, entitlements),<Conditions>(NotBefore/NotOnOrAfter — skew failures live here), and the<Signature>element.
The assertions you inspect describe real employees and their group memberships. That is precisely the data that should never round-trip through a paste-bin with a decoder attached.
Why "offline" changes what you can safely debug
With client-side decoding, the blast radius of a debugging session is zero: you can inspect production tokens, expired tokens, tokens from pentests, and SAML responses from real IdPs, because nothing transmits. The moment decoding involves an upload, you start self-censoring — pasting only sanitized tokens — and the debugging quality drops. The privacy property and the engineering property point the same direction.
Try it — both tools run in your browser tab
The JWT Debugger decodes and verifies (HS256 secret or RS256 public key, locally via Web Crypto). The SAML Decoder handles the base64 and deflate variants and pretty-prints the XML. Both state the same guarantee in their network tab: nothing leaves the page.