Turn raw SAML responses and requests into pretty XML — base64, DEFLATE, or a full redirect URL
base64(XML) in a form field, while the redirect binding sends base64url(DEFLATE(XML)) in the URL. To decode one, strip the URL wrapper if present, base64-decode, inflate if the bytes aren't XML yet, then pretty-print. The decoder below does all of it — paste any format and get readable XML plus issuer, NameID, audience, InResponseTo, and the NotBefore/NotOnOrAfter validity window, computed locally with pako. Nothing is uploaded.
| Binding | Transport | Encoding layers | Typical size |
|---|---|---|---|
| HTTP-POST | HTML form field | base64 (no compression) | a few KB of base64 |
| HTTP-Redirect | URL query parameter | DEFLATE → base64url → URL-encode | must fit in a URL (~8 KB browser limit) |
| HTTP-Artifact | URL or form | artifact reference only; XML fetched via back-channel | tiny |
Redirect's compression is why a decoded value can still look like binary garbage after base64 decoding — the DEFLATE stream has to be inflated first. POST payloads skip compression because they're not size-constrained.
| Field | What it must satisfy | Common failure |
|---|---|---|
Issuer | Exactly equals the IdP entity ID in your SP config | Trailing slash or http-vs-https mismatch |
Audience | Equals your SP entity ID | IdP metadata copied from another environment |
Recipient / Destination | Your ACS URL | Wrong host behind a proxy or load balancer |
InResponseTo | The ID of the AuthnRequest you sent (SP-initiated flow) | IdP-initiated login where SP expects a request |
NotBefore | ≤ now + allowed skew | IdP clock ahead; assertion "not yet valid" |
NotOnOrAfter | > now | Replay of an old capture; expired assertion |
StatusCode | …:status:Success | AuthnFailed, NoPassive, or requester/p responder codes |
Assertions are deliberately short-lived: 5 minutes of validity is the norm, and 5 minutes of clock-skew tolerance is the conventional fix on the SP side.
SAML 2.0 single sign-on moves an XML message between an identity provider (IdP) and your service provider (SP), but the XML never travels naked. Depending on the binding it's base64-encoded, DEFLATE-compressed, or both, and often the only artifact you can grab is the whole redirect URL. This tool unwraps all of those, prints the XML with indentation, and pulls out the fields that decide whether your login works. Decompression uses pako 2.1.0 (MIT/Zlib licensed, ~6,100 stars on GitHub, actively maintained), loaded from jsDelivr and run client-side.
Step one, if the paste is a URL, extract the SAMLResponse or SAMLRequest parameter and URL-decode it. Step two, normalize base64url characters (- and _) back to + and /, and pad. Step three, decode to bytes and sniff: if the first byte is < you have XML (POST binding). Otherwise inflate — first raw DEFLATE (redirect binding), then zlib-wrapped as a fallback, since some stacks emit it. Step four, pretty-print and extract fields.
Capture the value from your browser's devtools (Network tab, look for the POST to your ACS endpoint, then the SAMLResponse form field) or grab the entire IdP redirect URL. Paste either one and hit Decode. The chips load a known-good sample in each encoding so you can see every layer handled. The validity panel compares NotBefore and NotOnOrAfter against your own device clock and flags not-yet-valid, expired, or valid-within-window.
The redirect sample is a realistic 2,527-byte assertion. As a POST payload it becomes 3,372 characters of base64. Compressed for the redirect binding it drops to 706 bytes of DEFLATE — 27.9% of the original — which base64url-encodes to 942 characters in the URL. Decoding reverses all of that, and the fields tell the story: Issuer https://idp.example.com/saml/metadata, NameID [email protected] (emailAddress format), Audience https://app.example.com/metadata, InResponseTo id-9c8d7e6f. The window runs from NotBefore 11:59:00Z to NotOnOrAfter 12:05:00Z — a 6-minute validity window, issued at 12:00:00Z for 5 minutes of usable life. That's the standard SAML rhythm: short-lived by design, and the reason a few minutes of clock skew breaks logins.
It depends on the binding. A POST-binding SAMLResponse is base64 text: decode it and you have XML. A redirect-binding SAMLRequest or SAMLResponse was DEFLATE-compressed before encoding, so after base64 decoding the bytes you still need to inflate them. The decoder above handles both plus the plain-XML case automatically — paste the value, a whole redirect URL, or URL-encoded XML.
Both encodings exist. The HTTP-POST binding sends base64(XML) in a form field with no compression. The HTTP-Redirect binding puts the message in the query string, where size matters, so it sends base64url(DEFLATE(XML)) — raw DEFLATE with no zlib header, using - and _ in place of + and /. A decoder that only does base64 will show garbage for redirect messages; it needs an inflate step.
Start with the timestamps and audiences. NotBefore and NotOnOrAfter must bracket the current moment, allowing for clock skew between the identity provider and your server — 5 minutes is the conventional tolerance. Audience must equal your SP entity ID, Recipient and Destination must match your ACS URL, and InResponseTo must match the AuthnRequest ID you sent if you sent one. Mismatches in any of these are the most common causes of "invalid response" errors.
No. Decoding is just unpacking layers: base64, compression, XML. Signature verification means validating the ds:Signature block against the identity provider's X.509 certificate, checking the signed references, and the wrap-attack checks on the assertion. Always do that in your SAML library server-side; a decoder is for reading and debugging, never for making access decisions.
Assertions are typically valid for just 5 minutes. If the identity provider's clock is 3 minutes ahead of your server, a freshly issued assertion can look not-yet-valid on arrival. That's why every SAML stack has a skew setting — it widens the NotBefore/NotOnOrAfter window on both ends. A few minutes of tolerance is standard; more than 10 usually masks a real NTP problem you should fix instead.
The page decodes locally — nothing is uploaded, and there's no server call with your input. That said, a decoded response contains the NameID (often an email), group attributes, and session identifiers. If your organization treats tokens as sensitive, redact or use a test response. And never treat any pasted token as still-secret: assertions expire within minutes anyway.