Skip to main content

2 posts tagged with "users"

View All Tags

Keycloak slow migration vs fast migration: moving your users

· 11 min read
Jeff Patzer
Phase Two

A slow migration moves users from a legacy system into Keycloak one at a time, as each of them logs in. It goes by other names too: lazy migration, just-in-time (JIT) migration, trickle migration. Nobody gets a password reset email, there is no cutover weekend, and users who never come back are never migrated.

The other side is a fast migration: a bulk import that moves every user into Keycloak at once, before or at cutover. It is quicker to finish and easier to reason about, but it needs something a slow migration doesn't, usually the users' password hashes.

Keycloak doesn't ship slow migration. You add it with a user storage provider, and the one almost everyone uses is open source on GitHub: daniel-frak/keycloak-user-migration. This post covers how slow and fast migrations work, where the code lives, how to choose, and how to combine the two so a slow migration doesn't drag on for months.

Slow migrationFast migration
When users moveOne at a time, at their next loginAll at once, at import
Password hashes neededNo, the legacy system checks passwordsYes, or users set a new password
Legacy system after cutoverMust stay up and answer the migration endpointsCan be turned off
Dormant usersNever migrated unless you add a final stepMigrated with everyone else
Time to finishWeeks to months, plus a long tailHours to days

Migrating from Auth0 to Keycloak: a complete walkthrough

· 20 min read
Jeff Patzer
Phase Two

Migrating from Auth0 to Keycloak is three separate jobs wearing one name. Profiles move easily — Auth0's export job gives you newline-delimited JSON and Keycloak's partial-import endpoint takes it. Passwords do not move at all: Auth0 hashes with bcrypt, Keycloak 26.7.4 ships four password-hashing providers and none of them is bcrypt, so you either reset every password or stand up a bridge that verifies against the old hashes on first login. Your Rules and Actions have to be rewritten, because there is no equivalent runtime — some of them become authentication-flow configuration with no code at all, and some become a Java SPI.

The part that costs people a weekend is none of those. It is that Keycloak's admin API answers 201 Created to three different malformed migrations and then quietly loses the data. Everything below was run against Keycloak 26.7.4 on PostgreSQL 16.