Avnology ID
Migrate from another IAM

Migrate from Auth0

Bulk-import Auth0 users into Avnology ID, map Actions to Avnology Hooks, and reuse existing OAuth client IDs where possible.

Migrate from Auth0

This guide moves users, applications, and rules from an Auth0 tenant to Avnology ID.

Prerequisites

  • avnology CLI installed — see installation.
  • An admin API key in your .env (AVNOLOGY_SECRET_KEY=sk_live_…).
  • Auth0 tenant admin access with permission to run the bulk user export job.

Equivalent concepts

Auth0Avnology ID
TenantOrganization
Connection (Database)Password identity method
Connection (Social)Social provider (OIDC)
Rule / ActionWebhook Hook
Application (Regular Web)OAuth 2.1 Confidential Client
Application (SPA)OAuth 2.1 Public Client with PKCE
Application (M2M)Service Account + API Key
OrganizationOrganization (same concept)
RoleRole (roles:<role> in Keto)
Permissionnamespace:object#relation permission tuple
user_metadatatraits.metadata
app_metadataprivate_metadata (admin-only)
Universal LoginHosted sign-in page (/sign-in)

Export users from Auth0

  1. In the Auth0 dashboard, go to User Management → Users.
  2. Click Export Users. Auth0 emails you a JSON file containing every user in your tenant.
  3. Save the file as auth0_users.json in your working directory.

The export format is documented in the Auth0 bulk import docs. Each record looks like:

{
  "user_id": "auth0|64a1b…",
  "email": "[email protected]",
  "email_verified": true,
  "given_name": "Ada",
  "family_name": "Lovelace",
  "password_hash": "$2b$10$…",
  "created_at": "2024-01-02T03:04:05Z",
  "user_metadata": { "locale": "en-GB"

Auth0 exports bcrypt hashes by default. Avnology ID verifies bcrypt natively, so users can sign in with their existing passwords on day 1 — no forced reset required.

Import with the CLI

# Preview the canonicalised records.
avnology migrate auth0 --import auth0_users.json --dry-run

# Execute the import.
avnology migrate auth0 --import auth0_users.json

The CLI:

  • Normalises each record to the shared MigrationIdentity shape.
  • Sets external_id = <user_id> so re-running is idempotent.
  • Carries bcrypt hashes verbatim.
  • Copies given_name, family_name, nickname, and user_metadata into the identity traits.

Social identities (google-oauth2|…, github|…, etc.) are imported as link-later records: the next time the user signs in with the social provider, Avnology reconciles the external_id with the new social identity.

OAuth client migration

For each Auth0 Application:

  1. Register a new OAuth client in the Avnology dashboard under Developer → Applications. Pick the same client type (Regular Web / SPA / M2M).
  2. Copy the old Auth0 client ID into the Avnology client's legacy_client_id field so existing access tokens can be recognised during the cutover window.
  3. Move Allowed Callback URLs to Avnology's Redirect URIs list. Exact-match is required — wildcards are not accepted.
  4. For SPAs using PKCE, no secret is needed. For Regular Web + M2M, copy the new secret from the dashboard into your app's env (AVNOLOGY_SECRET_KEY).

Redirect URL mapping

Auth0 URLAvnology ID URL
https://<tenant>.auth0.com/authorizehttps://<Domain id="api"/>/oauth2/auth
https://<tenant>.auth0.com/oauth/tokenhttps://<Domain id="api"/>/oauth2/token
https://<tenant>.auth0.com/.well-known/jwks.jsonhttps://<Domain id="api"/>/.well-known/jwks.json
https://<tenant>.auth0.com/.well-known/openid-configurationhttps://<Domain id="api"/>/.well-known/openid-configuration
https://<tenant>.auth0.com/userinfohttps://<Domain id="api"/>/userinfo
https://<tenant>.auth0.com/v2/logouthttps://<Domain id="api"/>/oauth2/sessions/logout

Actions → Hooks

Auth0 Actions (post-login, post-change-password, pre-registration, etc.) map to Webhook Hooks on Avnology. Each Action translates to a webhook subscribed to the equivalent event:

Auth0 Action triggerAvnology event
post-loginsession.created
pre-user-registrationuser.pre_create
post-user-registrationuser.created
post-change-passworduser.password_changed
credentials-exchangeoauth.token_issued

Port the Action logic into a JS/TS webhook handler, subscribe it under Developer → Webhooks, and verify signatures with @avnology/backend's verifyRequest.

Cutover plan

  1. Run the user import in a non-production tenant and smoke-test with a handful of real emails.
  2. Dual-write window: keep Auth0 receiving all writes while Avnology ID handles reads. Set trust_forwarded_headers=false on both so session cookies don't cross over.
  3. Flip your app's AVNOLOGY_DOMAIN + AVNOLOGY_SECRET_KEY to the production Avnology tenant.
  4. Keep Auth0 online for 30 days for audit-log export, then decommission.