Understanding the fundamentals of SAML 2.0: the XML protocol for enterprise SSO, the roles of IdP and SP, the HTTP Redirect and HTTP POST bindings, the SP-initiated and IdP-initiated flows, and the assertion structure for authentication, attributes, and authorization decisions.

In episode 11 you handled the session lifecycle: when the SSO session is created, how idle timeout and max timeout constrain it, and how single logout pulls all sessions at once. Episode 12 opens a new phase with SAML 2.0, the XML-based authentication protocol that has become the de facto standard in enterprise environments. You might ask, why learn a protocol that feels old in the OIDC era? Because tens of thousands of corporate applications — from HR portals and ERP to supply chain applications — only provide SAML integration. This episode plants the foundation so that the integrations in episodes 13 and 14 feel light.
SAML (Security Assertion Markup Language) 2.0 was standardized by OASIS in 2005 and remains the protocol of choice for federation in the corporate world. Three traits keep it going:
urn:oasis:names:tc:SAML:2.0:assertion is the official namespace for assertion elements. You will often see strings like this in metadata and request documents — a marker that the document follows SAML 2.0 rather than an earlier version.
Before diving into the components, it's important to see the comparison map with the OIDC you already master:
| Aspect | SAML 2.0 | OpenID Connect |
|---|---|---|
| Message format | XML (assertion, response) | JSON (JWT) |
| Primary transport | HTTP Redirect and HTTP POST | HTTP Redirect and JSON |
| Discovery | XML metadata (entity descriptor) | OpenID Configuration and JWKS |
| User identity | NameID in assertion | sub claim in ID token |
| Logout | SLO via redirect or SOAP | RP-initiated and back-channel logout |
| Fit | Enterprise and legacy applications | Modern applications, SPA, mobile |
The rule of thumb from episode 2 applies: choose OIDC for new applications you build yourself, choose SAML when the application being integrated — usually a vendor product — only supports SAML.
SAML works with two main roles and a number of connecting elements:
| Binding | Mechanism | Advantage | Drawback |
|---|---|---|---|
| HTTP Redirect | Message sent as a GET query parameter | Lightweight, suitable for AuthnRequest | Limited by URL length |
| HTTP POST | Message embedded in an auto-submitting HTML form | Can carry large documents | Slightly heavier |
| SOAP | Direct exchange between servers without a browser | Suitable for back-channel, e.g. SLO | Doesn't work behind NAT |
Most modern implementations use a combination: AuthnRequest over HTTP Redirect, Response over HTTP POST.
The most common flow: the user starts from the application. Here are the steps:
1. The user opens the application (SP) and clicks the login button
2. The SP builds an AuthnRequest and sends it to the IdP via HTTP Redirect
3. The IdP checks the session, asking for credentials if not yet logged in
4. The IdP builds a Response containing an Assertion and signs it
5. The browser sends the Response to the SP's ACS endpoint via HTTP POST
6. The SP validates the signature and builds a local sessionIn step 2, the SP fills the SAMLRequest parameter in the query string. When the IdP answers, it adds the RelayState parameter to carry state back — make sure you return it as-is.
The reverse of the flow above: the user opens the IdP portal first, chooses the target application, then the IdP sends an assertion without any AuthnRequest from the SP. Faster for the user, but less secure because the SP never verifies the origin of the request — an assertion can be forced without SP initiative.
Assertion creation happens at the IdP once the user is proven; validation happens at the SP: checking the signature, validity window, audience, and response status. If any of these fails, the assertion is rejected.
Tip
Remember the key phrase: SP-initiated starts from the application, IdP-initiated starts from the identity provider. When debugging, first identify who started the flow — most early confusion is rooted here.
The assertion is the heart of SAML. There are three kinds of statements it can carry:
An example of a simplified Response:
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
<saml:Issuer>https://keycloak.example.com/realms/demo</saml:Issuer>
<samlp:Status>
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
</samlp:Status>
<saml:Assertion>
<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">budi@example.com</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"/>
</saml:Subject>
<saml:AttributeStatement>
<saml:Attribute Name="email" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
<saml:AttributeValue>budi@example.com</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
</samlp:Response>Some elements you should recognize:
bearer is the most common for browser flows.In this episode 12, you got to know SAML 2.0 as an XML protocol for enterprise SSO: its fundamental differences from OIDC, the IdP, SP, assertion, and binding components; the SP-initiated and IdP-initiated flows; and how to read the assertion structure from issuer to attribute statement.
Key takeaways:
In the next episode (episode 13), you'll place Keycloak in the SAML IdP role: creating a SAML client, exporting metadata, configuring signing and encryption keys, choosing the NameID format, all the way to preparing the ACS and SLS endpoints.