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="https://api.descope.com/sso/setup/<your-project-id>?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.
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 on the SSO config applies to both SCIM and JIT for that connection.
Flows
After a user signs in, lastAuth.ssoId holds the SSO configuration used for that login. You can branch the flow on it (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.