Skip to main content

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

Data residency requirements for SaaS authentication

· 16 min read
GR Patil
Phase Two

Data residency requirements for a SaaS authentication service are not one requirement, they are four, and only the first of them is about a region. You have to name where each class of identity data is stored. You have to name a lawful transfer mechanism for every touchpoint outside that region, including remote administrative access, which is a transfer and not an exception to one. You have to hold Article 28 processing terms that say so in writing. And you have to be able to produce an inventory of where the identity data goes after it is stored — the brokers, mail relays, event listeners and relying parties your own realm sends it to. Below is the checklist a data protection officer sends, the document that answers each item, what a thin answer looks like, our own answers including the unflattering ones, and the commands that generate that fourth item from a running Keycloak realm, tested on 26.8.1.

What Azure AD B2C's end of sale actually means

· 10 min read
GR Patil
Phase Two

Azure AD B2C's end of sale means Microsoft stopped selling it to new customers on 1 May 2025 and committed to supporting it until at least May 2030. It is not being shut down. Existing customers keep their tenants, can still create new ones, and keep the SLA, the security updates and the compliance posture. What ended is the roadmap.

One other date is doing a lot of damage. Premium P2 was discontinued on 15 March 2026 for all customers, and tenants moved to P1. That is a pricing-tier retirement, not a tenant retirement — but it has been reported often enough as "B2C shuts down in March 2026" that it is worth saying plainly: your tenant is fine, and you have roughly four years to make a decision rather than four months to execute one.

Four years is enough time to make a good decision and short enough that the one you make now is the one you live with. Here is what the three realistic destinations actually cost.

Which Keycloak clients should be enabled when you go live?

· 11 min read
Razvan Tufisi
Phase Two

The day a Keycloak realm is reachable from the internet, automated scanners find it. They read /realms/<name>/.well-known/openid-configuration, try every client ID that ships with every realm against the token endpoint and the login pages, and start replaying username and password pairs leaked from other sites. The traffic arrives from a different residential IP on almost every request, so it looks nothing like one noisy attacker. What you are trying to stop is not a single brute-force run. It is account takeover through credential stuffing, plus the enumeration that tells an attacker which of your users exist.

So the go-live question is not "should I disable admin-cli?" It is "which clients, and which grant types, should be on at all?" The short answer: the password grant off on every client, enforced by policy; only the clients you actually use exposed; a CAPTCHA on every flow that renders a login page; and account left enabled. Disabling a client is one tool among several, and for account it is usually the wrong one.

Everything below was reproduced against Keycloak 26.8.1, and every error string is copied out of a real response.

Passkeys make login faster. Here is the data, and how to roll them out in Keycloak

· 12 min read
Jeff Patzer
Phase Two

Every second a customer spends on your login page is a second they might spend somewhere else. Typing an email and password, mistyping it, waiting for a code, switching to an authenticator app, or giving up and resetting the password are all time between someone deciding to sign in and actually getting in. Passkeys remove most of those steps, and every large published measurement shows the same result: sign-in with a passkey takes about half the time, or less, and fails far less often. Our own customers report the same: after introducing passkeys, they measured login times drop by several seconds per sign-in.

This post collects the published figures, explains where the time goes, and shows how to introduce passkeys in Keycloak alongside the password login you already have.

Replacing homegrown e-commerce login with Keycloak

· 11 min read
Jeff Patzer
Phase Two

The login page is the most attacked page on an online store, and it is rarely the one anyone designed for attack. Homegrown e-commerce login usually starts as a users table, a bcrypt column and a session cookie, and it grows a password reset, a mobile API, a trade-account flag and a social button over the years. What it almost never grows is a defense against credential stuffing: automated replay of email and password pairs leaked from other sites, aimed at whichever of your customers reused one. Replacing homegrown login with Keycloak gives a store one identity service for web, app and back office, with social login, B2B accounts and branded pages built in, and you can move customers onto it without asking anyone to reset a password. It does not make the login page safe on its own. The defaults leave doors open that attackers look for first, and the rest of this post covers both halves: what you gain, and what has to be layered on top.

Keycloak 502 Bad Gateway behind a reverse proxy

· 8 min read
GR Patil
Phase Two

A Keycloak 502 Bad Gateway never comes from Keycloak. RFC 9110 defines 502 as a status a gateway emits about its upstream — so the proxy is telling you it could not get a usable response out of Keycloak, and the explanation is in the proxy's error log rather than anywhere in Keycloak's configuration. Start there, every time. In nginx there are only six lines that produce a 502 in front of Keycloak, each maps to one cause, and three of the six are the Quarkus-era port layout catching out a config written for an older release.

Everything below was reproduced against Keycloak 26.8.1 behind nginx 1.29, and every error string is copied out of a real run.

Data residency vs data sovereignty for your identity provider

· 14 min read
GR Patil
Phase Two

Data residency is a statement about geography: your identity data is stored and processed in a named region and does not leave it. Data sovereignty is a statement about law and control: which legal systems can compel access to that data, and who holds the keys and the administrative credentials that make access technically possible. They are not the same claim, and the gap between them matters more for an identity provider than for almost any other system you run, because the IdP holds a record of every person who can sign in to anything you operate and a log of when and from where they did it. Below: both definitions, each applied to the four classes of data a Keycloak realm actually stores, the point where a region setting stops helping — demonstrated against Keycloak 26.8.1 — and the rubric European buyers have started scoring vendors with.

Migrating from Okta to Keycloak

· 18 min read
GR Patil
Phase Two

Migrating from Okta to Keycloak is not a user migration. The users are the easy part: Okta's Users API hands you profiles and group membership, and Keycloak's partial-import endpoint takes them. Two other things decide how long this takes. Okta will not give you password hashes — they are an import-only field, so every user either resets a password or authenticates through Okta one last time while you drain. And every SAML and OIDC application has to be re-pointed by hand, one at a time, because the assertion consumer URL, the entity ID and the signing certificate all change when the identity provider does.

So the schedule is set by the app inventory, not by the user count. A thousand users is one afternoon. Forty SAML apps is a quarter. Everything below was run against Keycloak 26.8.1 in start-dev, and the Okta side is from Okta's published API specification, read on 2026-10-19.

"Restart login cookie not found" in Keycloak

· 9 min read
Jeff Patzer
Phase Two

"Restart login cookie not found. It may have expired; it may have been deleted or cookies are disabled in your browser." Keycloak shows this on a dead-end HTTP 400 page, and the message is more confident than it should be. It means exactly one thing: the request arrived with no KC_RESTART cookie at all. Not a stale one, not a rejected one. None. That cookie has no expiry to run out, so "it may have expired" is the one explanation that is never true. A rejected cookie produces a different message. And the page tells the user to "Click Back to Application", which on a default client renders no link to click.

Here is what the cookie is for, how to tell in one log line which failure you have, and the one client field that turns the dead end into a recoverable page.