In this article

Auth0 to WorkOS enterprise connections migration guide

A step-by-step technical guide to migrating enterprise SAML and OIDC connections from Auth0 to WorkOS with minimal downtime and no re-configuration for IT admins or end-users.

Enterprise connections in Auth0 can be really expensive. As of the time this article was written, the Auth0 Professional plan costs $800/month and provides up to 5 enterprise connections. After that, you need to reach out to their sales team.

Other than that, it's hard to scale enterprise connections with Auth0 unless you have a big team of support experts in SAML and OIDC.

You may want to move to a new platform, but there's a problem: this would require customers to re-configure their SAML or OIDC integrations, resulting in a lot of back-and-forth communication and downtime. This could be fine if you have 5 connections.

What if you have 50, 100, or 1000 connections?

We recently completed a migration of 1,000s enterprise connections from Auth0 to WorkOS, and it was seamless for 96% of this. We want to share how it works.

What does seamless mean?

It means zero friction for:

  • IT admins, who manage an enterprise identity provider (IdP)
  • End-users, who sign in to IdPs for accessing your application

Requirements

For having seamless enterprise connection migration, there are some requirements on the Auth0 tenant setup:

  • You must have configured a custom domain with Auth0 so that you control the domain routing.
  • The SAML enterprise connection doesn't use SAML Request Signing with Auth0 tenant global key pairs.
  • The SAML enterprise connection doesn't use SAML Response Encryption with Auth0 tenant global key pairs.

Auth0 to WorkOS migration in 9 steps

Let's dive into the steps for moving enterprise connections away from Auth0.

1. Export enterprise connections using the Auth Management API

First, we need to export the connections data from Auth0 using the Auth0 Management API.

The Get all connections and Get clients endpoints contain all the information needed to set up connections with your new vendor.

To access these endpoints, create a new Machine-To-Machine Application in the Auth0 Dashboard and assign it the read:connections, read:connections_options, and read:clients permissions.

Here's how to do this in the Auth0 dashboard:

1. Click Create Application on the Applications section.

Screenshot of Auth0 dashboard, showing how to create an application

2. Give the application a Name and select Machine to Machine Applications.

Screenshot of Auth0 dashboard, showing how to create a Machine-to-Machine application

3. Choose the pre-existing Auth0 Management API and select read:connections, read:connections_options , and read:clients permissions.

Screenshot of Auth0 dashboard, showing how to assign permissions to a Machine-to-Machine application

4. Go to the Settings tab and copy the Domain, Client ID and Client Secret values.

Screenshot of Auth0 dashboard, showing how to get the application's credentials

With those credentials, you can use our export script to export Connections and Clients data from Auth0. You might need to give chmod +x auth0_connection_reporter.rb to make the script executable.

Then run the script:

	
AUTH0_CLIENT_ID="" AUTH0_CLIENT_SECRET="" AUTH0_API_DOMAIN="" ./auth0_connection_reporter.rb > report.json
	

2. Setup custom domain with WorkOS

While this is not strictly required, we recommend setting up a custom domain before the migration occurs to prevent future breaking changes. WorkOS connections created without a custom domain can be impacted if a custom domain is created after.

Assuming you've created a WorkOS account, follow our documentation on how to set up an authentication API custom domain.

3. Import connections to WorkOS

Create a WorkOS account (it's free). Reach out to the WorkOS team via their support website or Slack channel to give them the file.

Because this JSON report contains sensitive information, we will provide a secure method for you to transfer the file.

WorkOS team will validate the report and import the connections for you.

The WorkOS team may contact you if we need more information about your specific Auth0 application configuration.

We can also come with a set of connections where we can't perform the seamless migration, given they require private keys that Auth0 doesn't export.

After the import process, we can also export the equivalent WorkOS connection IDs if you decide to have a map between WorkOS and Auth0 connections.

4. Place the WorkOS callback in your application

You need to create a new callback handler in your application. This handler will co-exist with Auth0's callback during the transition period.

This callback endpoint receives a WorkOS authorization code that your application will exchange for the user's profile information.

There are many ways for linking the WorkOS profile with your existing user data:

  1. Profile email: If your application gates users based on the email domain, you can extract the domain from email and resolve in the organization, workspace, or customer. For example, if you have a Foo Corp organization with the foo-corp.com domain, and you get a user profile with bob@foo-corp.com email, you would allow access to this profile.
  2. Profile idpId: If you have a mapping between the user ID (coming from IdP identity) and your customer organization, you can use this to match the user.
  3. Profile connection or organization ID: If you decided to have a mapping between Auth0 and WorkOS connection

Here's a code snippet for Next.js 15 that uses the WorkOS Node SDK (@workos-inc/node):

	
import { NextRequest, NextResponse } from 'next/server';
import { WorkOS } from '@workos-inc/node';

const workos = new WorkOS(process.env.WORKOS_API_KEY);
const clientId = process.env.WORKOS_CLIENT_ID;

export async function GET(req: NextRequest, _res: NextResponse) {
  const searchParams = req.nextUrl.searchParams;
  const code = searchParams.get('code');
  const error = searchParams.get('error');
  
  if (error) {
    // handle error from WorkOS SSO API
  }

  const { profile } = await workos.sso.getProfileAndToken({
    code,
    clientId,
  });

  // You can use `profile.idpId` or `profile.email` to match
  //   an existing user ID or email in your application database
  //
  // const allowedUser = usersService.findByEmail(profile.email);
  
  
  // You can also use the `profile.organizationId` or `profile.connectionId`
  //   to match a Auth0 connection ID

  return NextResponse.redirect('/');
}
	

You can also refer to our SSO documentation, which includes more examples of adding a WorkOS callback.

You need to add this callback URL as a Redirect URI in WorkOS dashboard.

5. Configure a proxy with your Auth0 custom domain

Next, configure a proxy for the Auth0 callback. This proxy will route the IdP callback responses to WorkOS, ensuring that customers do not need to modify their IdP configuration.

!!After completing the migration, you'll be able to turn off your Auth0 tenant entirely, but you'll need to maintain the custom domain in your DNS provider.!!

Flow diagram showing how a proxy for the Auth0 callback works

The chart above outlines the proxy flow:

  1. After user authorization in the IdP, a response is sent to the Auth0 callback, which is intercepted by a proxy positioned after the custom domain DNS resolution.
  2. The proxy checks for a fallback query parameter in the IdP response. If absent, it forwards the response to the WorkOS API at https://workos.your-domain.com/sso/:client_id/auth0/callback, where client_id is your WorkOS environment Client ID.
  3. WorkOS API searches for the previously imported connection using the Auth0 connection name in the IdP response.
    • If connection is found, WorkOS processes the response and redirects to your application's WorkOS callback.
    • If connection is not found, identified as coming from Auth0, or flagged with breaking change, WorkOS forwards it back to Auth0, adding the fallback=auth0 query parameter.
  4. When the proxy receives an IdP response with fallback=auth0, it forwards it to Auth0.

The fallback logic ensures a smooth transition and should prevent downtime for connections that are not resolved.

The proxy can be implemented in your own provider, but we'll provide a configuration example for when you have Cloudflare configured as a Reverse Proxy in Auth0.

Cloudflare rules

Configure the following two Cloudflare rules to forward callback traffic to WorkOS. Assuming your Auth0 custom domain is auth0.your-domain.com and your WorkOS custom domain is workos.your-domain.com.

1. Add a redirect rule

A redirect rule ****will forward callback traffic to your WorkOS custom domain. Create a new dynamic redirect rule with the following configuration:

  • Name: Auth0 callback redirect
  • Custom filter expression:
    • URI Path equals /login/callback
    • Hostname equals auth0.your-domain.com
    • URI Query String does not contain fallback=auth0
  • Then...
    • Type: Static
    • URL: https://<workos-subdomain>.your-domain.com/sso/<clientId>/auth0/callback
    • Status Code: 307
    • Preserve query string

2. Add a transform rule

The transform rule will clean up the proxy URL so that Auth0 can properly process SAML requests. Create new Rewrite URL Rule:

  • Name: Remove fallback query parameter
  • Custom filter expression:
    • URI Path equals /login/callback
    • URI Query String contains fallback=auth0
  • Then...
    • Path: Preserve
    • Query:
      • Rewrite to:
        • Dynamic: regex_replace(http.request.uri.query, "(\\\\?)?&?fallback=auth0&?", "${1}")

!!We recommend that you perform a proof-of-concept in staging environment before production. This should clear out any doubts and de-risk breaking changes in your setup.!!

6. Opt-in migrated connections by calling WorkOS authorization URL

After importing your connections to WorkOS, you can begin replacing Auth0's authorization calls with WorkOS authorization endpoints.

Most login pages use Home Realm Discovery (HRD) to identify enterprise connections based on email domains. If you already have this logic mapping Auth0 connections to domains, you can keep using it.

With your migration, you'll now have a mapping between Auth0 and WorkOS connections. You'll maintain a list of opted-in connection IDs that should redirect to the WorkOS authorization URL.

The code snippet below demonstrates how to conditionally direct users to either WorkOS or Auth0, enabling a gradual migration:

	
import { NextRequest, NextResponse } from 'next/server';
import { WorkOS } from '@workos-inc/node';

const workos = new WorkOS(process.env.WORKOS_API_KEY);
const clientId = process.env.WORKOS_CLIENT_ID;

// Mapping of Auth0 to WorkOS connections
const CONNECTION_MAPPING = {
  'auth0_conn_123': 'conn_workos_abc',
  'auth0_conn_456': 'conn_workos_def',
};

// -- Connections opted into WorkOS -- 
// This list can be persisted in a feature flag or temp storage.
// Ideally you want to have the ability for quickly changing this
// list to opt int new connections or rollback failed connection.
const WORKOS_OPT_IN = [
  'auth0_conn_123'
];

export function GET(req: NextRequest) {
  const { searchParams } = new URL(req.url);
  const connectionId = searchParams.get('connection');
  const redirectUri = 'https://dashboard.my-app.com/callback';

  // Check if connection is opted into WorkOS
  if (WORKOS_OPT_IN.includes(connectionId)) {
    const workosConnection = CONNECTION_MAPPING[connectionId];

    const authorizationUrl = workos.sso.getAuthorizationUrl({
      connection: workosConnection,
      clientId,
      redirectUri,
    });
    return NextResponse.redirect(authorizationUrl);
  } else {
    // Route to Auth0 (existing)
    const auth0Url = `https://your-tenant.auth0.com/authorize?response_type=code&client_id=auth0_client&redirect
_uri=${redirectUri}&connection=${connectionId}`;
    return NextResponse.redirect(auth0Url);
  }
}
	

Check our SSO documentation for more examples on implementing the WorkOS Authorization URL handling.

Rollout strategy and monitoring

We recommend that you perform a phased and incremental roll-out. This should de-risk issues and give you confidence in the flow.

For example, start with a single connection.

You can monitor the connection status and sessions from the WorkOS connection detail page.

If the connection rolled out successfully you should see Successful sessions meaning that a customers logged in successfully through WorkOS.

Once a Successfull session occurs the connection is automatically transitioned from a Setup in progress state to Active state.

Screenshot of WorkOS dashboard, showing where to view the sessions of an SSO connection

If you encounter failures, you'll see Failed sessions in the dashboard. You can use your previous gating logic to "rollback" the connection to Auth0 while you troubleshoot. Inspect the failed session error details in the WorkOS dashboard to identify the issue.

If you're uncertain about the cause of these errors, don't hesitate to reach out to us. Our team will help resolve the issue and can provide prompt support through Slack.

Screenshot of WorkOS dashboard, showing how to see details of a SAML error

Once you've gained confidence with your first activated connection, proceed to the next one from a different provider. We recommend starting with just 1-2% of your connections before expanding to 10%. After that, you can gradually roll out to 100% of connections.

For monitoring connections at scale, you can subscribe to our events API. The following events could be useful here:

  • authentication.sso_failed
  • authentication.sso_succeeded
  • connections.activated

If you use Datadog, you can easily stream these events to your Datadog instance.

8. Connection for manual migration

After step 3 (Import Connections), the WorkOS team can flag connections that can't have a seamless migration. For these connections, we advise that your customers configure a new connection.

In these cases, WorkOS can generate portal links allowing IT admins to configure new SAML or OIDC applications in the IdP without affecting the existing integration. Through the Admin Portal, IT admins receive contextualized instructions to configure this new connection and can test it immediately.

Screenshot of WorkOS Admin Portal

You can generate the portal link through the WorkOS dashboard, which can directly email the IT admin, or you can copy the setup link and send it manually to your customer.

Screenshot of WorkOS dashboard, showing how to generate Admin Portal links

When the connection is activated, your team will receive an email (if signed up in the WorkOS dashboard), or your application can listen to the connection.activated event. This signals that you can roll out the connection.

9. Shut down Auth0 👋

After you have successfully migrated all your connections and have thoroughly verified that all authentication traffic is being properly routed through WorkOS without any issues for an appropriate monitoring period, you can confidently proceed with shutting down your Auth0 tenant.

It's recommended to maintain both systems running in parallel for a few weeks to ensure complete stability before fully decommissioning your Auth0 infrastructure.

WorkOS SSO capabilities

The WorkOS SSO product features a rich set of capabilities that will help ensure both a smooth migration and long-term maintenance of your migrated and new connections:

Additionally, you can unlock advanced features that empower IT admins to manage authorization to your application from the IdP, including:

You can also migrate your entire user management solution to WorkOS with Authkit.

That's it!

Migrating from Auth0 to WorkOS offers a cost-effective and scalable solution for enterprise connections. This phased approach enables a seamless transition without disrupting customer authentication experiences, reducing costs while improving scalability.

WorkOS's comprehensive SSO capabilities and dedicated support help you manage enterprise authentication complexities while delivering better experiences for your team and customers.

Ready to migrate from Auth0 to WorkOS? Get in touch with us!

Further Reading:

This site uses cookies to improve your experience. Please accept the use of cookies on this site. You can review our cookie policy here and our privacy policy here. If you choose to refuse, functionality of this site will be limited.