Blog
IAM Chapter 4: SAML 2.0 & SSO

On this page
Part of the IAM study series.
Chapter 2 introduced the IdP sending apps "a signed statement." This chapter opens that statement up. It's a SAML assertion, and the ladder behind it runs: separate logins β centralized login β SSO β a standard format (SAML) β OAuth/OIDC, which is next.
The Separate-Login Problem
Without a standard, every one of Skyline's 200 apps handles authentication itself β its own user database, its own password rules. That means 200 passwords to remember (or reuse, and then breach), and 200 places to disable a leaver, which in practice means orphan accounts everywhere. The fix is sending everyone to one IdP (Entra ID). One disable action, every app locked.
SSO is covered in Chapter 2. The piece that makes it portable across 200 vendors is a standard format for the signed statement β otherwise every app vendor writes one integration per IdP, and ServiceNow serving 1,000 customers on 1,000 different IdPs needs 1,000 custom integrations. With a standard, ServiceNow implements it once, and any IdP that speaks the same standard just works. Like electrical plugs: one standard socket, any appliance plugs in.
What SAML Is
SAML (Security Assertion Markup Language) is that open XML standard β it defines the signed statement format and the login exchange steps. Published by OASIS, version 2.0 since 2005. It defines three things:
| Part | What it is | Plain words |
|---|---|---|
| Assertion | the signed statement about the user | the notarized letter |
| Protocol | the request-and-response messages | the question and answer |
| Binding | how messages travel (browser redirects, form posts) | the delivery method |
Mature, 20 years, huge app support β and verbose, fiddly XML.
The Assertion: A Notarized Letter
The analogy: Entra ID is the notary, John is the one carrying the letter, PLM is the bank. The assertion is the stamped, signed letter; the digital signature is the wax seal. Three pages inside the envelope:
| Page | Contains | Example |
|---|---|---|
| WHO | the subject the assertion is about | jwick@skyline.com |
| WHEN / HOW | the authentication statement β when checked, how long valid, who may accept it | checked 9:01, expires 9:06, audience PLM only |
| WHAT | attributes the app may need | dept Engineering, role Designer |
On the outside, the digital signature β the wax seal β is what PLM checks against the certificate from the trust setup.
SP-Initiated Flow (the app starts it)
SP-initiated means the login starts at the app (the Service Provider). John opens PLM, and PLM sends him to the IdP.
- John's browser hits
plm.skyline.com. PLM has no session for him today. - PLM generates a SAML Request with a unique ID β say
REQ-7742β meaning "Entra ID, authenticate this user and send them back." - PLM redirects John's browser to Entra ID, carrying that request.
- Entra ID checks John's session cookie. He logged in at 8:55 β no password, no MFA needed again.
- Entra ID builds the assertion: WHO (
jwick@skyline.com), WHEN (8:55, valid until 9:05), FOR WHOM (plm.skyline.comonly), WHAT (Engineering, Designer), and cruciallyInResponseTo: REQ-7742β echoing the request ID back. - Entra ID sends it through John's browser as an auto-submitting form POST to PLM's Assertion Consumer Service URL.
- PLM validates three things, all must pass: the signature (against Entra ID's certificate), the audience (matches
plm.skyline.comβ an assertion meant for ServiceNow fails here), and the request ID (REQ-7742matches what PLM sent β proof this is a fresh response, not a replay). - PLM creates its own session. John is in, under two seconds, no password typed.
Why this is secure: the request ID is the key. PLM generated it, Entra ID echoed it back. An attacker replaying a captured assertion later finds no matching open request at PLM, and gets rejected. Built-in replay protection.
IdP-Initiated Flow (the portal starts it)
IdP-initiated means the login starts at the IdP portal. John opens Entra ID's app portal and clicks the PLM tile β no SAML Request was ever sent, because PLM never asked for anything.
The assertion looks almost the same, except InResponseTo is empty β there's nothing to echo. PLM's checks: signature valid, audience valid, and request ID β nothing to check, so PLM accepts the assertion anyway.
Why this has a replay risk: there's no request ID to match. If an attacker intercepts the assertion in transit, they can resend that same assertion to PLM's ACS URL again within its validity window (often around 5 minutes), and PLM has no open request to compare it against. The only defense is PLM tracking which assertion IDs it has already seen β and not every app does that.
It still exists because: app portals need a starting point with no app to ask first; legacy apps were never built to generate SAML Requests, only to receive assertions; and deep links from emails ("click here to approve this in SAP") route through the IdP with no SP-initiated request in the loop.
| SP-initiated | IdP-initiated | |
|---|---|---|
| Starts at | the app | the IdP portal |
| SAML Request sent? | yes, with a unique ID | no |
InResponseTo? | echoes the request ID | empty |
| Replay protection | built-in | app must track seen assertions |
| Security | stronger β default choice | weaker β use only when needed |
Trust Setup (Metadata) and the Most Common Outage
Metadata is a small XML file describing one side of the SAML relationship β its name, web addresses, and signing certificate. Entra ID gives PLM its issuer name, login URL, and signing certificate; PLM gives Entra ID its entity ID (becomes the audience) and ACS URL. One-time config, about 30 minutes, no code.
Certificate expiry is the most common SAML outage. Certificates expire every 1 to 3 years. IT renews the certificate on the IdP side β but if nobody updates PLM's stored copy, PLM keeps verifying against the old certificate. The new signature doesn't match the old public key. Verification fails. Every single person at Skyline gets locked out of PLM simultaneously, with a generic "contact your administrator" error, and the fix (uploading the new certificate) takes five minutes once someone finds the actual cause β which usually takes the other two hours. With 50 apps connected via SAML, that's 50 separate places the new certificate has to land.
Where SAML Breaks
| Problem | Why |
|---|---|
| Mobile apps | SAML uses browser redirects; native apps aren't browsers β clunky web views, broken session cookies |
| APIs (machine-to-machine) | no human, no browser; SAML assertions are big XML documents, heavy for API calls |
| XML complexity | verbose, hard to debug, XML signature wrapping attacks |
OAuth 2.0 picks up the mobile and API cases with JSON and lightweight tokens; OIDC adds identity on top for SSO everywhere. SAML isn't dead, though β hundreds of enterprise apps still speak it, and Skyline runs both: SAML for legacy browser apps, OIDC for new apps and mobile.
π΄ CHECKPOINT: Study Notes

| Term | One line |
|---|---|
| Assertion | the signed statement about the user |
| SP-initiated | the app requests, replay-protected via request ID matching |
| IdP-initiated | the IdP pushes, no request to match, weaker replay defense |
| Metadata | the one-time trust config shared by both sides |
| Certificate expiry | the silent killer β renew the IdP cert, forget one app, that app breaks for everyone |
β Previous: Authentication & MFA Β· Back to the series start Β· Next: OAuth 2.0, Part 1 β