SAML (Security Assertion Markup Language) is an open XML standard that lets an identity provider tell a separate application that a user has already signed in, so the user does not log in again. The identity provider sends a digitally signed message called a SAML assertion; the application verifies the signature and grants access. The current version, SAML 2.0, has been an OASIS Standard since March 2005 and still powers most enterprise single sign-on (SSO) to SaaS apps.
| Quick facts | Detail |
| Parties | Identity provider (IdP), service provider (SP), user’s browser |
| Message format | XML with an XML signature |
| What the app never sees | The user’s password, MFA code, or passkey |
| What SAML does not do | Create, update, or delete user accounts |
| Setup difficulty | Moderate to connect a SaaS app; high to build an SP from scratch |
How Does SAML Work?

Here is how SAML works in the most common pattern, SP-initiated SAML SSO:
- User opens the app. The browser requests app.example.com with no active session.
- The app sends an AuthnRequest. The SP creates a request with a unique ID and redirects the browser to the IdP.
- IdP authenticates the user. The IdP performs password, MFA, or passkey checks here.
- IdP returns a signed response. It contains an assertion naming the user, the target app, a validity window, and optional attributes.
- Browser posts the response to the app. An auto-submitting form delivers it to the SP’s Assertion Consumer Service (ACS) URL.
- The app validates and logs the user in. The SP checks the signature against the IdP certificate it stored earlier, then checks time, audience, and recipient.
All trust rests on the IdP signing certificate exchanged before the first login. Whoever holds that private key can mint valid logins for every connected app.
What Is Inside a SAML Assertion?
The SAML 2.0 core specification defines three statement types: authentication, attribute, and authorization decision. The simplified assertion below marks the fields an app must check and the attack each check blocks.
<saml:Assertion ID="_a75adf55" IssueInstant="2026-09-23T14:02:10Z" Version="2.0">
<!-- Must match the trusted IdP entityID -->
<saml:Issuer>https://idp.example.com</saml:Issuer>
<!-- Verify with the IdP cert from stored metadata, never a cert inside the message -->
<ds:Signature>...</ds:Signature>
<saml:Subject>
<!-- The identifier the app maps to a local account -->
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">jane@example.com</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<!-- InResponseTo: ties the assertion to the app's own request (blocks injection) -->
<!-- Recipient: must equal the app's ACS URL (blocks redirection) -->
<saml:SubjectConfirmationData InResponseTo="_req9f3c"
Recipient="https://app.example.com/saml/acs"
NotOnOrAfter="2026-09-23T14:07:10Z"/>
</saml:SubjectConfirmation>
</saml:Subject>
<!-- Validity window: reject outside it (blocks replay) -->
<saml:Conditions NotBefore="2026-09-23T14:01:10Z" NotOnOrAfter="2026-09-23T14:07:10Z">
<!-- Must equal the app's own entityID (blocks assertions minted for another app) -->
<saml:AudienceRestriction>
<saml:Audience>https://app.example.com</saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="2026-09-23T14:02:08Z">
<saml:AuthnContext>
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
<!-- Attributes the app uses for roles -->
<saml:AttributeStatement>
<saml:Attribute Name="groups"><saml:AttributeValue>finance-admins</saml:AttributeValue></saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
SP-Initiated or IdP-Initiated: Which Should You Enable?
| Factor | SP-initiated | IdP-initiated |
| Starts from | The app’s login page | An app tile on the IdP dashboard |
| InResponseTo check | Possible | Impossible (no request exists) |
| Injection risk | Lower | Higher, because the app accepts unsolicited responses |
| Deep links | Supported via RelayState | Limited |
| Verdict | Default | Enable only if users need dashboard launch, with strict replay caching |
How Is SAML Used?
How is SAML used in practice? It fits wherever an organization, not the individual user, controls identity. The SAML 2.0 profiles specification defines the Web Browser SSO profile behind nearly all of these deployments.
| Use case | Who configures it | Typical attributes |
| Employee SSO to SaaS (CRM, HR, ticketing) | Corporate IT via Entra ID, Okta, Google Workspace, or Ping | Email, name, groups |
| Cloud console federation (AWS, Google Cloud, Azure) | Cloud and security teams | Role mapped to cloud permissions |
| “Enterprise SSO” inside your own B2B SaaS product | Your engineers as SP; each customer’s IdP | Email, customer-defined roles |
| University research federations | Campus identity offices | Affiliation (student, faculty, staff) |
| Government and contractor portals | Agency identity programs | Identifier tied to an assurance level |
How Do You Set Up SAML Authentication for One App?
SAML authentication between one IdP and one app takes five configuration steps. If you have not picked a platform yet, start with how to choose an identity provider.
- Create the app in the IdP. Enter the app’s entityID and ACS URL, found in the app’s SSO settings or SP metadata.
- Choose the NameID. Use a stable, unique identifier (email or immutable user ID) that matches accounts in the app.
- Map attributes. Send only what the app needs, such as email and group, to limit data exposure.
- Import IdP metadata into the app. This loads the IdP entityID, SSO URL, and signing certificate.
- Test with a non-admin account first. Keep a local break-glass admin login until SSO is proven.
Why Doesn’t SAML Remove Access When Someone Leaves?
SAML only answers “who is logging in right now.” It never tells an app that a user was fired, renamed, or moved teams. Disabling a user in the IdP blocks new SAML logins, but existing app sessions, local passwords, and API tokens can stay active.
| Gap | SAML alone | SAML plus SCIM |
| Account created before first login | No (requires just-in-time creation on login) | Yes |
| Role change pushed to the app | Only at the next login | Immediately |
| Account deactivated on offboarding | No | Yes |
The fix is SCIM, an IETF standard for provisioning and deprovisioning accounts across domains. When buying SaaS, ask for SAML and SCIM together; without one, you leave an offboarding gap. Our SCIM provisioning guide covers setup.
SAML vs OAuth vs OpenID Connect: Which One Fits?
| Criterion | SAML 2.0 | OAuth 2.0 | OpenID Connect |
| Job | Log a user into a web app | Give an app scoped access to an API | Log a user into any app |
| Token | Signed XML assertion | Access token | Signed JSON ID token |
| Mobile and single-page apps | Weak (browser form POST) | Strong | Strong |
| Enterprise SaaS support | Near-universal | Not a login protocol alone | Broad and growing |
| Parsing risk | High (XML signatures) | Implementation-dependent | Lower (JSON) |
SAML vs OAuth decision rule: They solve different problems. OAuth 2.0 grants API access; it does not prove who the user is. Use SAML when enterprise customers require it for workforce login. For a new app with no SAML requirement, OpenID Connect is simpler to build and maintain. See the full SAML vs OIDC comparison for migration trade-offs.
Why Does SAML Security Matter More in 2026?
SAML cuts the number of passwords attackers can steal, but it concentrates risk in two places: the IdP signing key and each app’s validation code.
- Attackers shifted to exploiting software. The 2026 Verizon Data Breach Investigations Report found vulnerability exploitation rose to 31% of breach initial access, while credential abuse fell to 13%. Only 26% of critical CISA KEV vulnerabilities were fully remediated in 2025, down from 38% the prior year. For SAML, patching your SSO library now matters as much as protecting passwords.
- Stolen signing keys bypass MFA. In Golden SAML attacks documented by CISA, an actor compromised federated identity systems and used forged authentication tokens to move into Microsoft cloud environments. The forged tokens pass every check because they carry a real signature.
- Validation code fails silently. In 2025, ruby-saml versions before 1.12.4 and 1.18.0 allowed authentication bypass because two XML parsers read the same message differently, enabling signature wrapping.
Explore more: STRIDE Threat Model: Definition, Framework, and How to Use It
What Should a SAML Security Checklist Include?
| # | Check | Blocks |
| 1 | Verify the signature only with the IdP certificate from stored metadata | Attacker-supplied keys |
| 2 | Confirm the signed element is the exact element your code reads | Signature wrapping |
| 3 | Use one XML parser for verification and data extraction | Parser differentials |
| 4 | Match Issuer to the expected IdP | Cross-tenant reuse |
| 5 | Match Audience to your entityID | Assertions for another app |
| 6 | Match Recipient and Destination to your ACS URL | Redirected assertions |
| 7 | Enforce NotBefore and NotOnOrAfter with small clock skew | Replay of old assertions |
| 8 | Require InResponseTo to match an open request | Unsolicited injection |
| 9 | Cache assertion IDs until expiry and reject repeats | Replay inside the window |
| 10 | Disable DTDs and external entities | XXE attacks |
| 11 | Alert before IdP certificate expiry; rotate on schedule | Outages and key-theft persistence |
| 12 | Patch the SAML library on your fastest security cadence | Known bypasses |
Items 2 and 3 are where hand-built implementations fail most often. Use a maintained library or identity platform instead of parsing XML yourself.
Delve into the details of: Cybersecurity Interview Questions That Actually Get Asked in 2026
How Do You Fix Common SAML Login Errors?
| Symptom | Likely cause | Fix |
| “Invalid signature” after months of working | IdP signing certificate rotated or expired | Re-import IdP metadata into the app |
| “Audience mismatch” | entityID differs, often by a trailing slash or http vs https | Make IdP and app values identical |
| “Assertion expired” or “not yet valid” | Server clock drift | Sync servers with NTP |
| “Invalid recipient” or “Destination mismatch” | Wrong ACS URL in the IdP | Copy the ACS URL from SP metadata |
| Login succeeds but user has no access | Attribute name or group value not mapped | Match attribute names exactly in both systems |
| “User not found” | NameID format differs from app accounts | Align NameID with the app’s unique identifier |
| Works from dashboard, fails from app (or reverse) | Only one flow enabled | Enable the required flow or add RelayState |
To inspect a live response, open browser developer tools, find the POST to the ACS URL in the Network tab, Base64-decode the SAMLResponse value, and compare each field against the table above.
<!– EDITOR: insert a real screenshot here of a decoded SAMLResponse from your own test tenant (blur tenant IDs and emails). Suggested alt text: “Decoded SAML response in browser developer tools showing Issuer, Audience, and NotOnOrAfter fields”. –>
How Does NIST SP 800-63C-4 Grade SAML Federations?
US agencies and many federal contractors measure federation strength with NIST SP 800-63C-4, published July 2025 and superseding SP 800-63C. It rates federations by Federation Assurance Level (FAL).
| FAL | Core expectation | SAML implication |
| FAL1 | Signed assertion from the IdP | Standard signed response with basic validation |
| FAL2 | Adds injection protection and a formal trust agreement | Prefer SP-initiated flows; enforce InResponseTo; document the trust relationship |
| FAL3 | User proves possession of an authenticator bound to the assertion | Bearer-only SAML is insufficient; a holder-of-key assertion or bound authenticator is required |
If a contract cites 800-63-4, confirm the required FAL before enabling IdP-initiated SSO.
What Are SAML’s Limits?
- XML complexity: Canonicalization and XML signatures create more attack surface than JSON tokens.
- Browser dependence: The form-POST design makes native mobile apps awkward.
- Unreliable logout: Single Logout needs every app to respond; one failure leaves sessions open.
- Certificate outages: One expired IdP certificate breaks login for every connected app at once.
Learn more about: 10 Cyber Security Certifications That Pay $180K+ in 2026
Verdict: Should You Use SAML?
- Use SAML if you sell to enterprises or connect employees to SaaS apps that already support it, and pair it with SCIM to close the offboarding gap.
- Choose OpenID Connect for new consumer, mobile, or single-page apps with no SAML requirement.
- Never hand-build SAML validation. Use a maintained library, apply the 12-point checklist, and patch SAML dependencies as fast as internet-facing systems.
- Treat the IdP signing key as your most sensitive secret. Restrict access, monitor its use, and test certificate rotation before an outage forces it.
FAQ
Is SAML authentication or authorization?
Primarily authentication. Assertions can carry attributes and authorization decisions, but the app enforces its own permissions.
What is the difference between SAML and SSO?
SSO is the experience of signing in once for many apps. SAML is one protocol that delivers it.
Is SAML still used in 2026?
Yes. Enterprise SaaS vendors and major cloud providers continue to support SAML 2.0 for workforce login.
Does SAML work with passkeys and MFA?
Yes. The IdP performs the passkey or MFA check, and every connected app inherits it through the assertion. Pair SAML with phishing-resistant MFA at the IdP for the strongest setup.
