Skip to content
Hameed's dev blog

Blog

IAM Chapter 4: SAML 2.0 & SSO

Β·7 min readΒ·---
Iam chapter 4 saml and sso.png
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:

PartWhat it isPlain words
Assertionthe signed statement about the userthe notarized letter
Protocolthe request-and-response messagesthe question and answer
Bindinghow 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:

PageContainsExample
WHOthe subject the assertion is aboutjwick@skyline.com
WHEN / HOWthe authentication statement β€” when checked, how long valid, who may accept itchecked 9:01, expires 9:06, audience PLM only
WHATattributes the app may needdept 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.

  1. John's browser hits plm.skyline.com. PLM has no session for him today.
  2. PLM generates a SAML Request with a unique ID β€” say REQ-7742 β€” meaning "Entra ID, authenticate this user and send them back."
  3. PLM redirects John's browser to Entra ID, carrying that request.
  4. Entra ID checks John's session cookie. He logged in at 8:55 β€” no password, no MFA needed again.
  5. Entra ID builds the assertion: WHO (jwick@skyline.com), WHEN (8:55, valid until 9:05), FOR WHOM (plm.skyline.com only), WHAT (Engineering, Designer), and crucially InResponseTo: REQ-7742 β€” echoing the request ID back.
  6. Entra ID sends it through John's browser as an auto-submitting form POST to PLM's Assertion Consumer Service URL.
  7. 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-7742 matches what PLM sent β€” proof this is a fresh response, not a replay).
  8. 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-initiatedIdP-initiated
Starts atthe appthe IdP portal
SAML Request sent?yes, with a unique IDno
InResponseTo?echoes the request IDempty
Replay protectionbuilt-inapp must track seen assertions
Securitystronger β€” default choiceweaker β€” 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

ProblemWhy
Mobile appsSAML 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 complexityverbose, 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

IAM Chapter 4: SAML 2.0 & SSO, handwritten study notes with SP-initiated and IdP-initiated sequence diagrams
TermOne line
Assertionthe signed statement about the user
SP-initiatedthe app requests, replay-protected via request ID matching
IdP-initiatedthe IdP pushes, no request to match, weaker replay defense
Metadatathe one-time trust config shared by both sides
Certificate expirythe 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 β†’

Practical notes on product management, distributed systems, and AIβ€”written from real engineering and product experience.