← All playbooks
Authentication and identity migration

Keycloak → Auth0

Export the Keycloak realm with the CLI, then load profiles into an Auth0 database connection with the bulk import job. Map a password only when the hash algorithm is one Auth0 documents.

Typical timeline8 to 20 business days24 to 60 hours active work
Statusneeds review
Source profileKeycloak import and export documentation reviewed 2026-11-05
Destination profileAuth0 bulk import documentation reviewed 2026-11-05
Documentation date
Review window
Evidence3 sources
This route needs review.Use it as a planning baseline, then verify the dated sources and test with representative data before production.
Before you migrate

Should you make this move?

Both platforms have a case. Compare what you gain with what you give up before scheduling the cutover.

Current platform

Keycloak

Reasons to stay
  • Self-hosted realms, clients, and login flows keep identity on infrastructure you operate
  • Centralized sign-in, federation, MFA, and user lifecycle controls reduce application security work
Reasons to leave
  • Realm export, password algorithms, and custom providers make a cutover an operations project
  • Passwords, sessions, factors, identities, and authorization policy are unusually sensitive to migration errors
New platform

Auth0

What gets better
  • Mature federation, extensibility, enterprise connections, and migration tooling cover complex identity programs
  • Centralized sign-in, federation, MFA, and user lifecycle controls reduce application security work
What gets worse
  • Tenant configuration, actions, pricing, and Auth0-specific claims can create substantial lock-in
  • Passwords, sessions, factors, identities, and authorization policy are unusually sensitive to migration errors
Best of the move

Auth0: Mature federation, extensibility, enterprise connections, and migration tooling cover complex identity programs. This removes a major source-side concern: Realm export, password algorithms, and custom providers make a cutover an operations project.

Worst of the move

What you lose: Self-hosted realms, clients, and login flows keep identity on infrastructure you operate. What you inherit: Tenant configuration, actions, pricing, and Auth0-specific claims can create substantial lock-in.

Jump to a section
01At a glance

Know the shape of the move.

Transfer outcome10 features audited
Transfer outcome distributionClean transfer: 0, Partial transfer: 5, Manual rebuild: 3, Not transferred: 2.
Clean0
Partial5
Manual3
Lost2
Mapping route9 of 9 fields have a destination path

This timeline assumes

  • You can stop Keycloak nodes and run kc.sh export. The Admin Console export cannot export users and masks secrets.
  • The Auth0 destination is a database connection, which is what the bulk import job fills.
  • You can split the import. Auth0's file limit is 500KB, and their guideline is about 1,000 users with fewer than 10 metadata fields.
  • You will read the credential algorithm in the export before you put it in custom_password_hash.
  • Applications move one at a time, and Keycloak stays up until Auth0 logins are proven.
02What transfers

What survives the move.

“Partial” and “manual” are not footnotes. They are work that must be scheduled and verified.

ItemOutcomeImpactWhat happensMitigation
Realm userspartialcriticalThe CLI can write users to separate files, one file, or the realm file. The default is different files, 50 users each. Over 50,000 users, Keycloak tells you to export a directory, not one file. Consistency wants the nodes stopped.Stop the nodes, export the realm you mean, and count users in the files.
Admin Console partial exportlosthighThat path does not include users, masks passwords and client secrets, and Keycloak says it is not for moving servers.Do not build the import from realm-export.json downloaded in the browser.
Password credentialspartialcriticalAuth0's schema accepts password_hash for bcrypt, or custom_password_hash for algorithms they list, including bcrypt, argon2, pbkdf2, scrypt, hmac, ldap, and several digests. A hash they do not list means the user resets.Read the algorithm and parameters in the Keycloak credential. Import one known password before the batch.
Sessions, events, and revoked tokenslosthighKeycloak excludes them from the export. Auth0 sessions start fresh.Tell people they will sign in again.
Import file shapepartialhighAuth0 wants a JSON array, not the NDJSON shape of an Auth0 export, and not an unbounded Keycloak file. Each job is capped at 500KB. Job data is deleted after 24 hours. A job that does not finish in time is failed.Convert and split. Download job errors the same day.
User idspartialhighAuth0 says bulk import adds an auth0| prefix to imported user ids. Keep the Keycloak id in metadata even when you also pass a user_id, so a later export does not confuse you.Store the Keycloak id in app_metadata. Reconcile a sample.
Clients and identity providersmanualcriticalA realm export contains clients and providers, but Auth0 applications and connections are configured in Auth0, not by posting that JSON.Recreate each application and connection. Test the callback.
Authentication flows and required actionsmanualcriticalKeycloak flows, SPIs, and required actions do not run inside Auth0. Actions are the Auth0-side rewrite.List every flow that blocks a login or adds a claim. Rewrite it and compare tokens.
MFA credentialsmanualhighA Keycloak OTP or WebAuthn credential is not automatically an Auth0 factor. Auth0's import schema has an mfa_factors object for secrets you format yourself.Enroll a test user. If the secret format does not match the schema, plan a fresh enrollment.
Groups and rolespartialhighYou can put role names into Auth0 metadata or roles, but Keycloak composite roles and group trees need a map.Flatten the roles the applications check. Test one user per role.
03Field and feature mapping

Where each thing goes.

SourceDestinationMethodNotes
Keycloak user idapp_metadata keycloak_user_idtransformKeep it even if Auth0 assigns auth0|...
username and emailemail and username fields in the import JSONtransformResolve duplicates before the job.
emailVerifiedemail_verifiedtransformDo not mark a contact verified if Keycloak had not.
enabled falseblocked truetransformDisabled users should not become active Auth0 users.
firstName and lastNamegiven_name and family_nametransformMap empty names on purpose.
Credential hashpassword_hash or custom_password_hashmanualOnly if the algorithm is on Auth0's list.
Realm roleAuth0 role or metadatamanualFlatten composites first.
Identity provider linkAuth0 connectionmanualCreate the connection, then test a login.
ClientAuth0 applicationmanualNew client id, secret, and callbacks.
04Before you begin

Make the move recoverable.

Backup procedure

Create the source-of-truth backup

Produce a CLI export while Keycloak is still the system of record.

  1. Stop Keycloak nodes, as the export guide recommends for a consistent file.
  2. Run kc.sh export for the one realm, to a directory if you have many users.
  3. Copy the realm file and the user files off the server.
  4. Start Keycloak again only after the copy is stored.

Proof to capture: The user-file count matches the realm's user count, and the files are named the way Keycloak's import rules expect.

Transformation · A script plus the Auth0 Management API import job

Auth0 import batches

Fit Keycloak users into Auth0's 500KB JSON jobs.

  1. Read users from the CLI files.
  2. Emit JSON arrays under 500KB.
  3. Put the Keycloak id in app_metadata.
  4. Omit custom_password_hash unless the algorithm and parameters match the schema.

Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.

Transformation · A single bulk import job and a test login

One-user password proof

See if Auth0 will verify the hash you mapped.

  1. Import one user whose password you know.
  2. Sign in against the Auth0 database connection.
  3. If Auth0 rejects the hash, drop custom_password_hash for the rest and send resets.
  4. Only then start the remaining jobs.

Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.

05Handle with care

The things most likely to hurt.

These are operating limits. Treat every “Stop if” condition as a blocked migration, not a suggestion.

Export

The browser export is used as the user source

criticalpossible likelihood

The file has no users, and secrets are asterisks.

Consequence
Auth0 gets an empty or useless import.
Mitigation
Export with the CLI while nodes are stopped.

Stop if: The user files are missing or secrets are masked.

Import

An unlisted hash is sent as custom_password_hash

criticalpossible likelihood

The job fails, or users are created and cannot sign in.

Consequence
You discover it at cutover.
Mitigation
Test one password. If it fails, import profiles and reset.

Stop if: The known user cannot sign in.

Cutover

A Keycloak flow has no Auth0 Action

criticalpossible likelihood

The token is missing a claim the API still checks.

Consequence
Requests that used to pass now fail, or the reverse.
Mitigation
Compare tokens for each role before you switch the app.

Stop if: A required claim differs.

06Precise timeline

Do the work in this order.

Estimate forOne Keycloak realm exported with the CLI and imported to one Auth0 database connection in 500KB jobs.
Total elapsed8 to 20 business days
Active work24 to 60 hours
BufferAdd time when user files are large, MFA secrets need formatting, or several applications each have their own token claims.
01
Days 1 to 3List realm pieces2 to 3 days
02
Days 3 to 5CLI export1 to 2 days
03
Days 5 to 10One-user import3 to 6 days
04
Days 10 to 15Import and switch one app2 to 5 days
05
Days 15 to 20Watch sign-ins3 to 5 days
  1. Days 1 to 3 · inventory

    List realm pieces

    6 to 10 hours active2 to 3 days elapsedApp owners waiting
    • List clients, identity providers, flows, and roles the apps check.
    • Pick the Auth0 database connection.

    Depends on: Keycloak admin, Auth0 admin

    Stop / go checkpoint

    Export?

    Go when: Each application has an owner.

    Stop when: A production client is unowned.

  2. Days 3 to 5 · backup

    CLI export

    3 to 8 hours active1 to 2 days elapsedNode stop waiting
    • Stop nodes and export the realm.
    • Count users in the files.

    Depends on: Approved inventory

    Stop / go checkpoint

    Convert?

    Go when: The count matches and file names are valid.

    Stop when: The console file was used, or the count is short.

  3. Days 5 to 10 · pilot

    One-user import

    8 to 20 hours active3 to 6 days elapsedAuth0 job waiting
    • Convert a tiny JSON file.
    • Import one known user and sign in.
    • Rewrite one claim as an Action.

    Depends on: Verified export

    Stop / go checkpoint

    Import everyone?

    Go when: The test login works or the reset path is accepted.

    Stop when: The hash test fails and no reset plan exists.

  4. Days 10 to 15 · cutover

    Import and switch one app

    5 to 14 hours active2 to 5 days elapsedImport jobs waiting
    • Run the remaining jobs.
    • Switch one application to Auth0.
    • Keep Keycloak serving the others.

    Depends on: Passed pilot

    Stop / go checkpoint

    Switch the next app?

    Go when: The app accepts Auth0 tokens and the user count matches.

    Stop when: Job errors are unresolved.

  5. Days 15 to 20 · observe

    Watch sign-ins

    2 to 8 hours active3 to 5 days elapsedLogin cycle waiting
    • Review failed logins.
    • Keep the Keycloak export.

    Depends on: Verified cutover

    Stop / go checkpoint

    Retire Keycloak?

    Go when: No rollback trigger fires.

    Stop when: A connection or claim fails.

07The point of change

Cut over with a way back.

Go live

Cutover

Have Auth0 authenticate the application you are switching, with Keycloak still intact.

Recommended window: A morning when that application's config can be reverted the same day.

  1. Freeze Keycloak profile edits or take a final CLI export.
  2. Run the remaining import jobs and read every error.
  3. Repeat the known-user login.
  4. Point one application at the Auth0 issuer.
  5. Leave Keycloak running for everything else.

Proof to capture: The Auth0 user count matches the export, and the switched app accepts an Auth0 login.

Return to safety

Rollback

Point the application back at Keycloak.

Deadline: Before you delete the realm or the CLI export.

  1. Stop Auth0-only signups if you can.
  2. Restore the application's Keycloak client settings.
  3. List users who exist only in Auth0.
  4. Import those profiles back with a tested path, or force a reset. Do not assume the Auth0 hash is a Keycloak hash.
  5. Confirm the app accepts Keycloak tokens.

Proof to capture: The application uses Keycloak again, and Auth0-only users are listed.

Rollback immediately when
  • The known-user login fails
  • Import jobs leave unresolved errors
  • A required claim is missing
  • An identity provider login fails
08Verification report

Prove the migration worked.

Every blocking check must pass. Capture the evidence before cleanup begins.

0%
Interactive report preview0 / 8 checks passed
PassIDCheckMethodExpected resultEvidence
V-01BlockingUser countCount users in the CLI files and in Keycloak.The counts match.Export manifest
V-02BlockingImport errorsRead each Auth0 job result before it ages out.Every failed row is fixed or accepted.Job log
V-03BlockingKnown userSign in with a password you know.Auth0 accepts it, or the reset flow works.Login note
V-04BlockingKeycloak idLook up app_metadata on a sample.The old id is present.Id sample
V-05BlockingClaimsCompare Auth0 tokens with what the app checked under Keycloak.Required claims match.Token sample
V-06BlockingProvidersSign in with each social or enterprise connection.The user lands on the right account.Provider checklist
V-07BlockingAuthorizationCall the app as each role.Access matches the old checks.Role matrix
V-08BlockingReverse one appPoint a test app back at Keycloak.Keycloak tokens work again.Rollback note
09Post-migration cleanup

Remove the scaffolding safely.

Safe after: Production apps have signed in through Auth0 and the CLI export is archived.

  1. Store the CLI export with restricted access. It can contain credential material.
  2. Delete pilot Auth0 users and import files from laptops.
  3. Rotate secrets that landed in tickets.
  4. Keep Keycloak until the rollback date.
  5. Write down the hash decision you made, so a later import does not guess.
Sources and evidence

Verify against the primary material.

Platform behavior changes. Check these sources and the review dates above before executing a production migration.

  1. Keycloak: importing and exporting realmsAccessed 2026-11-05
  2. Auth0: bulk import user dataAccessed 2026-11-05
  3. Auth0: bulk import user schemaAccessed 2026-11-05