Skip to content
Scalekit Docs
Go to Dashboard

Migrate SSO without IdP reconfiguration for customers

Single Sign-On capability of your application allows users in your customer’s organizations to access your application using their existing credentials. In this guide, you will migrate SSO connections to Scalekit without requiring customers to reconfigure their identity providers from their existing SSO provider solutions such as Auth0 or WorkOS.

  1. You control DNS for your auth domain, and its CNAME points to your external SSO provider. Diagram
  2. Scalekit is set up — you have signed up and installed the Scalekit SDK.

Our main goal is to make sure your current SSO connections keep working seamlessly, while enabling new connections to be set up with Scalekit—giving you the flexibility to migrate to Scalekit whenever you’re ready.

This primarily involves two key components:

  1. The data migration of tenant resources such as organizations and users. We provide a data migration utility to automate this approach.
  2. A SSO proxy service that routes SSO connections between your existing SSO provider and Scalekit. We can assist with a ready-to-deploy SSO proxy service that best suits your infrastructure.
SSO proxy sequence diagram

The SSO proxy ensures those connections continue to work while you gradually migrate. This approach is ideal when you prefer a staged rollout—move organizations one by one or all at once with data migration utilty without forcing customers to reconfigure SSO connection settings in their IdP.

Proxy routes SSO requests to external providers or Scalekit

Section titled “Proxy routes SSO requests to external providers or Scalekit”

The SSO proxy acts as a smart router that directs authentication requests to the right provider. It sits between your application and both SSO systems, making migration seamless.

  1. Provider selection

    Your app sends login requests with user information (email, domain, or organization ID). The proxy analyzes this data and routes authentication to either the external provider or Scalekit.

  2. Redirection to proxy domain

    Users are redirected to your proxy domain (e.g., auth.yourapp.com) to begin authentication. This domain handles all SSO traffic during migration.

  3. Request forwarding

    The proxy forwards authentication requests to the selected provider while preserving all necessary identifiers and session parameters.

  4. Identity provider processing

    The user’s IdP processes authentication and sends responses (SAML or OIDC) back to your proxy domain via configured callback URLs.

  5. Response routing

    The proxy examines response identifiers to determine which provider handled authentication and routes the callback accordingly.

  6. Code exchange

    Your app receives an authorization code with a state indicator showing which provider processed the request. Use this information to complete the authentication flow.

Set up provider selection in your auth server

Section titled “Set up provider selection in your auth server”
  1. Maintain organization migration mapping

    Store information about which organizations are migrated to Scalekit versus those still using external SSO providers. You can use a database, configuration file, or API endpoint based on your app architecture. This mapping determines which SSO provider to use for each organization.

    example: organization-mapping.js
    const organizationMapping = {
    'megasoft.com': { provider: 'workos', migrated: false },
    'example.com': { provider: 'workos', migrated: false },
    'newcompany.com': { provider: 'scalekit', migrated: true }
    };
  2. Implement conditional routing logic

    Add logic to your authentication endpoint that checks the organization mapping and redirects users to the appropriate SSO provider. For migrated organizations, route to Scalekit; for others, use the external provider.

    example: auth-server.js
    app.post('/sso-login', (req, res) => {
    const { email } = req.body;
    const [, domain] = email.split('@');
    // Check for force Scalekit header (helpful for debugging)
    const forceScalekit = req.headers['x-force-sk-route'] === 'yes';
    if (forceScalekit || organizationMapping[domain]?.migrated) {
    // Route to Scalekit
    const authUrl = scalekit.getAuthorizationUrl(redirectUri, { loginHint: email, domain });
    res.redirect(authUrl);
    } else {
    // Route to external provider
    const authUrl = externalProvider.getAuthorizationUrl(redirectUri, { email });
    res.redirect(authUrl);
    }
    });
  3. SSO proxy handles provider interactions

    The SSO proxy manages all interactions with SSO providers and identity providers. See the SSO proxy architecture overview section above for details on how this works.

  4. Create separate callback endpoints

    Set up two callback endpoints to handle authorization codes from different providers. While you can use one endpoint, separate endpoints are recommended for clarity and easier debugging.

    Callback endpoints
    https://yourapp.com/auth/ext-provider/callback # External provider
    https://yourapp.com/auth/scalekit/callback # Scalekit
  5. Handle code exchange and user profile retrieval

    Your callback endpoints receive authorization codes and exchange them for user profile details. The proxy adds state indicators to help identify which provider processed the authentication.

    example: callback-handlers.js
    // External provider callback
    app.get("/auth/ext-provider/callback", async (req, res) => {
    const { code, state } = req.query;
    // Exchange code with external provider for user profile
    const userProfile = await externalProvider.exchangeCode(code);
    // Create session and redirect
    });
    // Scalekit callback
    app.get("/auth/scalekit/callback", async (req, res) => {
    const { code } = req.query;
    // Exchange code with Scalekit for user profile
    const userProfile = await scalekit.authenticateWithCode(code, redirectUri);
    // Create session and redirect
    });

Once you create equivalent organizations in Scalekit for the ones you plan to migrate, the proxy can begin routing callbacks to Scalekit for those organizations while others continue on the external provider.

Once you create equivalent organizations in Scalekit for the ones you plan to migrate, the proxy can begin routing callbacks to Scalekit for those organizations while others continue on the external provider.

  1. Update organization mapping for migrated organizations

    When organizations are ready for Scalekit, update your mapping to mark them as migrated. The proxy will automatically route these to Scalekit.

  2. Proxy routes Scalekit requests appropriately

    The proxy detects migrated organizations and routes authentication to Scalekit while maintaining the same callback URLs for seamless user experience.

  3. Handle Scalekit callbacks

    Use your existing Scalekit callback endpoint to process authentication responses and complete the login flow.