Back to guides

Migrate from Supabase Auth to Own Auth


To migrate from Supabase Auth to Own Auth, export the auth.users and auth.identities records from the production Postgres project, preserve UUID mappings for application tables, and replace Supabase JWT sessions with verified Own Auth account claims. Do not point Own Auth at Supabase's auth schema or treat GoTrue password hashes as a supported Own Auth import format.

Supabase Auth migration is an identity cutover. Inventory users, login methods, application foreign keys, active sessions, organisations, and recovery flows.

Export and inventory Supabase Auth users

  1. Back up the production project before reading the auth schema.
  2. Export auth.users and auth.identities through a controlled SQL or pg_dump workflow.
  3. Inventory public tables that reference auth.users IDs, Row Level Security policies, storage ownership, provider identities, and banned users.
  4. Record which application queries depend on Supabase JWT claims or service-role behavior.

Account transition

Own Auth creates new passwords with Argon2id and verifies only its documented hash formats. Do not copy an arbitrary provider password digest into Own Auth tables. The portable default is to create a passwordless user, verify control of the email address with a single-use magic link, and let the user set a new password through the password-reset flow.

  • Supabase JWTs remain valid until expiry unless the original signing configuration revokes them.
  • Row Level Security policies that read auth.uid() need an application-owned replacement.
  • Storage objects and public profile rows may retain foreign keys to Supabase UUIDs.
  • GoTrue password hashes and identity rows should not be inserted into undocumented Own Auth fields.
scripts/import-users.ts
await auth.createUser({
  email: exportedUser.email,
  name: exportedUser.name ?? undefined,
  metadata: {
    migrationSource: "supabase-auth",
    legacyUserId: exportedUser.id,
  },
});

Run imports through a server-only script with an idempotent legacy-ID mapping. Do not call this from a public route. Reconcile source and destination counts, duplicate emails, disabled accounts, and failures before sending any claim links.

Move application ownership safely

Keep the old provider ID in an application-owned mapping table until every foreign key and background job uses the Own Auth user ID. A matching email string is not enough to attach billing records, private content, or organisation membership. Require a verified claim before transferring access.

  1. Create Own Auth tables in the staging and production databases with the official migration command.
  2. Import disabled or deleted status separately so blocked accounts do not regain access.
  3. Create an explicit legacy-provider-ID to Own-Auth-user-ID mapping.
  4. Send claim links in controlled batches and rate-limit the claim endpoint.
  5. Transfer application records only after the claim succeeds.
  6. Keep an audit record of imported, claimed, skipped, and failed accounts without logging tokens or passwords.

Session replacement

Supabase Auth issues JWT access and refresh tokens through GoTrue. Own Auth uses revocable database-backed sessions. During the transition, keep Supabase token validation inside the legacy adapter, map the claimed Supabase UUID to the new Own Auth user, then issue an opaque Own Auth session and update protected data access to use the new server-side authorization context.

Use different cookie names during a short parallel window. Validate each cookie only with the system that issued it. Never accept an old provider token as an Own Auth session token, and remove the legacy validation path after the announced migration window.

Cutover and rollback

  1. Freeze authentication configuration changes while taking the final export.
  2. Run the idempotent import and reconcile counts.
  3. Enable Own Auth sign-in and recovery for a small internal cohort.
  4. Monitor sign-in failures, claim completion, email delivery, and support requests.
  5. Switch new sign-ins to Own Auth while retaining a time-limited rollback path.
  6. Revoke old provider sessions and credentials only after the cutover is stable.
  7. Delete encrypted working exports according to the migration retention plan.

The successful end state is not two permanent auth systems. Supabase Auth becomes read-only during the transition, Own Auth becomes the only issuer of new sessions, and the legacy path is removed after account recovery and data reconciliation are complete.