Skip to content

Tenant identification is easy to treat as a routing detail. In practice, it is one of the first product decisions in an enterprise SaaS login flow.

Before ProAuth can send a user to the right federated identity provider, apply tenant-specific login views, or validate tenant-level configuration, it needs to know which tenant the authentication request belongs to. That decision usually happens before the user has authenticated. The SaaS application knows the customer context from the URL, the customer network, or the way it builds the OpenID Connect request. ProAuth turns that context into the tenant pipeline used for the rest of the login.

The earlier tenant identification deep dive shows a concrete subdomain-based setup. This post looks at the design patterns behind that setup: subdomains, route segments, IP ranges, and the OpenID Connect acr_values tenant hint.

Why tenant discovery comes before authentication

In a single-tenant application, the login URL can be static. The application redirects every user to the same issuer, the same client configuration, and the same identity provider selection.

Enterprise SaaS login works differently. Two users may open the same SaaS product but belong to different customers, each with its own federation target, branding, user lifecycle model, and security policy. The application should not need customer-specific authentication code for each of those differences. It should be able to redirect to ProAuth with enough context for ProAuth to select the tenant-specific configuration.

Once the tenant is known, ProAuth can use the tenant pipeline for the request. That pipeline can then use the configured tenant, client application, and IdP instance relationships. If a tenant has a dedicated federated IdP for the application, the flow can route users directly to that tenant’s identity provider instead of asking them to choose from unrelated options.

The important design question is where the tenant signal should come from.

flowchart TD
    A["User starts login from SaaS application"] --> B{"Where is the tenant context strongest?"}
    B -->|Customer-facing URL| C["Subdomain: tenantkey.app.example"]
    B -->|Shared host with tenant path| D["Route segment: app.example/tenantkey"]
    B -->|Known internal network| E["IP range assigned to tenant"]
    B -->|Client controls OIDC request| F["acr_values: tenant:{tenant-id}"]

    C --> G["Registered redirect URI uses {{tenantkey}} or {{tenantid}}"]
    D --> G
    E --> H["Configured tenant IP ranges are evaluated from the request address"]
    F --> I["Authorization request carries the tenant id explicitly"]

    G --> J["ProAuth resolves tenant pipeline"]
    H --> J
    I --> J
    J --> K["Apply tenant-specific IdP, claims, and login experience"]

Pattern 1: tenant-specific subdomain

A tenant-specific subdomain is the most visible pattern:

https://contoso.app.example.com/signin-oidc

In ProAuth, the client application’s redirect URI can use the tenant key or tenant id placeholder:

https://{{tenantkey}}.app.example.com/signin-oidc
https://{{tenantid}}.app.example.com/signin-oidc

When the application sends a redirect URI such as https://contoso.app.example.com/signin-oidc, ProAuth can match the placeholder and resolve the tenant. The ProAuth documentation describes the supported placeholders as {{tenantkey}} and {{tenantid}}, and notes that the redirect URI and placeholders must be lowercase.

This is a strong fit when each customer already gets a branded or customer-specific application URL. It is also easy for users to understand: the URL itself carries the tenant context before login starts.

The tradeoff is operational. Customer onboarding needs DNS, certificate coverage, and redirect URI registration to be part of the rollout checklist. That is usually a good trade for external enterprise customers, but it is still a trade.

Pattern 2: tenant route part

A route segment keeps all tenants on one host while still making the tenant visible in the URL:

https://app.example.com/contoso/signin-oidc

The same redirect URI placeholder model applies:

https://app.example.com/{{tenantkey}}/signin-oidc
https://app.example.com/{{tenantid}}/signin-oidc

ProAuth also exposes tenant-specific issuer routes where the tenant id or tenant key is the first path token of the ProAuth URL:

https://idp.example.com/contoso
https://idp.example.com/00000000-0000-0000-0000-000000000000

Route-based tenant discovery is useful when subdomains are expensive to operate or when the application already has a tenant-aware path structure. It is often simpler for local development, internal tools, and environments where wildcard DNS or certificate automation is not available.

The main caution is consistency. The route segment has to be treated as part of the tenant contract. If the application lets users move between tenant routes without restarting the authentication request, the login flow can become ambiguous. Keep the tenant path stable from the application entry point through redirect URI registration.

Pattern 3: IP-range routing for internal tenants

IP-range routing is a different kind of signal. Instead of reading the tenant from the URL or request parameters, ProAuth can match the request address against configured tenant IP ranges.

This is mostly useful for internal tenants or controlled network scenarios: an employee portal, an operations console, or an appliance-style deployment where requests originate from known networks. The 2022 tenant article describes it as a pattern for cases where login should only be possible while the user is inside the company’s LAN.

Use this pattern carefully for public SaaS onboarding. IP addresses can change, users may work remotely, and reverse proxies can hide the original client address unless forwarding is configured and trusted correctly. IP ranges are best when the network boundary is genuinely part of the product model, not when it is used as a shortcut for customer discovery.

Pattern 4: OIDC acr_values tenant hint

When the client application can build the OpenID Connect authorization request itself, it can pass the tenant id explicitly through acr_values:

acr_values=tenant:00000000-0000-0000-0000-000000000000

OpenID Connect defines acr_values as an optional request parameter for requested authentication context values. ProAuth uses a tenant:<Tenant ID> value to identify the tenant for the authentication flow.

This pattern is useful when the tenant is known inside the application but is not part of the URL. It also helps with clients that cannot easily use tenant-specific redirect URIs. Because the tenant id is a protocol parameter, it should be generated by trusted application code, not typed by users.

The downside is discoverability. A support engineer can see a subdomain or route segment in a browser URL. An acr_values hint is hidden inside the authentication request. That is fine for controlled clients, but it means logging and troubleshooting should preserve enough request context to explain why a user was routed to a tenant.

Choosing the pattern

Most SaaS platforms do not need every pattern on day one. They need one default pattern that matches the onboarding model, plus a documented exception path for special customers.

PatternBest fitCustomer setup effortOperational fitMain caution
SubdomainExternal SaaS customers with branded or customer-specific URLsDNS, certificates, redirect URI registrationClear user experience and clean tenant separation in URLsRequires disciplined onboarding automation
Route segmentShared host applications, internal portals, environments without wildcard DNSRedirect URI registration and route consistencySimple to test and operate on one hostTenant route must stay stable through login
IP rangeInternal tenants and controlled networksAccurate tenant IP ranges and proxy/network ownershipWorks when network location is a real trust boundaryWeak fit for roaming users and public SaaS traffic
acr_valuesClients that know the tenant but cannot express it in the URLClient code must add tenant:<Tenant ID>Precise protocol-level hintHarder to inspect manually during support

A practical onboarding checklist

For each tenant onboarding flow, decide the tenant identification pattern before configuring the IdP instance. That order matters because the redirect into ProAuth and the return from the customer IdP both depend on stable URLs.

Check the following:

  1. Which tenant signal will the SaaS application provide: subdomain, route segment, IP range, or acr_values?
  2. Does the client application have the right redirect URI registered, including {{tenantkey}} or {{tenantid}} placeholders when needed?
  3. Is the tenant key stable enough to appear in URLs, support tickets, and customer documentation?
  4. Is the tenant allowed to use the client application if tenant restrictions are configured?
  5. Is the tenant’s IdP instance assigned to the tenant and ready to receive the user?
  6. Can support teams see enough context in the URL, request, or logs to explain the routing decision?

Tenant identification is not only about reaching the correct pipeline. It is about making customer onboarding repeatable. A good pattern lets the application keep one trust relationship to ProAuth while ProAuth handles tenant-specific federation, claims, and login experience at runtime.

Further reading: