# Microsoft Entra ID SAML integration for SaaS apps

**How do I set up Microsoft Entra ID SAML SSO for a SaaS application?**

In Microsoft Entra ID (formerly Azure AD), you add SAML [single sign-on](https://clerk.com/glossary.md#single-sign-on-sso) by creating an enterprise application, entering the Identifier (Entity ID) and Reply URL (ACS URL) from your SaaS app, mapping the NameID and claims, configuring the signing certificate or federation metadata, assigning users, and testing the connection. Entra is the [SAML](https://clerk.com/glossary.md#security-assertion-markup-language-saml) 2.0 [identity provider](https://clerk.com/glossary.md#identity-provider-sso-idp-sso) (IdP); your SaaS app is the [service provider](https://clerk.com/glossary.md#service-provider-sp) (SP) that consumes the signed assertion. Basic SAML SSO is free on every Entra tier and needs only an admin role.

This guide walks the full path: the protocol basics, prerequisites and licensing, a six-step Zendesk walkthrough, attribute mapping, certificate rotation, SCIM, security hardening, and troubleshooting. It closes with the part most Entra tutorials skip: what changes when _your_ SaaS has to accept SAML from many customers' Entra tenants at once.

Facts here are current as of June 2026. Anything pricing-sensitive or in preview carries an as-of date, because those change often. Verify them against the vendor's own page before you commit.

> Direction is everything in SAML. Microsoft Entra ID is the **identity provider**: it authenticates the user and issues a signed assertion. Your SaaS application is the **service provider**: it trusts that assertion instead of holding a password. Keep IdP and SP straight and most of the configuration below stops being confusing.

**Key takeaways:**

- Microsoft Entra ID (formerly Azure AD) acts as the SAML 2.0 IdP; your SaaS app is the SP that validates the assertion.
- Basic SAML SSO is free on every Entra tier, including custom non-gallery apps. You only need an admin role. P1/P2 licenses add Conditional Access, group-based assignment, group provisioning, and token encryption.
- The six core steps: create the enterprise app, set Identifier and Reply URL, map the NameID and claims, configure the signing certificate, assign users, and test.
- Entra's signing certificate defaults to 3-year validity; rotate it through an overlapping inactive certificate to avoid downtime.
- A SAML assertion is valid for 70 minutes by default. SP-initiated SSO is preferred over IdP-initiated for security.
- SAML authenticates; SCIM provisions and deprovisions. Use both for the full account lifecycle.
- If your SaaS must accept SAML from many customers' Entra tenants, that's a multi-tenant service-provider problem, covered in the last section.

## What is SAML SSO with Microsoft Entra ID?

SAML 2.0 is an XML standard for exchanging [authentication](https://clerk.com/glossary.md#authentication) and [authorization](https://clerk.com/glossary.md#authorization) data between an identity provider and a service provider. It was ratified as an OASIS Standard in 2005 and remains the entrenched enterprise SSO protocol ([OASIS Technical Overview](https://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html)). In a Microsoft Entra integration, Entra is the IdP and the SaaS app is the SP ([Microsoft Learn: SAML architecture](https://learn.microsoft.com/en-us/entra/architecture/auth-saml)).

The login itself runs as one of two flows. In **SP-initiated** SSO, the user starts at your app, which sends a SAML `AuthnRequest` to Entra over an HTTP Redirect; Entra authenticates the user and POSTs a signed `Response` back to your [Assertion Consumer Service](https://clerk.com/glossary.md#assertion-consumer-service-acs) (ACS) URL. In **IdP-initiated** SSO, the user starts from a tile in Entra and Entra POSTs the assertion without a prior request. Entra supports both, and uses HTTP Redirect for the request and HTTP POST for the response ([Microsoft Learn: SAML protocol](https://learn.microsoft.com/en-us/entra/identity-platform/single-sign-on-saml-protocol)).

Trust between the two parties is cryptographic. Entra signs each assertion with an X.509 certificate, and your app validates that signature against Entra's published certificate or federation metadata. The assertion carries the user's identity in a `Subject`/`NameID` plus an `AttributeStatement`, time-bounds it in a `Conditions` element, and records how the user authenticated in an `AuthnStatement`.

Here's a trimmed, representative Entra SAML response. Real assertions are larger and include the XML signature, but this shows the elements an SP reads and validates:

```xml
<samlp:Response Version="2.0" IssueInstant="2026-06-04T07:38:15.128Z"
  Destination="https://acme.zendesk.com/access/saml" InResponseTo="_req-id-123"
  xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
  <Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">https://sts.windows.net/00000000-0000-0000-0000-000000000000/</Issuer>
  <samlp:Status>
    <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
  </samlp:Status>
  <Assertion Version="2.0" IssueInstant="2026-06-04T07:38:15.128Z"
    xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
    <Issuer>https://sts.windows.net/00000000-0000-0000-0000-000000000000/</Issuer>
    <!-- ds:Signature over this Assertion element belongs here -->
    <Subject>
      <NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">a1b2c3-opaque-pseudonym</NameID>
      <SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
        <SubjectConfirmationData InResponseTo="_req-id-123"
          NotOnOrAfter="2026-06-04T07:43:15.128Z"
          Recipient="https://acme.zendesk.com/access/saml" />
      </SubjectConfirmation>
    </Subject>
    <Conditions NotBefore="2026-06-04T07:38:15.128Z" NotOnOrAfter="2026-06-04T08:48:15.128Z">
      <AudienceRestriction>
        <Audience>https://acme.zendesk.com</Audience>
      </AudienceRestriction>
    </Conditions>
    <AttributeStatement>
      <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress">
        <AttributeValue>ada@acme.com</AttributeValue>
      </Attribute>
      <Attribute Name="http://schemas.microsoft.com/identity/claims/objectidentifier">
        <AttributeValue>11111111-2222-3333-4444-555555555555</AttributeValue>
      </Attribute>
    </AttributeStatement>
    <AuthnStatement AuthnInstant="2026-06-04T07:38:10.000Z">
      <AuthnContext>
        <AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</AuthnContextClassRef>
      </AuthnContext>
    </AuthnStatement>
  </Assertion>
</samlp:Response>
```

Notice the two time windows. The `Conditions NotOnOrAfter` is exactly 70 minutes after `NotBefore`, which is Entra's documented assertion validity window ([Microsoft Learn: SAML protocol](https://learn.microsoft.com/en-us/entra/identity-platform/single-sign-on-saml-protocol)). The shorter `SubjectConfirmationData NotOnOrAfter` (about 5 minutes) is the bearer window during which the assertion can be presented to the ACS URL. One quirk worth knowing: the sign-in `Issuer` is `https://sts.windows.net/<tenant-id>/`, a legacy host string that Entra still emits.

Enterprises require SAML SSO into SaaS apps for three reasons: centralized identity (one corporate login, not a password per app), security and compliance (MFA, Conditional Access, and audit trails enforced in one place), and lifecycle control (access granted and revoked from the directory).

## SAML vs. OIDC in Microsoft Entra ID: which to choose

For new application development, use [OpenID Connect](https://clerk.com/glossary.md#openid-connect) (OIDC); reach for SAML when you're integrating an existing app that only speaks SAML. That's Microsoft's own guidance, and stating it plainly matters more than the fact that this article targets SAML.

Microsoft writes: _"Choose OpenID Connect and OAuth 2.0 if the application you're connecting to supports it"_ and _"Choose SAML whenever possible for existing applications that don't use OpenID Connect or OAuth"_ ([Microsoft Learn: Plan SSO deployment](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/plan-sso-deployment)). For greenfield work it's blunter: _"For new application development, we recommend using OpenID Connect (OIDC) for authentication"_ ([Microsoft Learn: Authenticate applications and users](https://learn.microsoft.com/en-us/entra/architecture/authenticate-applications-and-users)).

The technical contrast is short. SAML uses signed XML assertions, a mature enterprise feature set, and a metadata-plus-certificate exchange. OIDC uses JSON and [JWTs](https://clerk.com/glossary.md#json-web-token) on top of [OAuth](https://clerk.com/glossary.md#oauth) 2.0, with discovery via a `/.well-known/openid-configuration` endpoint and key rotation through a JWKS endpoint that removes most manual certificate handling. Entra fully supports both, and SAML 2.0 has no retirement timeline; it remains the default for a large catalog of SaaS apps ([Microsoft Q\&A: SAML token retirement](https://learn.microsoft.com/en-us/answers/questions/5757030/)).

## Key SAML terms and their Microsoft Entra ID equivalents

The single most useful reference for configuring Entra is the mapping between standard SAML vocabulary and the exact labels in the admin center. The first three columns of your setup all live in the **Basic SAML Configuration** blade.

| SAML / SP term                       | Microsoft Entra portal label                                  | Where it appears         |
| ------------------------------------ | ------------------------------------------------------------- | ------------------------ |
| Entity ID (SP)                       | **Identifier (Entity ID)**                                    | Basic SAML Configuration |
| Assertion Consumer Service (ACS) URL | **Reply URL (Assertion Consumer Service URL)**                | Basic SAML Configuration |
| SP-initiated start URL               | **Sign on URL**                                               | Basic SAML Configuration |
| RelayState                           | **Relay State (Optional)**                                    | Basic SAML Configuration |
| Single-logout endpoint               | **Logout Url (Optional)**                                     | Basic SAML Configuration |
| NameID / Subject identifier          | **Unique User Identifier (Name ID)**                          | Attributes & Claims      |
| IdP metadata document                | **App Federation Metadata Url** / **Federation Metadata XML** | SAML Certificates        |
| IdP signing certificate              | **Certificate (Base64)** / **Thumbprint**                     | SAML Certificates        |
| IdP SSO endpoint (SP-side value)     | **Login URL**                                                 | "Set up [App]"          |
| IdP Entity ID (SP-side value)        | **Microsoft Entra Identifier**                                | "Set up [App]"          |
| IdP SLO endpoint (SP-side value)     | **Logout URL**                                                | "Set up [App]"          |

The values in the bottom three rows are what you copy _out_ of Entra and into your SaaS app. Everything else you type _into_ Entra from your app's requirements.

## Prerequisites for configuring Entra ID SAML SSO

You need an Entra admin role, a handful of values from the SaaS app, and a test user. You do not need a premium license for basic SAML SSO.

**Admin role.** Cloud Application Administrator is the recommended role; it equals Application Administrator minus app-proxy management. For a single app, assigning yourself as the application's **owner** is the least-privilege option. Both admin roles can add credentials to an app and effectively impersonate it, so treat them as high-privilege, and note that neither grants Conditional Access (that needs the Conditional Access Administrator role) ([Microsoft Learn: Delegate app roles](https://learn.microsoft.com/en-us/entra/identity/role-based-access-control/delegate-app-roles)).

**Values to collect from the SaaS app.** The Identifier (Entity ID), the Reply URL (ACS URL), an optional Sign on URL, the expected NameID format, and any required claims. A non-production test user or group to validate against before you roll out to everyone.

**Licensing reality check.** SSO for enterprise apps is free on every Entra tier. Microsoft states it directly: _"SSO for preintegrated enterprise applications is free"_ ([Microsoft Learn: Plan SSO deployment](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/plan-sso-deployment)). That sentence names gallery ("preintegrated") apps, but custom non-gallery apps are covered too: the SAML setup guide lists only an admin role as a prerequisite and states that SAML SSO is configurable on "single tenant applications or gallery applications" — and a custom "Create your own application" app is single-tenant ([Microsoft Learn: Enable SAML SSO](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/add-application-portal-setup-sso)). What needs Entra ID P1 or P2 is the set of features layered on top: Conditional Access, group-based app assignment, automated _group_ provisioning and provisioning logs, and SAML token encryption ([Microsoft Learn: Licensing](https://learn.microsoft.com/en-us/entra/fundamentals/licensing)). Automated _user_ provisioning is available on the Free tier.

> A common misconception is that a custom, non-gallery SAML app ("Create your own application") requires P1 or P2. It doesn't. Microsoft's SAML setup guide lists only an admin role as a prerequisite and notes that SAML SSO is configurable on "single tenant applications or gallery applications" alike — a custom app is single-tenant, so it qualifies. Only multi-tenant apps have SAML SSO greyed out ([Microsoft Learn: Enable SAML SSO](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/add-application-portal-setup-sso)).

## Choosing an integration approach

### Gallery vs. non-gallery (custom) enterprise applications

If your SaaS app is in the Entra application gallery, add it from there: the gallery holds thousands of pre-integrated apps with preconfigured SSO, per-app setup tutorials, and provisioning where supported ([Microsoft Learn: Application gallery](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/overview-application-gallery)). If it isn't listed, create a custom app with **New application > Create your own application** and configure SAML manually.

The trade-off is pre-filled metadata and tested defaults (gallery) versus full manual control (custom). Neither path costs a premium license; custom SAML SSO is a Free-tier feature, exactly like gallery SSO. The only things that push you to P1 or P2 are group-based assignment, Conditional Access, group provisioning, and token encryption.

### IdP-initiated vs. SP-initiated SSO

Prefer SP-initiated SSO. It binds the response to the request through the `InResponseTo` attribute (derived from the `AuthnRequest` ID) plus RelayState, which gives login-CSRF and replay protection that IdP-initiated flows structurally lack. OWASP's guidance is to not allow IdP-initiated SSO where you can avoid it, because a stolen assertion can be injected into another browser session ([OWASP SAML Security Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/SAML_Security_Cheat_Sheet.html); [Scott Brady](https://www.scottbrady.io/saml/dangers-of-idp-initiated-sso)).

The honest nuance: many enterprise customers still launch apps from their IdP dashboard, so a well-built SaaS app usually has to support IdP-initiated flows too, just safely (validate `InResponseTo` when present, enforce short assertion lifetimes, and detect replays).

## Step-by-step: configure SAML SSO in Microsoft Entra ID (Zendesk walkthrough)

This walkthrough uses **Zendesk** as a representative SaaS app. Its URL patterns are clean and consistent, and it has no mandatory SAML attributes, so it shows the flow without edge cases. The same six steps apply to any gallery app; for an app that isn't in the gallery, the **Microsoft Entra SAML Toolkit** is Microsoft's vendor-neutral test app. Throughout, `<subdomain>` is your Zendesk subdomain.

The admin center is at `entra.microsoft.com`. The current top-level navigation is **Entra ID > Enterprise apps**, not "Azure Active Directory."

### Step 1: Create the enterprise application

Go to **Entra ID > Enterprise apps > New application**, search the gallery for **Zendesk**, and add it (or choose **Create your own application** for a non-gallery app). Open the app and select **Single sign-on > SAML**.

### Step 2: Configure Basic SAML Configuration

Select the edit (pencil) icon on the **Basic SAML Configuration** card and enter Zendesk's values ([Microsoft Learn: Zendesk tutorial](https://learn.microsoft.com/en-us/entra/identity/saas-apps/zendesk-tutorial)):

| Field                  | Value                                         |
| ---------------------- | --------------------------------------------- |
| Identifier (Entity ID) | `https://<subdomain>.zendesk.com`             |
| Reply URL (ACS URL)    | `https://<subdomain>.zendesk.com/access/saml` |
| Sign on URL            | `https://<subdomain>.zendesk.com`             |

The Identifier tells Entra which app the assertion is for (it becomes the `Audience`). The Reply URL is where Entra POSTs the response. The Sign on URL is the page that kicks off SP-initiated login.

Two details that save debugging later. A single SAML app can hold a list of up to 256 Reply URLs (handy for separating staging and production, or regional subdomains). For SP-initiated sign-in, Entra POSTs the response to the Reply URL that _exactly_ matches the literal `AssertionConsumerServiceURL` in the app's `AuthnRequest`; it matches on the URL string, not on a SAML index ([Microsoft Learn: Reply URL](https://learn.microsoft.com/en-us/entra/identity-platform/reply-url)). When the request carries no ACS URL, including every IdP-initiated flow, Entra uses the _first_ Reply URL in the list. A requested URL that isn't in the list throws AADSTS50011 (see troubleshooting).

The **Relay State (Optional)** field is more useful than its label suggests. RelayState carries the user's intended destination across the round-trip. In SP-initiated SSO the app sends RelayState in its request and Entra echoes the same value back, so the app can route the user to the page they originally asked for. The field on this blade only takes effect for IdP-initiated flows, where it supplies the landing URL ([Microsoft Q\&A: RelayState](https://learn.microsoft.com/en-us/answers/questions/1847181/)). The SAML spec caps RelayState at 80 bytes, so apps commonly store the real URL server-side and pass a short token ([OASIS SAML 2.0 errata](https://docs.oasis-open.org/security/saml/v2.0/errata05/os/saml-v2.0-errata05-os.html), section 3.4.3).

### Step 3: Configure user attributes and claims

Open **Attributes & Claims**. The default **Unique User Identifier (Name ID)** is `user.userprincipalname`, and Zendesk needs no other mandatory attributes. Some apps do need the NameID remapped: GitHub Enterprise and Box, for instance, expect `user.mail` as the identifier rather than the UPN. The deep dive below covers when and how to change this.

### Step 4: Set up the signing certificate and metadata

In the **SAML Certificates** card, you can either download the **Certificate (Base64)** and **App Federation Metadata Url** to hand to the SaaS app, or copy individual values. For Zendesk specifically, copy the certificate **Thumbprint (SHA-256)**; Zendesk wants the fingerprint, not the full certificate.

### Step 5: Assign users and groups

Go to **Users and groups > Add user/group** and assign your test user. By default the app's **Assignment required** property is Yes, so only assigned users can sign in. Assigning individual users works on every tier; group-based assignment requires P1 or P2 ([Microsoft Learn: Assign user or group access](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/assign-user-or-group-access-portal)). Nested group membership is not honored, so assign users directly or through a directly assigned group.

### Step 6: Test the SSO integration

Use the **Test single sign-on** button on the SAML page (it stays greyed out until you save the Basic SAML Configuration). For deeper inspection, install the **My Apps Secure Sign-in Extension** for Chrome or Edge, which captures the SAML request and response and offers a "Fix it" prompt for common errors ([Microsoft Learn: Debug SAML SSO](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/debug-saml-sso-issues)).

Once the app is configured and the test user (or a group they're in) is assigned, the app tile also appears automatically on that user's **My Apps portal** at `myapps.microsoft.com`, Entra's end-user launchpad. Microsoft notes it _"can take several minutes for an application to appear"_ there ([Microsoft Learn: My Apps](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/myapps-overview)). Launching from a My Apps tile drives an IdP-initiated flow. Keep the _portal_ (the website launchpad) separate from the _Extension_ (the debugging browser add-on); they share a name but do different jobs.

### Configure the Zendesk service-provider side

Back in Zendesk Admin Center, go to **Account > Security > Single sign-on > Create SSO configuration > SAML** and map the Entra values you collected:

| Zendesk field                     | Value from Entra |
| --------------------------------- | ---------------- |
| SAML SSO URL                      | **Login URL**    |
| Certificate fingerprint (SHA-256) | **Thumbprint**   |
| Remote logout URL                 | **Logout URL**   |

Activate the configuration by assigning it to **Team member** and/or **End user authentication**. Two gotchas account for most first-attempt failures: the Test button stays greyed out until the Basic SAML Configuration is saved, and forgetting to assign the test user produces an "AADSTS50105" error at sign-in.

## Attribute mapping and claims customization

This is where most real-world integrations succeed or fail, so it's worth the depth.

### Choosing a stable NameID

The NameID is how your SaaS app recognizes a returning user, so it must be stable. Entra's NameID format dropdown offers Default, Persistent, Email address, Unspecified, and Windows domain qualified name (Transient is supported but not in the dropdown), and you can source it from attributes like the UPN, email, `objectid`, `employeeid`, or extension attributes ([Microsoft Learn: SAML claims customization](https://learn.microsoft.com/en-us/entra/identity-platform/saml-claims-customization)).

Lead with stability. Microsoft describes the persistent NameID as _"persistent, it can be revoked, but is never reassigned... opaque,"_ and the object ID (`objectid`) as _"immutable, globally unique, and reuse safe"_ ([Microsoft Learn: SAML token reference](https://learn.microsoft.com/en-us/entra/identity-platform/reference-saml-tokens)). Microsoft's own nOAuth advisory warns against using the mutable, non-unique `email` claim for authorization decisions; prefer the immutable OID ([Microsoft MSRC: nOAuth](https://www.microsoft.com/en-us/msrc/blog/2023/06/potential-risk-of-privilege-escalation-in-azure-ad-applications)). Use email for display, not as the sole identity key.

### Claim names Entra sends

By default Entra emits a standard set of claims under these URIs:

| Claim        | URI                                                                  |
| ------------ | -------------------------------------------------------------------- |
| First name   | `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname`    |
| Last name    | `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname`      |
| Display name | `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name`         |
| Email        | `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress` |
| Object ID    | `http://schemas.microsoft.com/identity/claims/objectidentifier`      |
| Tenant ID    | `http://schemas.microsoft.com/identity/claims/tenantid`              |
| Groups       | `http://schemas.microsoft.com/ws/2008/06/identity/claims/groups`     |

The `name` claim is the UPN and is display-only, not a unique key ([Microsoft Learn: SAML token reference](https://learn.microsoft.com/en-us/entra/identity-platform/reference-saml-tokens)).

### Transformations and group claims

Entra can transform ordinary claims with a library of functions (lowercase, regex replace, extract, join, and more), up to two transformations per claim. The NameID is more restricted: only `ExtractMailPrefix` and `Join` are allowed there, and a `Join` suffix must be a verified tenant domain ([Microsoft Learn: Claims customization reference](https://learn.microsoft.com/en-us/entra/identity-platform/reference-claims-customization)).

Group claims have a hard limit that surprises people. Entra emits at most 150 groups in a SAML assertion (200 in a JWT). Past that, it _"completely omit[s] sending group claims in the token"_ and substitutes an overage link to Microsoft Graph instead ([Microsoft Learn: Group claims](https://learn.microsoft.com/en-us/entra/identity/hybrid/connect/how-to-connect-fed-group-claims)). It's an all-or-nothing cliff, not a truncation. You can scope the claim (all groups, security groups, directory roles, or just groups assigned to the application) and filter only when a user is in 1,000 or fewer groups. When auth succeeds but the app reports "user not found," it's almost always because the value Entra sends doesn't match how the app stores the user; the fix is to align the Unique User Identifier claim with the SP's expectation ([Microsoft Learn: Troubleshoot SAML SSO](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/troubleshoot-saml-based-sso)).

## Managing SAML signing certificates

### Default validity and why rotation matters

Entra generates a self-signed signing certificate that's _"valid for three years"_ ([Microsoft Learn: Manage certificates](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/tutorial-manage-certificates-for-federated-single-sign-on)). When it expires, every SAML login to that app breaks, so rotation is an operational must, not an optional nicety. The validity period is configurable only at creation (anywhere from now to three years out) and can't be changed afterward.

### Rotating a certificate without downtime

The mechanism that makes zero-downtime rotation possible is the secondary, inactive certificate:

1. Create a new certificate. It lands in an **Inactive** state.
2. Download it in the format your SaaS app needs, or rely on metadata if the app consumes the federation metadata URL.
3. Configure or pre-trust the new certificate on the SP side.
4. Select **Make certificate active**. The old certificate flips to Inactive.
5. Retire the old certificate once you've confirmed sign-ins work.

During the overlap, Entra publishes both certificates in its federation metadata, so a metadata-consuming SP can trust the next certificate before it goes active ([Microsoft Learn: Federation metadata](https://learn.microsoft.com/en-us/entra/identity-platform/federation-metadata)). Watch one edge case: if an expired certificate and an inactive-but-valid one coexist, Entra uses the valid one, which can surprise an SP that wasn't ready for it.

### Expiration notifications and automation

Entra sends email warnings _"60, 30, and 7 days before the SAML certificate expires,"_ and you can list up to five notification addresses ([Microsoft Learn: Manage certificates](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/tutorial-manage-certificates-for-federated-single-sign-on)). Keep the signing algorithm at the SHA-256 default and only drop to SHA-1 if an app truly requires it ([Microsoft Learn: Certificate signing options](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/certificate-signing-options)).

There's an industry trend toward shorter certificate lifetimes (the CA/Browser Forum is stepping public-TLS validity down to 47 days by 2029), but that mandate applies to publicly trusted TLS certificates, not private SAML signing certificates ([Keyfactor](https://www.keyfactor.com/education-center/what-are-47-day-certificates/)). The takeaway is to automate rollover, not to force your SAML certificate to 47 days.

## Automating user lifecycle with SCIM provisioning

SAML and OIDC authenticate; SCIM provisions. [SCIM](https://clerk.com/glossary.md#scim) (System for Cross-domain Identity Management) is the REST-and-JSON standard Entra uses to create, update, and deactivate accounts in your app, and Microsoft calls it _"the de facto standard for provisioning"_ that pairs with federation for an end-to-end solution ([Microsoft Learn: User provisioning](https://learn.microsoft.com/en-us/entra/identity/app-provisioning/user-provisioning)).

### SCIM vs. SAML just-in-time (JIT) provisioning

SAML just-in-time provisioning creates an account only on first login, from the attributes carried in the assertion, and it can't deprovision. SCIM creates accounts before first login and deactivates them on offboarding. There's a subtle coupling worth calling out: because JIT builds the account from the assertion, any roles or groups the app needs must ride along as claims at login, which runs straight into the 150-group SAML claim cliff described above. SCIM sidesteps that by syncing out of band over a separate HTTPS channel, independent of the assertion.

### Enabling automatic provisioning

On the app's **Provisioning** blade, set **Provisioning Mode** to **Automatic** and supply the SCIM endpoint URL (Tenant URL) and a bearer token. The initial full sync runs once, then incremental cycles run _"approximately every 40 minutes"_ as long as the service is running ([Microsoft Learn: Use SCIM](https://learn.microsoft.com/en-us/entra/identity/app-provisioning/use-scim-to-provision-users-and-groups)). If the failure rate stays high (over 40%), Entra throttles the job to once a day and disables it after four weeks. [Provisioning](https://clerk.com/glossary.md#provisioning) of individual users is available on Free; group provisioning and provisioning logs require P1.

### Testing without waiting: Provision on demand

Don't sit through a 40-minute cycle to validate a SCIM setup. The **Provision on demand** button syncs a single user immediately, _"typically... less than 30 seconds,"_ and returns a per-user, five-step trace (test connection, shown only on failure, then import, determine scope, match, and perform action) so you can see exactly where a user is being skipped ([Microsoft Learn: Provision on demand](https://learn.microsoft.com/en-us/entra/identity/app-provisioning/provision-on-demand)). It handles one user at a time (groups up to 5 members), the user must already be assigned and in scope, and it only exists where an automatic SCIM connector is configured. Microsoft documents only the Application Administrator role for on-demand provisioning, so it doesn't require P1 on its own.

## Security best practices for Entra ID SAML SSO

Hardening Entra SAML is split across two sides. The IdP-side controls live here; the SP-side validation that your app must perform is in the build-vs-buy section, since that's where it bites.

- **Prefer SP-initiated SSO**, for the request/response binding described earlier.
- **Use a stable, non-reassignable NameID** (`objectid` or persistent), never email as the sole identity key.
- **Apply least-privilege admin roles** and protect app-registration and credential changes; an App Administrator can add credentials and impersonate the app.
- **Layer Conditional Access, [MFA](https://clerk.com/glossary.md#multi-factor-authentication-mfa), and sign-in frequency** (P1/P2) on top of the connection.
- **Encrypt the assertion** with SAML token encryption (P1/P2, AES-256) when it carries sensitive attributes ([Microsoft Learn: Token encryption](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/howto-saml-token-encryption)).
- **Rotate certificates on time** and **deprovision promptly** through SCIM or assignment removal.

### Requiring signed authentication requests

Entra can enforce that incoming `AuthnRequest`s are signed. Upload the SP's signing public key under **Single sign-on > SAML Certificates > Verification certificates** and enable **Require verification certificates**; Entra then validates each request against that key and rejects unsigned ones, hardening against forged login requests ([Microsoft Learn: Enforce signed SAML requests](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/howto-enforce-signed-saml-authentication)).

It's an optional control with a real cost, not a default. The feature is off by default. When you turn it on, it applies to SP-initiated requests only and _"will not allow IDP-initiated authentication requests (like SSO testing feature, MyApps or M365 app launcher)"_ to work, because the IdP doesn't hold the SP's private key. It also accepts only RSA-SHA256 signatures unless an admin opts into a weak algorithm. So enabling it disables the Step 6 Test button and the My Apps launch for that app. Configure it under **Enterprise applications**, not under App registrations (a different feature for an app authenticating itself), and don't expect a single Microsoft Graph toggle: the public key is stored as a service principal `keyCredential` with `usage: "Verify"`.

## Common pitfalls and troubleshooting

Each row is a self-contained Symptom, Cause, and Fix. The error codes are Entra's verbatim AADSTS codes.

| Error                | Symptom                                                            | Cause                                                                                                                                                               | Fix                                                                                                                                                                                                                                                                                                  |
| -------------------- | ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| AADSTS50011          | Reply URL mismatch at sign-in                                      | The `AssertionConsumerServiceURL` in the SAML request doesn't match a registered Reply URL. Matching is case-sensitive on the URL path and trailing-slash sensitive | Add the exact ACS URL to the Reply URL list. A trailing slash or case difference on the path is a common cause ([Microsoft Learn: AADSTS50011](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/app-integration/error-code-aadsts50011-reply-url-mismatch))                             |
| AADSTS50105          | "The signed in user is not assigned to a role for the application" | The user isn't assigned, and nested-group membership isn't honored                                                                                                  | Assign the user directly or via a directly assigned group, or set Assignment required to No ([Microsoft Learn: AADSTS50105](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/app-integration/error-code-aadsts50105-user-not-assigned-role))                                            |
| AADSTS70001          | App not found / Issuer mismatch                                    | The SAML Issuer or Entity ID doesn't match the registered app                                                                                                       | Align the Identifier (Entity ID) with what the app sends ([Microsoft Learn: AADSTS70001](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/app-integration/error-code-aadsts70001-app-not-found-in-directory))                                                                           |
| AADSTS75011          | Authentication method mismatch                                     | The app's `RequestedAuthnContext` doesn't match the existing session's method                                                                                       | Ask the vendor to remove `RequestedAuthnContext`, or send `forceAuthn="true"`. If `Comparison` is set, it must be `exact`, not `minimum` ([Microsoft Learn: AADSTS75011](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/app-integration/error-code-aadsts75011-auth-method-mismatch)) |
| AADSTS75005 / 750054 | Invalid SAML request / wrong binding                               | A malformed request, or the `AuthnRequest` sent over the wrong binding (POST instead of HTTP Redirect)                                                              | Fix the request encoding; send the `AuthnRequest` over HTTP Redirect ([Microsoft Learn: AADSTS750054](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/app-integration/error-code-aadsts750054-saml-request-not-present))                                                               |
| AADSTS50012 / 650056 | Signature or certificate error                                     | Expired, inactive, or wrong signing certificate, or a signature-algorithm mismatch                                                                                  | Confirm the active certificate, rotate if expired, and match the signing algorithm ([Microsoft Learn: App sign-in problem](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/application-sign-in-problem-application-error))                                                          |
| (no code)            | Auth succeeds, app says "user not found"                           | The NameID or attribute Entra sends doesn't match how the app stores the user                                                                                       | Adjust the Unique User Identifier claim to match the SP ([Microsoft Learn: Troubleshoot SAML SSO](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/troubleshoot-saml-based-sso))                                                                                                     |

### Debugging tools

Work the tooling in order. Start with the **Test single sign-on** button, then the **My Apps Secure Sign-in Extension** and its "Fix it" prompt, then **SAML-tracer** or Fiddler to read the raw XML. For broader visibility, open the **Sign-in logs** (filter by Application and Status, and add the "Authentication protocol" column for SAML 2.0; minimum role Reports Reader), grab the Correlation ID, and look up any code at `https://login.microsoftonline.com/error?code=<CODE>` ([Microsoft Learn: Sign-in logs](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-sign-ins)). For provisioning problems rather than sign-in, the parallel tool is **Provision on demand**, which runs the per-user step trace in seconds. SAML sign-in logs and provisioning logs are separate surfaces, and provisioning logs require P1.

## Accepting Microsoft Entra ID SAML in your SaaS application

Everything above is the IdP-admin side. Flip the perspective: if you're building the SaaS app, "integration for SaaS apps" means _your_ application has to accept Entra SAML from many customers, each with its own tenant, metadata, and certificate. This is the only section where it's worth weighing a managed provider.

### What your app must implement as a SAML service provider

The build list is longer than it first looks:

- An ACS endpoint that receives the POSTed response.
- Full assertion validation (the ordered checks below).
- Per-customer connection storage: each customer is its own Entra tenant, metadata, and certificate.
- Certificate-rotation handling: consume federation metadata and support overlapping certificates.
- Both IdP- and SP-initiated support.
- Multi-tenant routing: map an email domain to the right connection.
- SCIM provisioning, including Entra's PATCH quirks (operation casing, the `/scim` root, `active:false` soft-delete, a single bearer token).
- Single Logout, if customers require it (more on its difficulty below).

Validation is the part that's easy to get subtly wrong. Here's the ordered check, as vendor-neutral pseudocode, so the burden is concrete:

```text
function validateSamlResponse(response, storedRequestId):
    assertion = extractAssertion(response)

    # 1. Verify the XML signature BEFORE reading any value.
    #    Confirm the signature's ds:Reference URI covers THIS assertion
    #    (use an absolute XPath, not getElementsByTagName) to block XSW.
    require verifySignature(assertion, trustedIdpCert) using RSA-SHA256 or stronger
    reject if the signing algorithm is SHA-1

    # 2. Confirm the assertion is addressed to you.
    require assertion.Audience == OUR_ENTITY_ID
    require assertion.SubjectConfirmationData.Recipient == OUR_ACS_URL
    require response.Destination == OUR_ACS_URL

    # 3. Confirm it is live.
    now = currentTime()
    require Conditions.NotBefore - skew <= now < Conditions.NotOnOrAfter + skew
    require SubjectConfirmationData.NotOnOrAfter > now

    # 4. Confirm it answers a request you sent (SP-initiated).
    require assertion.InResponseTo == storedRequestId   # absent for IdP-initiated

    # 5. Block replay: reject an assertion ID you have seen before.
    require not replayCache.contains(assertion.ID)
    replayCache.add(assertion.ID, ttl = Conditions.NotOnOrAfter)

    return assertion.NameID, assertion.Attributes
```

One more interoperability detail: sign your outbound `AuthnRequest`s with RSA-SHA256. SHA-1 is disallowed for new signatures (NIST SP 800-131A), yet `@node-saml/node-saml` (and the `passport-saml` wrapper on top of it) still default `signatureAlgorithm` to `'sha1'`, so you have to set `'sha256'` explicitly ([node-saml README](https://github.com/node-saml/node-saml/blob/master/README.md)). This is general SP hygiene for cross-IdP interoperability; by default Entra doesn't even validate the request signature (it verifies the requester through registered ACS URLs), so the algorithm only matters against IdPs that do, or when "Require verification certificates" is enabled.

### Why multi-tenant SAML is structurally hard on Entra

SAML SSO is configured per single-tenant or gallery enterprise app. Entra greys SAML SSO out on multi-tenant apps, which Microsoft states directly ([Microsoft Learn: Enable SAML SSO](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/add-application-portal-setup-sso)). A SaaS serving many customers therefore needs a separate connection per customer, not one shared app, which is the core of the multi-tenant build problem.

Single Logout is a build burden of its own. Per SAML core, when another app in the same session signs out, Entra sends _your_ app a `LogoutRequest`, so you must implement an inbound logout handler and map each SAML session back to a local one. Logout runs over front-channel HTTP Redirects only, with no SOAP back-channel, so the browser has to visit each participating app in turn, and OASIS warns that _"the result of the logout process cannot be guaranteed"_ if the chain breaks ([OASIS Technical Overview](https://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html)). Entra also diverges from the spec (it ignores the `NameID` you send on logout and uses a different sign-out Issuer, `login.microsoftonline.com/<tenant>/`, versus the sign-in `sts.windows.net/<tenant>/`), so even spec-correct code needs Entra-specific handling ([Microsoft Learn: Single sign-out](https://learn.microsoft.com/en-us/entra/identity-platform/single-sign-out-saml-protocol)).

### The security reality: a wave of SAML library CVEs

Rolling your own SAML SP means owning a class of bugs that keeps recurring. One caveat on the numbers: NVD's CVSS v3.1 scores and the GitHub advisories' CVSS v4.0 scores sometimes diverge, so a CVE's severity depends on which you read (NVD rates the samlify flaw 7.5 where GitHub rates it 9.9; the ruby-saml pair is 9.8 versus 9.3). The scoring system behind each figure is noted in its citation below. 2025 and 2026 brought a run of critical service-provider library vulnerabilities:

- **node-saml** loaded the assertion from an unsigned document: CVE-2025-54419, CVSS 10.0 ([NVD](https://nvd.nist.gov/vuln/detail/CVE-2025-54419)).
- **ruby-saml** parser differentials let an attacker forge assertions for any user: CVE-2025-25291 and CVE-2025-25292, CVSS 9.3 ([GitHub Advisory](https://github.com/advisories/GHSA-4vc4-m8qh-g8jm)), with an incomplete-fix follow-up (CVE-2025-66567 and CVE-2025-66568) in December 2025 ([GitHub Blog](https://github.blog/security/sign-in-as-anyone-bypassing-saml-sso-authentication-with-parser-differentials/); [GitHub Advisory](https://github.com/advisories/GHSA-9v8j-x534-2fx3)). The pattern predates 2025: CVE-2024-45409 (CVSS 9.8) let attackers forge ruby-saml assertions back in September 2024 ([NVD](https://nvd.nist.gov/vuln/detail/CVE-2024-45409)).
- **samlify** signature wrapping: CVE-2025-47949, CVSS 9.9 ([GitHub Advisory](https://github.com/advisories/GHSA-r683-v43c-6xqv)).
- **xml-crypto** comment and multi-reference bypasses: CVE-2025-29774 and CVE-2025-29775, CVSS 9.3 ([GitHub Advisory](https://github.com/advisories/GHSA-x3m8-899r-f7c3)).

These sit on top of the classic XML Signature Wrapping research, which found 11 of 14 SAML frameworks vulnerable ([Somorovsky et al., USENIX 2012](https://www.usenix.org/conference/usenixsecurity12/technical-sessions/presentation/somorovsky)), and XML comment-injection (CVE-2017-11427 and family). The through-line: every one is an SP-library bug, fixes are incremental, and safe validation means getting roughly ten OWASP checks right at once on a hardened XML parser.

### Option A: build SAML in-house

Building gives full control at the cost of ongoing maintenance, multi-tenant complexity, and the security burden above. The cost figures that exist are illustrative vendor and practitioner estimates, not an industry consensus, and they disagree: SSOJet models roughly $112,000 to $150,000 in first-year cost (about 320 engineering hours) ([SSOJet](https://ssojet.com/blog/the-hidden-150-000-cost-of-a-simple-sso-feature)); Scalekit puts a from-scratch build at 12 to 16 weeks ([Scalekit](https://www.scalekit.com/blog/build-vs-buy-how-to-approach-sso-for-your-saas-app)); WorkOS estimates about three months for a single IdP plus 10 to 20 hours of onboarding per enterprise customer ([WorkOS](https://workos.com/blog/build-vs-buy-part-i-complexities-of-building-sso-and-scim-in-house)).

### Option B: use a managed authentication provider

For most multi-tenant SaaS teams, a managed provider is the better trade: it gives you per-organization SAML and OIDC connections, certificate handling, IdP- and SP-initiated support, and SCIM, integrated with sessions and tenancy.

[Clerk](https://clerk.com/docs/guides/configure/auth-strategies/enterprise-connections/overview.md) is a strong default for this specific job. It models each customer as an enterprise connection scoped to a domain and, optionally, to a Clerk [Organization](https://clerk.com/glossary.md#organizations), so one customer maps to one Entra tenant. For Microsoft Entra specifically, Clerk emits the Reply URL and Entity ID you paste into Entra, you paste Entra's App Federation Metadata URL back into Clerk, and the required attribute mapping is `emailaddress` to `user.mail` (with `givenname` and `surname` optional) ([Clerk: Add Microsoft Entra ID as a SAML connection](https://clerk.com/docs/guides/configure/auth-strategies/enterprise-connections/saml/azure.md)). [Directory Sync](https://clerk.com/glossary.md#directory-sync) (SCIM) reached GA in April 2026 for Okta and Microsoft Entra ID ([Clerk changelog](https://clerk.com/changelog/2026-04-16-directory-sync.md)); deactivating a user immediately revokes all their active sessions, and there's no separate charge beyond the connection ([Clerk: Directory Sync](https://clerk.com/docs/guides/configure/auth-strategies/enterprise-connections/directory-sync.md)). Clerk also recommends SAML over its multi-tenant EASIE option precisely because _"SAML depends on a single-tenant identity provider,"_ which reduces the risk of one tenant's user reaching another tenant's resources.

A few honest caveats. Clerk's group-to-role and custom-attribute mapping reached general availability in May 2026 ([Clerk changelog](https://clerk.com/changelog/2026-05-21-directory-sync-groups-attributes-ga.md)). Custom-attribute mapping works on any enterprise connection at no extra charge, syncing IdP attributes into the user's `publicMetadata` ([Clerk: Custom attribute mapping](https://clerk.com/docs/guides/configure/auth-strategies/enterprise-connections/custom-attribute-mapping.md)). Group-to-role mapping additionally requires linking the connection to a Clerk Organization, which is part of the **Enhanced B2B Authentication** add-on ($100/mo, or $85/mo billed annually). Connection pricing as of June 2026: paid plans include one enterprise connection, with additional connections metered from $75/mo each (dropping to $60, $30, and $15 at higher volume bands) ([Clerk pricing](https://clerk.com/pricing)).

[WorkOS](https://workos.com/single-sign-on) solves the same problem and is a credible alternative, especially if you want a standalone, pay-per-connection federation layer over auth you already run. It supports 20+ IdPs behind one API, with Directory Sync and a hosted admin portal that lets customers self-configure their IdP. WorkOS meters SSO and Directory Sync per connection (from $125/connection at the entry band down to $50 at higher volume), with the first connection paid, and AuthKit free to 1,000,000 MAU ([WorkOS pricing](https://workos.com/pricing)). Pricing for both is volatile; verify before committing.

### Listing your app in the Microsoft Entra application gallery

Independent of how you build, you can cut per-customer setup work by publishing your app to the Microsoft Entra application gallery, _"a collection of SaaS applications that are preintegrated with Microsoft Entra ID"_ ([Microsoft Learn: Application gallery](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/overview-application-gallery)). Once listed, a customer adds it from **Enterprise apps > New application** with pre-filled metadata and an auto-generated tutorial, instead of the manual "Create your own application" path. Eligibility requires a federation protocol Microsoft lists (SAML 2.0, WS-Federation, or OpenID Connect; SCIM is optional), and you submit through Microsoft's onboarding process rather than the admin center ([Microsoft Learn: List your app](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/v2-howto-app-gallery-listing)). As of June 2026, Microsoft notes it's _"not accepting new SSO or provisioning requests"_ during its Secure Future Initiative, so check intake status before you plan around it.

### When building in-house still makes sense

Honest balance: build it yourself when you have regulatory constraints that rule out a third party, an existing SAML investment and in-house expertise, or a genuinely simple single-tenant need where the multi-tenant problem never arises.

## Performance and operational considerations

A few operational factors move the needle more than the rest.

**Token and session lifetime.** A SAML assertion's `Conditions` window defaults to 70 minutes; the related SAML token lifetime defaults to 1 hour and is configurable from 10 minutes to 23:59:59 ([Microsoft Learn: Configurable token lifetimes](https://learn.microsoft.com/en-us/entra/identity-platform/configurable-token-lifetimes)). You set it through a token lifetime policy (`tokenLifetimePolicy`, property `AccessTokenLifetime`) via the Microsoft Graph REST API or the Microsoft Graph PowerShell SDK (for example `New-MgPolicyTokenLifetimePolicy`); there's no admin-center UI for it. Don't reach for the legacy AzureAD or MSOnline PowerShell modules, which were deprecated on March 30, 2024. Refresh and session lifetimes are now governed by Conditional Access sign-in frequency, whose default is a 90-day rolling window ([Microsoft Learn: Session lifetime](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-session-lifetime)).

**Metadata caching and refresh.** A federation-metadata-consuming SP should cache signing keys with about a 24-hour TTL, refresh the metadata roughly hourly, and refresh immediately when a token arrives signed with an unknown key. That behavior is what makes certificate rollover transparent ([Microsoft Learn: Signing key rollover](https://learn.microsoft.com/en-us/entra/identity-platform/signing-key-rollover)).

**Monitoring.** Watch the Sign-in logs (filter by Application and Status, Authentication protocol = SAML 2.0; capture AADSTS codes and Correlation IDs). Entra Health adds SAML sign-in monitoring (preview, P1/P2) that surfaces three common failure causes, a missing signing certificate, a missing or incorrect Reply URL, and access misconfiguration, as signals to investigate rather than automated alerts ([Microsoft Learn: SAML health monitoring](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/scenario-health-sign-ins-saml-auth)).

**Scale.** The per-app, single-tenant SAML constraint is what pushes SaaS builders toward per-customer connections, which is the reason the service-provider section above matters at scale.

## Conclusion and next steps

Configuring Microsoft Entra ID as a SAML IdP for one SaaS app is a well-trodden path: create the enterprise application, exchange the Identifier, Reply URL, signing certificate, and claims, assign users, and test. The operational weight lands after the first login, in stable NameIDs, certificate rotation, SCIM for the account lifecycle, and the muscle memory to read the AADSTS codes when something breaks.

The decision that actually matters sits on the service-provider side. If you're building a SaaS that has to accept Entra SAML from many customers, the per-customer connection model, the recurring SAML-library CVEs, and the Single Logout and certificate-rotation burden are why most teams reach for a managed provider instead of hand-rolling it. Start from Microsoft's primary documentation for the Entra side, and from [Clerk's enterprise SSO docs](https://clerk.com/docs/guides/configure/auth-strategies/enterprise-connections/overview.md) or a comparable provider for the application side.

## Frequently asked questions

## FAQ

### What is the difference between an identity provider and a service provider in Entra ID SAML?

The identity provider (IdP) authenticates the user and issues a signed assertion; the service provider (SP) consumes that assertion and grants access. In an Entra integration, Microsoft Entra ID is the IdP and your SaaS application is the SP. Almost every configuration question resolves once you know which side you're on.

### What is the Reply URL / ACS URL in Entra ID and where do I find it?

The Reply URL (Assertion Consumer Service URL) is the endpoint where Entra POSTs the SAML response, and you set it in the Basic SAML Configuration blade. You get the value from your SaaS app's SSO documentation. A single Entra app can hold up to 256 Reply URLs, and Entra picks the one that exactly matches the AssertionConsumerServiceURL in the request.

### What is the Identifier (Entity ID) in Entra ID?

The Identifier (Entity ID) uniquely names the service provider and becomes the Audience that the assertion is restricted to. You enter it in the Basic SAML Configuration blade using the value your SaaS app expects. A mismatch produces an AADSTS70001 error.

### Gallery vs. non-gallery enterprise application: which should I use?

Use the gallery app if your SaaS app is listed there, because it ships with preconfigured SSO and a setup tutorial. Use a non-gallery app ("Create your own application") when it isn't listed and configure SAML manually. Both are free; neither requires a P1 or P2 license.

### How do I fix AADSTS50011 (reply URL mismatch)?

Make a registered Reply URL exactly match the AssertionConsumerServiceURL your app sends. Matching is case-sensitive on the URL path and trailing-slash sensitive, so a stray slash or a capitalization difference is a common cause. One app can hold up to 256 Reply URLs, and Entra selects by literal URL match.

### How often do Entra ID SAML signing certificates expire, and how do I rotate them?

Entra's self-signed SAML signing certificate defaults to three-year validity. To rotate without downtime, create a new certificate (it starts Inactive), configure or pre-trust it on the service-provider side, then select "Make certificate active" and retire the old one. Entra publishes both certificates in federation metadata during the overlap, and it emails warnings 60, 30, and 7 days before expiry.

### Which NameID value should I use?

Use a stable, non-reassignable identifier like the persistent NameID or the object ID (objectid), which Microsoft describes as immutable and reuse-safe. Avoid using email as the sole identity key, because it's mutable and Microsoft's nOAuth guidance warns against using it for authorization. Email is fine for display.

### When should I choose SAML over OIDC in Entra ID?

Choose OIDC for new application development, and SAML when you're integrating an existing app that only supports SAML; that's Microsoft's own guidance. Entra fully supports both, and SAML 2.0 has no retirement timeline. Many SaaS catalogs still default to SAML for enterprise SSO.

### Do I need an Entra ID P1 or P2 license for SAML SSO?

No. Basic SAML SSO for enterprise apps, including custom non-gallery "Create your own application" apps, is included in Microsoft Entra ID Free; you only need an admin role. P1 adds Conditional Access, group-based assignment, group provisioning, and provisioning logs, and P1 or P2 adds SAML token encryption.

### What is the difference between IdP-initiated and SP-initiated SSO, and which is safer?

In SP-initiated SSO the user starts at your app, which sends a request that the response is bound to via InResponseTo; in IdP-initiated SSO the user starts from a tile in Entra with no prior request. SP-initiated is safer because that binding gives login-CSRF and replay protection that IdP-initiated lacks. A well-built SaaS app supports both but defaults to SP-initiated.

### How is SCIM provisioning different from SAML SSO (and from JIT)?

SAML and OIDC authenticate users; SCIM provisions and deprovisions accounts out of band over REST. SAML just-in-time (JIT) provisioning creates an account from the claims in the assertion at first login, so it hits Entra's 150-group SAML claim cap and can't deprovision. SCIM syncs independently of the assertion and removes access when a user leaves the directory.

### How do I test a SAML integration in Entra ID?

Use the "Test single sign-on" button on the app's SAML page (it's greyed out until you save the Basic SAML Configuration). Install the My Apps Secure Sign-in Extension for Chrome or Edge to capture the request and response, and use SAML-tracer or the sign-in logs for deeper inspection. Assign your test user first, or you'll get AADSTS50105.

### Why does a user get "user not found" after a successful SAML sign-in?

Authentication succeeded but the NameID or attribute Entra sent doesn't match how the application stores that user (for example, the app expects email but Entra sent the UPN). Fix it by adjusting the Unique User Identifier claim in the Basic SAML Configuration to match what the service provider expects. This is a mapping problem, not a signing problem.

### How long is an Entra ID SAML assertion valid?

The assertion's Conditions window defaults to 70 minutes (NotOnOrAfter is 70 minutes after NotBefore). The related SAML token lifetime defaults to 1 hour and is configurable from 10 minutes to 23:59:59 through a token lifetime policy set via Microsoft Graph. The short bearer window in SubjectConfirmationData (about 5 minutes) is separate.

### How do I let my own SaaS app accept SAML logins from customers' Entra tenants?

Your app is the service provider: it needs an ACS endpoint, full assertion validation, per-customer connection storage, certificate-rotation handling, and both IdP- and SP-initiated support. You can build this against a library or use a managed provider that exposes per-organization SAML connections. Most teams use a managed provider because the validation and multi-tenant work is easy to get subtly wrong.

### How do I support many customers' Entra tenants at once (multi-tenant SAML)?

You need a separate SAML connection per customer, because Entra greys out SAML SSO on multi-tenant applications and configures it per single-tenant app. Map each customer to an organization, store its tenant's metadata and certificate, and route users to the right connection by email domain. A managed provider like Clerk or WorkOS handles the per-customer connection model for you.

### How do I test SCIM provisioning without waiting for the 40-minute cycle?

Use the "Provision on demand" button on the app's Provisioning blade to sync a single user immediately, typically in under 30 seconds, and read the per-user step trace to see why a user is skipped. It does one user at a time (groups up to 5 members), the user must already be assigned and in scope, and the app needs an automatic SCIM connector configured. It needs only the Application Administrator role.

### How do I require signed SAML authentication requests in Microsoft Entra ID, and what stops working if I do?

Upload the SP's signing public key under Single sign-on > SAML Certificates > Verification certificates and enable "Require verification certificates." It's off by default, applies to SP-initiated requests only, accepts only RSA-SHA256-signed requests, and disables IdP-initiated SSO, including the portal Test button, the My Apps portal, and the Microsoft 365 launcher. Treat it as an optional hardening control, not a default.

### Does Microsoft Entra ID support SAML Single Logout (SLO), and why is it hard to implement?

Yes, over front-channel HTTP Redirect only at `https://login.microsoftonline.com/<tenant>/saml2`, with no back-channel SOAP binding. It's hard on the service-provider side because you must also handle inbound LogoutRequests, map each SAML session to a local one, and accept that front-channel logout is best-effort (OASIS: "the result of the logout process cannot be guaranteed"). Entra also ignores the NameID you send on logout, so DIY code needs Entra-specific handling.
