Move WorkOS User Management, AuthKit, SSO, and organization membership to Authdog without a hard cutover. This guide covers inventory, user and org export, SSO remapping, Directory Sync replacement, application cutover, and retiring WorkOS. For product positioning, see the [Migrate from WorkOS](/migrate-from-workos) overview.

## Prerequisites

- An Authdog [tenant, project, and environment](/docs/concepts/multi-tenancy) for rehearsal (staging first).
- WorkOS API key access to list users, organizations, memberships, and SSO connections (and Directory Sync directories if you use them).
- Inventory of every app that uses AuthKit, the WorkOS Node/Python/Go SDK, or validates WorkOS-issued sessions/JWTs.
- Agreement on cutover windows for B2B customers that authenticate through WorkOS SSO.

## Migration shape

1. **Inventory and export** — capture WorkOS users, orgs, SSO connections, and Directory Sync mappings.
2. **Map and import** — recreate organizations, roles, users, and SSO in Authdog.
3. **Parallel run** — validate Authdog sessions while WorkOS still serves production cohorts.
4. **Cut over and retire** — switch apps, then disable WorkOS redirects, API keys, and Directory Sync.

Do not flip production SSO domains until a rehearsal environment passes acceptance checks on org membership, IdP login, and session validation.

## 1. Inventory the WorkOS environment

Document everything production depends on:

| WorkOS resource | What to capture | Authdog target |
| --- | --- | --- |
| Users | `id`, email, email verified, first/last name, profile picture, `created_at` | [Users](/docs/users) |
| Organizations | Org id, name, domains, metadata | [Organizations](/docs/concepts/organizations) |
| Organization memberships | User ↔ org, role (`member` / `admin` / custom) | Org membership + [roles](/docs/permissions) |
| AuthKit / email auth | Password and magic-auth usage | [Sign up & sign in](/docs/authentication) |
| SSO connections | SAML/OIDC metadata, domains, org binding | [Integrations](/docs/integrations) / enterprise SSO |
| Directory Sync | Directory source, group → role mappings, user attributes | [Provisioning](/docs/concepts/provisioning) (SCIM) or scheduled sync |
| Custom claims / session enrichment | Any claims apps read from WorkOS tokens | Roles, metadata, or app-side claims |

Store each WorkOS user `id` as an Authdog **external identifier** so admin tools and databases that keyed on WorkOS IDs keep resolving.

## 2. Export users and organizations

Use the WorkOS API (Users, Organizations, Organization Memberships) to export:

- WorkOS user `id` (required external identifier)
- Email and verification state
- Profile fields your product shows
- Organization memberships and roles
- SSO profile / IdP subject identifiers when available
- Disabled or inactive signals if you track them outside WorkOS

If you rely on Directory Sync today, export the **desired end state** of users and groups from the directory (or from WorkOS after the latest sync), not only a point-in-time API dump — sync lag can hide recently deactivated users.

### Password and AuthKit strategy

WorkOS AuthKit password hashes are not always available for bulk import. Pick a strategy before cutover:

- **Progressive migration** — on next email/password sign-in, verify once against WorkOS (or your previous IdP), then set the credential in Authdog and stop calling WorkOS for that user.
- **Magic link / SSO-first** — move cohorts to passwordless or enterprise SSO when passwords cannot be exported.
- **Forced reset** — acceptable for small internal bases; avoid for large end-user populations.

Never log raw passwords. Encrypt any credential material and delete it after cutover.

## 3. Recreate Authdog configuration

In the target Authdog environment:

1. Enable the sign-in methods you need (password, magic link, social, MFA, enterprise SSO). See [Sign up & sign in](/docs/authentication).
2. Create Authdog [organizations](/docs/concepts/organizations) that match WorkOS orgs (name, domains, metadata). Keep a mapping table: `workos_org_id` → Authdog org id.
3. Define roles that match WorkOS membership roles (and any app-specific roles you encoded elsewhere). See [Roles & permissions](/docs/permissions).
4. Recreate SAML/OIDC connections with **new** ACS / redirect URLs pointing at Authdog. Leave WorkOS SSO live until each customer cohort cuts over.
5. If you used Directory Sync, configure Authdog [provisioning](/docs/concepts/provisioning) (or your own SCIM/HRIS pipeline) so deprovisioning does not regress after WorkOS is retired.
6. Replace any WorkOS Actions / webhook enrichment with Authdog metadata, roles, or application logic after session validation. See [Sessions & tokens](/docs/concepts/sessions-tokens).

Use staging for the first full import. Promote configuration only after rehearsal.

## 4. Import users and memberships

Import via console bulk import or the REST [Directory API](/docs/api):

1. Upsert each user with email, profile, and verification state.
2. Set the WorkOS user `id` as the external identifier.
3. Attach metadata your app still needs.
4. Add organization memberships from your mapping table.
5. Assign roles that match WorkOS org roles or app RBAC.
6. Suspend users that should not sign in (offboarded directory users, blocked accounts).

### Identity and SSO linking

- Users who previously signed in only via SSO should import with verified email when the IdP asserts it; test first login through the new Authdog SSO connection.
- Users with both AuthKit email auth and SSO should land as **one** Authdog user when emails match and are verified.
- Preserve IdP subject identifiers in metadata if your compliance or audit flows need them.

## 5. Update applications

For every client that used WorkOS AuthKit or the WorkOS SDK:

1. Install the Authdog SDK or components for that stack ([quickstarts](/docs/quickstarts)).
2. Replace WorkOS client/API configuration with the Authdog environment **public key** (`pk_...`).
3. Point login, callback, and logout URLs at Authdog.
4. Validate Authdog sessions on the backend instead of WorkOS session/JWT verification. See [Backend requests](/docs/backend).
5. Update code that read WorkOS-specific fields (`org_id`, `role`, custom session claims) to the Authdog session and organization model.

During parallel run you may temporarily accept **either** issuer in a thin adapter. Keep it instrumented and short-lived.

## 6. Cut over in stages

Recommended sequence:

1. Rehearse export → org/user import → SSO and email sign-in in staging.
2. Move internal apps first.
3. Move one WorkOS organization (customer) or one application at a time.
4. For each SSO customer: schedule IdP metadata/ACS update, validate login, then disable the WorkOS connection for that domain.
5. Monitor failed logins, support tickets, and provisioning drift.
6. After all cohorts are stable, revoke WorkOS API keys, disable AuthKit, and decommission Directory Sync.

Rollback for a cohort means pointing that app (or that customer's SSO) back at WorkOS while you fix mapping — which is why external IDs and dual-run matter.

## Acceptance checklist

Before you call production migration done:

- [ ] WorkOS user `id` values stored as Authdog external identifiers.
- [ ] Organizations and memberships match the mapping table (spot-check per customer).
- [ ] Email/password or progressive-migration path verified for AuthKit users.
- [ ] SAML/OIDC SSO succeeds against Authdog for pilot customers.
- [ ] Roles / permissions match WorkOS org roles or the agreed replacement model.
- [ ] Directory Sync / SCIM deprovisioning path replaced or intentionally retired.
- [ ] Every callback, logout, and web-origin URL is registered in Authdog.
- [ ] Backend session validation no longer depends on WorkOS JWKS or session APIs.
- [ ] WorkOS API keys and SSO connections revoked after the soak period.

## Related

- [Migrate from Auth0](/docs/guides/migrate-from-auth0)
- [Migrate from Firebase](/docs/guides/migrate-from-firebase)
- [Migrate from Supabase](/docs/guides/migrate-from-supabase)
- [Organizations](/docs/concepts/organizations)
- [Provisioning](/docs/concepts/provisioning)
- [Migrate from WorkOS (overview)](/migrate-from-workos)
