Single Sign-On isn't a monolithic authentication problem, it's a modular capability that evolves differently than the rest of your auth infrastructure.
We're seeing consistent patterns: companies that built on AWS Cognito hit scaling walls when enterprise SSO demands grow. Teams on Auth0 face pricing pressure as their customer count increases, but don't want to migrate their entire user authentication system, just SSO. Others built custom auth for specific user flows and now need enterprise SSO without maintaining SAML/OIDC complexity in-house.
SSO needs to be modular. You should be able to add, change, or upgrade your SSO layer without touching the rest of your authentication infrastructure.
But here's what makes SSO migration different: you can't just swap out code on your end. Each enterprise customer has configured their identity provider: Okta, Azure AD, Google Workspace, to work with your current setup.To understand why, consider how SSO establishes trust between your application and your customer's identity system. Whether using SAML or OIDC, the IdP and Service Provider exchange user information through predetermined parameters: Entity IDs, callback URLs, certificates for SAML; Client IDs, Redirect URIs, and Discovery endpoints for OIDC.
Your customers configure these parameters once in their identity provider. The problem emerges when you want to change SSO providers. All those configured parameters are tied to your current provider. To switch providers, every customer needs to reconfigure their IdP with new values. And since you can't control your customers' identity providers, you can't automate this change. Each customer must manually update their configuration, which requires coordination, testing, and deployment windows on their side.
We built a migration method that eliminates customer-side reconfiguration entirely. Through DNS redirection and smart proxying, you can move SSO connections from Auth0, WorkOS, Firebase, or AWS Cognito to Scalekit while your customers keep their existing IdP settings unchanged.
Here's what makes it work:
The DNS redirect layer
Your auth domain (like auth.yourapp.com) already points to your current provider. We help you add a proxy layer at that domain that examines each authentication request and routes it to the right provider.
Smart organization mapping
You maintain a simple mapping of which organizations have migrated to Scalekit versus those still on your old provider. The proxy checks this mapping on every authentication request.
Transparent routing
When a user initiates SSO login, the proxy routes migrated organizations to Scalekit and unmigrated ones to your existing provider. Users see no difference—same login flow, same experience.
Preserved IdP configuration
Because Scalekit accepts the same Entity IDs and ACS URLs your customers already configured in their IdP, their settings don't change. The SAML or OIDC responses flow through the proxy to Scalekit exactly as they did to your previous provider.
Let's walk through a real migration scenario from Auth0 to Scalekit.
Your company, ExampleCorp, has 50 enterprise customers using SSO through Auth0. Each customer has configured their Okta, Azure AD, or Google Workspace to send SAML assertions to auth.examplecorp.com/saml/callback with Entity ID auth.examplecorp.com.
You configure Scalekit to accept the same Entity ID and ACS URL that Auth0 currently uses. This means when a customer's IdP sends a SAML response, Scalekit can process it using the exact parameters already configured in their IdP.
You deploy a lightweight proxy at your auth domain. We provide ready-to-deploy implementations for AWS Lambda, Cloudflare Workers, or your existing infrastructure.
When a user from acmecorp.com tries to log in, your application initiates SSO as usual:
After the user authenticates at their IdP, the SAML response returns to auth.examplecorp.com/saml/callback.
The proxy examines the response, determines it came from a migrated organization, and forwards it to Scalekit for processing.
Your callback handler receives the authorization code and exchanges it for user details—exactly as before, just from a different provider: