Skip to content
Ashish.
All posts
Diagram illustrating an identity orchestrator acting as a central state machine between user agents and multiple identity providers.

Building Identity Orchestration: Connecting Multiple IdPs with Custom Workflows

An examination of building identity orchestration to connect multiple identity providers through custom authentication workflows.

By Ashish KumarPart 4 of Identity Platform Architecture

The State Machine of Identity

Identity orchestration is often mischaracterized as a simple load balancer for authentication requests. It is not. It is a stateful protocol transformer that sits between the user agent and the identity providers (IdPs), acting as a central nervous system that observes, decides, and directs the flow of credentials. To build this, you must first understand the mechanism of interception.

Consider a user, alice, attempting to access a SaaS application. In a standard setup, the application redirects alice directly to IdP-A because her tenant ID matches a hardcoded rule. In an orchestrated architecture, alice hits the Orchestrator endpoint. The Orchestrator does not immediately redirect. Instead, it initiates a "protocol-agnostic handshake." It captures the request parameters—specifically the client_id, redirect_uri, and any initial login_hint—and pauses the flow. At this exact moment, the Orchestrator holds the state of the transaction in its own ephemeral memory, independent of the downstream IdP.

This decoupling is critical. By intercepting the request, the Orchestrator gains the ability to inspect the full context before committing to a specific identity provider. It can see the user's IP address, the User-Agent string, and the time of day. This visibility allows the system to make a decision that a standard IdP cannot make alone. The mechanism here is the separation of routing logic from identity storage.

The Mechanism of Interception

The first step in building an identity orchestration layer is establishing the interception point. This component acts as a protocol-agnostic handshake, capturing the initial request before it reaches a specific provider. This effectively decouples the user from the backend identity logic.

To achieve this, the Orchestrator must intercept the user's browser request directly, typically via a reverse proxy or by acting as the redirect target for the application. This ensures the Orchestrator can pause the flow at the browser level, rather than merely capturing parameters while the user is redirected. The distinction is vital: a passive proxy forwards traffic, whereas a broker actively manages the session state.

When the Orchestrator receives the request, it extracts the necessary parameters and stores the transaction state in ephemeral memory. This allows the system to pause the flow and inspect the context. The Orchestrator can analyze the request parameters, such as client_id, redirect_uri, and login_hint, without committing to a specific identity provider.

By intercepting the request, the Orchestrator gains full visibility into the user's context. It can inspect the user's IP address, the User-Agent string, and the time of day. This visibility enables the system to make decisions that a standard IdP cannot make alone. The core mechanism is the separation of routing logic from identity storage, allowing the Orchestrator to act as a central control point.

Contextual Routing as a Function

Once the Orchestrator has captured the initial request, it executes a decision function. This is where the "orchestration" becomes active. The system does not rely on static rules like "Route all users from Europe to IdP-EU." Instead, it evaluates a composite of signals.

Imagine alice logs in from a corporate device on the internal network. The Orchestrator detects the corporate subnet and the presence of a specific browser cookie indicating a trusted session. The decision function evaluates these inputs:

  1. Source IP: Matches 10.0.0.0/8 (Corporate).
  2. Device Fingerprint: Matches known enterprise devices.
  3. User Attribute: alice belongs to the Engineering group.

Based on this, the Orchestrator selects IdP-Internal (e.g., Azure AD). Now, imagine alice logs in from a public coffee shop. The Orchestrator detects the public subnet and the absence of the trusted cookie. The decision function re-evaluates:

  1. Source IP: Public range.
  2. Device Fingerprint: Unknown.
  3. User Attribute: Same Engineering group.

The Orchestrator now routes alice to IdP-Social (e.g., Google) or a dedicated external IdP, perhaps triggering a stricter verification flow. This dynamic routing is the core value proposition. It allows the enterprise to enforce different security postures for the same user depending on the context, without requiring the user to manage multiple accounts or the application to know the routing logic.

The mechanism relies on the Orchestrator maintaining a unique correlation token that persists across the redirections. When the user is redirected to IdP-Internal, the Orchestrator passes the standard state parameter (for OIDC) or RelayState (for SAML) as a parameter. When the IdP completes authentication and redirects back, it returns this standard parameter. The Orchestrator then resumes the paused state, knowing exactly where to pick up the flow.

Technical diagram showing an identity orchestrator acting as a central hub between a user agent and multiple identity providers (IdP-A, IdP-B, IdP-C). The diagram should illustrate the "interception" phase where the orchestrator pauses the flow, inspects context (IP, User-Agen…

Protocol Normalization and State Bridging

The most complex mechanism in identity orchestration is handling the fragmentation of protocols. Different IdPs speak different languages. One speaks SAML 2.0, another speaks OpenID Connect (OIDC), and a legacy system might use legacy CAS. The Orchestrator must normalize these interactions.

When the Orchestrator decides to route to IdP-SAML, it constructs a SAML AuthnRequest. It signs this request using the Orchestrator's certificate and sets the AssertionConsumerServiceURL (ACS) to the Orchestrator's own endpoint, not the application's. This is the "proxy" pattern. The application remains unaware of the IdP; it only talks to the Orchestrator. The Orchestrator is fully aware of the IdP's protocol details to perform normalization, while the application sees only a consistent interface.

When IdP-SAML responds, it sends a signed SAML assertion back to the Orchestrator's ACS endpoint. The Orchestrator verifies the signature, decrypts the assertion, and extracts the user attributes (NameID, Email, Groups). Crucially, the Orchestrator does not stop there. If the downstream application expects OIDC, the Orchestrator must transform the SAML assertion into an OIDC ID Token and a set of claims compatible with the application's schema.

This transformation is not trivial. SAML attributes are often structured differently than OIDC claims. The Orchestrator must map saml:emailAddress to oidc:email and handle name format differences (e.g., urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress). The mechanism here is a schema mapping engine that runs in memory. It ensures that regardless of the upstream IdP, the downstream application receives a consistent, normalized token.

If the Orchestrator fails to normalize correctly, the application will reject the token, breaking the chain. Therefore, the state management must be robust. The Orchestrator must store the original AuthnRequest parameters and the resulting Assertion until the final token is issued to the application. This ensures that the round-trip is atomic.

Custom Workflow Injection

The true power of orchestration emerges when you inject custom logic into the flow. Standard IdPs offer limited customization. An Orchestrator allows you to run arbitrary code at specific points in the authentication lifecycle.

Consider a scenario where alice is logging in from a high-risk location. The Orchestrator detects the risk score is above 80. Instead of simply blocking or allowing, it triggers a custom workflow. The Orchestrator pauses the flow and calls an external API, auth-service/mfa-enforce. This service generates a one-time password (OTP) and sends it via SMS to alice.

The Orchestrator updates its session state to waiting_for_mfa. It redirects alice to a custom UI hosted by the Orchestrator that prompts for the OTP. When alice enters the code, the Orchestrator validates it against the SMS provider. Only upon successful validation does the Orchestrator resume the flow and redirect alice to the selected IdP.

Hosting a custom UI breaks the passive proxy model described earlier; it requires the Orchestrator to act as an active participant (a Service Provider or interactive broker) that manages the user interface and session state directly. This mechanism allows for "step-up" authentication that is impossible with a standard IdP configuration. You can also inject logic to enrich user attributes. For example, before redirecting to IdP-Internal, the Orchestrator could query a HR database to check if alice is currently active. If she is terminated, the Orchestrator blocks the flow immediately, returning a generic error to the application without ever exposing the specific reason to the IdP.

The custom workflow is executed as a script or a microservice call. The Orchestrator acts as the controller, passing the current context (user attributes, request metadata) to the script. The script returns a decision object: { action: "continue", next_step: "mfa" } or { action: "block", reason: "account_disabled" }. This makes the authentication flow programmable.

Flowchart diagram illustrating a custom workflow injection in an identity orchestration system. Show the orchestrator detecting a high-risk login, pausing the flow, calling an external MFA API, displaying a custom UI for OTP entry, and then resuming the flow to the IdP. Use a …

Architectural Tradeoffs

Building this orchestration layer introduces latency. Every request now passes through an additional hop, which must parse, validate, transform, and route. In a high-throughput environment, this can become a bottleneck. The mechanism for mitigating this is caching. The Orchestrator can cache the routing decision for a specific user-session combination for a short duration (e.g., 5 minutes), reducing the need to re-evaluate the decision function for every subsequent request in the same session.

Another tradeoff is complexity. You are now managing the state of the authentication flow yourself. If the Orchestrator crashes during the middle of a SAML handshake, the user is left in a broken state. The system must implement durable state storage, such as Redis or a database, to persist the session state across restarts. This adds operational overhead compared to a simple IdP redirect.

However, the flexibility gained is substantial. You can integrate legacy systems that do not support modern protocols, you can enforce granular policies based on real-time context, and you can decouple the identity provider strategy from the application logic. The Orchestrator becomes the single point of truth for identity routing, allowing the enterprise to swap out IdPs without changing the application code.

In summary, identity orchestration is a mechanism of control. It transforms the rigid, linear flow of authentication into a dynamic, state-driven process. By intercepting requests, normalizing protocols, and injecting custom logic, it provides the agility needed for modern enterprise security architectures. The cost is increased complexity, but the reward is a system that can adapt to the user's context in real-time.

Conclusion

Identity orchestration represents a shift from passive routing to active state management. By intercepting requests, evaluating contextual signals, and normalizing disparate protocols, the Orchestrator provides a flexible layer that adapts to the dynamic needs of modern security architectures. While it introduces latency and operational complexity, the ability to enforce granular policies and inject custom logic makes it an essential component for enterprises managing multiple identity providers.

Common Pitfalls

  • State Management Failures: Relying solely on in-memory state without durable storage can lead to broken sessions if the Orchestrator restarts mid-flow.
  • Latency Bottlenecks: Failing to implement caching for routing decisions or protocol transformations can degrade performance under high load.
  • Single Point of Failure: Treating the Orchestrator as a simple pass-through rather than a critical service node can result in total identity service outages if the Orchestrator goes down.

Practical Takeaways

  • Separation of Concerns: Always decouple the routing logic from the identity storage; the Orchestrator knows where to send, but the IdP knows who the user is.
  • Standardize Correlation: Never invent custom session IDs for IdP correlation; strictly use standard state (OIDC) and RelayState (SAML) parameters.
  • Active vs. Passive: Determine early if your Orchestrator acts as a passive proxy or an active broker, as this dictates the UI and session handling architecture.

FAQ

Q: Can I use identity orchestration with legacy SAML IdPs? A: Yes. The Orchestrator can act as a bridge, accepting modern OIDC requests from the application and translating them into legacy SAML requests for the backend IdP, handling the normalization transparently.

Q: Does the application need to know about the Orchestrator? A: The application must be configured to redirect users to the Orchestrator's endpoint instead of the IdP directly. However, the application remains unaware of which specific IdP is being used for the final authentication.

Q: How do I handle session timeouts during custom MFA workflows? A: Implement a robust state store (like Redis) that persists the waiting_for_mfa state. Configure the Orchestrator to extend the session timeout dynamically while the user is interacting with the custom MFA UI.

Related posts