Multiple SSO Providers Per Tenant
Most tenants need one IdP. Some need several on the same tenant, for example Acme's corporate Okta plus a contractor Entra directory, or regional IdPs under one customer org.
That is what this page covers: multiple SSO configurations on one tenant, each with its own ssoId. It is not the same as “each customer gets a tenant with one IdP” (that’s ordinary multi-tenant SSO).
When You Need This
Use additional SSO configs when:
- One customer org authenticates through more than one IdP
- Different email domains under the same tenant must hit different IdPs
- You want a separate SCIM pipeline per IdP
- Admins should configure each connection in its own SSO Setup Suite link
If every customer is a separate org with one IdP, create one tenant per customer instead. See the B2B guide and SSO overview.
Default vs Additional Configurations
Every tenant has a default SSO configuration. You can add more profiles in the Console or via the Management API/SDK. Each additional profile has an ssoId you use when starting SSO, loading settings, or generating a Setup Suite link.

You can also generate a dedicated SSO Setup Suite link per configuration (pass ssoId when generating the link).

How Users Reach the Right IdP
Domains on Each SSO Config
Assign SSO domains on each configuration (not only on the tenant). Descope uses the user’s email domain to pick the matching connection when you start SSO with the tenant and don’t pass an ssoId.
Example under tenant Acme:
| SSO config | SSO domains | IdP |
|---|---|---|
| Default | acme.com | Acme Okta |
contractors | acme-contractors.com | Contractor Entra |
A user signing in as alex@acme.com is routed to Okta. A user signing in as sam@acme-contractors.com is routed to Entra.
Pass ssoId Explicitly
When domain routing isn’t enough (shared domains, picker in your UI, deep link to a specific IdP), pass the configuration id when you start SSO.
Backend SDK (optional sso_id / ssoId on start, shown in SSO with Backend SDKs):
resp = descope_client.sso.start(
tenant="acme-tenant-id",
return_url="https://app.example.com/sso/callback",
sso_id="contractors", # optional; omit to use domain routing / default
)Management SDK. Load or delete a specific profile with ssoId:
const ssoSettings = await descopeClient.management.sso.loadSettings('tenantId', 'contractors');Full surface: Configure SSO with SDKs.
SSO Setup Suite embed. Append ?ssoId=... so the iframe opens that profile (embed guide):
<iframe
src="__BaseURL__/sso/setup/__ProjectID__?ssoId=contractors"
...
></iframe>Tenant Slug / ID Still Applies
You still identify the tenant first (SSO domain, tenant slug/ID, or flow tenant param). Multi-SSO then picks which IdP inside that tenant. See Tenant identification.
Authentication-Only Connections
A connection classified as authentication only verifies someone at the IdP and returns the attributes, with no Descope user and no session. Use it when one tenant has two populations: people who should use the app, and people you only need to identify.
That is the same outcome as the SSO / Authenticate Only flow action, except the connection forces it for every login through that config, whichever SSO action the flow uses.
Example under tenant Acme:
| SSO config | Purpose | Result of a sign-in |
|---|---|---|
| Default | Application login | A user is created or updated, and a session is issued |
verification | Authentication only | The IdP attributes are returned, no user, no session |
You can classify a connection in three places:
- In the Console, turn on Authentication Only on the tenant's SSO configuration.
- In a flow, use the SSO / Create SSO Configuration action and set Authentication only. That is how a tenant administrator creates one through the tenant profile widget, in a flow you author.
- Through the Management API, set
authenticationOnlyon the connection's SSO settings. See Configure SSO with SDKs. Classify the connection when you create it; change it afterwards in the Console or the API.

The SSO Setup Suite reads the classification and adapts to it, but never sets it.
Routing is what to watch, and it differs between the two kinds of connection. The example above is the tenant's default connection, which keeps its SSO domains:
- On an additional connection, leave its SSO domains empty, so email-domain routing never sends a regular login to a connection that returns no session.
- On the default connection, as pictured, you cannot route around it that way: a regular sign-in matching no other connection falls back to it and comes back without a session. Pass the
ssoIdof a login-enabled connection for those sign-ins.
SCIM per SSO Configuration
SCIM is tied to each SSO configuration, not only the tenant. Each IdP can have its own SCIM base URL and token under that profile. Group → role mapping for that connection applies to both SCIM and JIT, and is configured in that configuration's Roles & Groups tab - select the SSO profile first - rather than per SSO method. The mapping is shared across the SAML and OIDC methods of one configuration, not across configurations, so a tenant with several profiles still maps groups once per profile.
Flows
After a user signs in, lastAuth.ssoId holds the SSO configuration used for that login. After an authentication-only connection, ssoAuthenticationOnly is true, so the same flow can send those logins to a verified-identity screen instead of the app. See dynamic keys.
Checklist
- Create the default SAML/OIDC connection on the tenant (Console or Setup Suite).
- Add another SSO configuration and note its
ssoId. - Put the right SSO domains on each config, or plan to pass
ssoIdfrom your app. - Map attributes and groups on each config (SSO mapping).
- If you use SCIM, configure it under each SSO profile that needs directory sync.
- Test each connection (Setup Suite test, or Mock SAML for a non-prod profile).
- Ship start/exchange with the tenant id, and
ssoIdwhen domain routing isn’t enough.
Related
- SSO overview
- SSO / Authenticate Only
- SSO Setup Suite
- Configure SSO (Management SDKs)
- SCIM multi-SSO
- SSO troubleshooting