Share via

Opinions on Entra security architecture for SaaS

Philip Hendry 110 Reputation points
2026-04-06T14:23:08.0866667+00:00

I manage a SaaS application that comprises an asp.net core web api and React SPA frontend with authentication managed by a custom solution. I'm migrating that security system to Entra managed but would like opinions on the architecture I've chosen.

I've created an Entra External ID (CIAM) tenant to handle the following account types:

  • Local accounts: email/password sign-up
  • Social accounts: Google
  • Non-Entra B2B SSO registered as SAML or OIDC custom identity providers.

Initially I had hoped to federate our own Entra Workforce tenants so our employees can log in but neither SAML nor OIDC federation is possible Entra-to-Entra so instead I've configured our workforce tenant as another issuer of tokens my API validates. In addition I've created an app registration in this tenant that is a multi-tenant application and therefore other external Entra tenants, once white-listed, can sign in.

This split between workforce and CIAM tenants does complicate the code slightly but also seems to have overcome all the issues I faced with trying to define it all in just the CIAM tenant.

I've also turned on the Native Authentication API so I could build my own login page since, even though the Microsoft pages can be branded, the user journey was awkward to control - especially when needing to decide between two different MSAL instances to use (one for CIAM and the other for workforce.)

Does this sounds like a reasonable architecture? Has anyone been using something similar to deliver a SaaS to the range of account types I've listed above?

Microsoft Security | Microsoft Entra | Microsoft Entra ID

Answer accepted by question author

  1. Shubham Sharma 15,675 Reputation points Microsoft External Staff Moderator
    2026-04-13T15:57:47.9866667+00:00

    Hello Philip Hendry

    Thank you for the reply.

    Yes- If you collapse everything into the CIAM tenant and rely only on OIDC‑federated external IdPs, then:

    • Each external Entra tenant would need its own OIDC identity provider configuration
    • That means:
      • Separate metadata endpoints
      • Separate client registrations
      • Separate issuer validation paths
    • This does not scale well for B2B SaaS onboarding

    For your reference: https://learn.microsoft.com/en-us/entra/external-id/customers/how-to-custom-oidc-federation-customers

    By contrast, the current model using:

    • A multi-tenant workforce app registration
    • Allowing external Entra tenants to consent
    • Trusting those tenants as token issuers directly in your API

    is still the most scalable solution for onboarding many enterprise customers quickly.

    That pattern exists explicitly to avoid the “custom IdP per tenant” problem.

    I don’t want a button per IdP — what is actually supported?

    This is the real pain point in Entra External ID today, and your experience matches the platform limitations precisely.

    What Entra External ID supports out-of-the-box

    Identity providers must be:

    Explicitly registered

    Explicitly enabled on a user flow

    Each IdP appears as a UI option/button in the user flow

    There is no first-class “home realm discovery” (HRD) like classic ADFS

    “Silent discovery of the correct IdP based on email domain”

    Not supported today in External ID user flows

    3. Can Entra auto-provision users from federated IdPs?

    Yes — but only during sign-in, not via Graph

    When a user signs in through a federated OIDC or SAML IdP, Entra External ID will:

    Automatically create a local representation of that user

    Apply claims mapping you defined

    Link the external identity to the user object

    This is not SCIM and not Graph-driven provisioning — it’s sign-in‑time provisioning

    You do NOT need Graph API just to create the user

    4. Why the “no button per IdP” scenario is so hard

    Below are the options: -

    Option A – Domain-based routing in your own UI (most common)

    Since you are already using Native Authentication / custom UI, the cleanest approach is:

    User enters email

    You inspect the domain (@acme.com)

    You decide:

    Workforce tenant

    Multi-tenant Entra app

    External OIDC IdP

    You initiate the correct auth flow directly

    Without exposing multiple buttons

    This is not built into Entra, but fully supported when you own the UX

    This avoids:

    Buttons for each IdP

    Graph hacks

    SCIM complexity

    Option B – One multi-tenant Entra path for all enterprises

    Many SaaS platforms simplify by saying:

    “All enterprise customers use Entra ID. Non-Entra customers use local or social.”

    This lets you:

    Keep one enterprise sign-in button

    Let Entra handle tenant selection & consent

    Avoid custom IdPs entirely

    Not always acceptable — but massively simpler.

    Option C – Graph API / SCIM before sign-in

    This is not recommended for your scenario because:

    Graph cannot pre‑provision users before authentication context exists

    SCIM is for lifecycle management, not auth-time discovery

    You still wouldn’t know which IdP to use until the user authenticates

    Key limitation to be aware of with Native Authentication

    One important call‑out from the docs:

    Native authentication does NOT support federated identity providers yet

    (Enterprise or social sign-in still requires browser-based auth)

    https://learn.microsoft.com/en-us/entra/identity-platform/concept-native-authentication

    So:

    Native Auth - for local accounts

    Browser redirect - still required for enterprise / OIDC IdPs

    This doesn’t invalidate the architecture — but it does mean your routing logic must handle two paths cleanly.

    Was this answer helpful?

    1 person found this answer helpful.
    0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.