Five applications, five ways to sign in
Each application had grown its own login and its own user store, at a different time, for a reason that made sense then.
A joiner meant creating five accounts. A leaver meant remembering all five, and remembering them was a person's job rather than a system's. The support queue filled with password resets that no single team owned.
You did not build that estate. You are expected to end it, and you have already said out loud, with the CTO in the room, roughly what it would take. Both halves of that sentence are now yours. If the cutover locks a team out on a Monday morning, your phone rings, and there is no vendor incident review to stand behind. So the rest of this is the mechanism, in the order it was actually done, and what it cost afterwards.
The estate before and after
Centralised login platforms
Before5
After1
Shared identity providers to operate
Beforenone
AfteroneSomebody patches it, watches it and carries a pager for it. The estate now runs a shared identity service of its own, and it did not exist before.
What it costs to keep is set out further down, in the same detail as what it saved.
Two rows, because two things are countable. Five centralised login platforms became one. The second row moves the wrong way, and it belongs here because it is true.
Onboarding meant five accounts. Be exact about what consolidation changed there: it changed where a person is authenticated, not necessarily where they are created. Federation leaves the underlying stores in place, so a joiner may still be created in more than one of them.
Offboarding is the other half, and it is reported rather than counted, so it is not put in the table as a third measurement. Revoking access used to be a checklist nobody trusted. It became one action that can be proven.
Five stores existed. A shared service did not.
The credentials never moved
Verify
Against the store that already holds the credential
Nothing is copied. The provider answers as one issuer before any application moves. We federated the existing user stores into the provider instead of migrating them in one move.
Keycloak Server Administration Guide, LDAP storage mode password validation always occurs on the directory server
Re-encode
On sign-in, under the realm's current policy
The upgrade happens as people sign in, so nobody is asked to reset anything. The only moment the plaintext exists is the moment of a successful sign-in, and that moment is spent either way.
Keycloak source, PasswordCredentialProvider.java rehashPasswordIfRequired
Retire
When accounts that never sign in are handled
Only then does the legacy verifier come out of service. That is what sets the decommission date. Not a plan, and not a date you can pick in advance.
Keycloak source, rehashPasswordIfRequired the catch block logs and carries on
Keycloak's administration guide is direct about why that is the shape of the answer. It imports users from a directory into its own database, and it states that it never imports passwords, because password validation always happens on the directory server. The same guide says that existing data storage typically cannot be migrated into a Keycloak deployment, which is exactly why federation exists, and that a store it does not speak natively can be reached through the User Storage SPI.
The upgrade to the current hashing policy then happens on a sign-in rather than inside a window. Keycloak's own source file for password credentials, services/src/main/java/org/keycloak/credential/PasswordCredentialProvider.java, reads the algorithm off the stored credential in isValid, verifies with the hash provider that owns it, and on success re-encodes the password the person just typed under the realm's current policy.
The honest half is in that same file, in rehashPasswordIfRequired. Keycloak's own comment says the re-encode runs in a different transaction and must not fail on a model exception caused by concurrent logins, and the catch block logs and carries on. A sign-in can succeed while the upgrade quietly does not happen. An account that never signs in never converts at all, so the old verifier stays deployed until you deal with that tail on purpose, by reset or by expiry.
How five applications moved, one at a time
Each step is here because the one after it cannot hold without it
- The stores go first
Behind the provider, because nothing can integrate against one issuer until one issuer exists. Federated, verifying where the credentials already lived.
- One application integrates next
Because the mechanism has to be proven somewhere before it is trusted anywhere. Against the provider, once, starting where a failure costs least.
- The old login path is demoted rather than removed
Because rollback cannot be live if the path it rolls back to is gone. It becomes one of the provider identity sources, not a switched-off system.
- The rest follow in ascending order of what a failure would cost
Because the expensive case should not be the one that tests the mechanism. Each application carrying its own cutover and its own live rollback.
- The legacy paths come out last
Because a path still serving one application cannot be retired for any of them. Retirement waits on the last application rather than on a date.
No change freeze. A freeze is a cost every other team in the business pays for a decision only one team made, so the order was the plan.
The property that makes it safe is in Keycloak's brokering documentation: an application integrated against the provider cannot see how the identity behind it is validated, and an identity source only has to know about the provider. An application therefore integrates once and never again, however much moves behind it afterwards. The legacy login was not switched off at all. It was demoted to being one of the provider's own identity sources, and which path a request took was a per-client switch, which is what made rollback a live thing rather than a paragraph in a runbook.
Risk ascending. The application whose failure would cost most moved once the mechanism had already held on the ones where it costs least. That was the ordering rationale, and it is the only one stated here, because there is no published rule about which application should go first and we are not going to invent one.
What signing out actually delivers, per application
| Mechanism | What it delivers |
|---|---|
| Front-channel logout | What it deliversOne iframe per application in the browser. |
| Back-channel logoutthe default here | What it deliversServer to server, no browser dependency. |
| Neither registered | What it deliversNothing at all, and silently. |
Single sign-on is the easy half. What single sign-out guarantees is less than the phrase suggests. The session at the provider ends. Everything past that is a notification, and no part of the chain promises delivery. Keycloak's administration guide sets out the front-channel limits above and recommends back-channel logout instead. The Back-Channel Logout specification, section 2.5, then permits a delayed retransmission only where the provider suspects the previous attempt failed for a recoverable reason, such as a network outage or a temporary interruption at either end, and says it should not retransmit in any other case. There is no queue and no acknowledgement, and an application that is down for some other reason is not owed another attempt.
Across five applications that is three different states, and the third one is silent.
Can be blocked by a content security policy, and closing the browser first can leave sessions alive. No acknowledgement comes back.
Delivery is still not guaranteed: retransmission is permitted only where the provider suspects a recoverable failure, and an application unreachable for any other reason is not owed another attempt. Needs a server-side session store, because the call carries none of the user cookies.
Back-channel is the default here, and it carries a cost the specification states in its opening section. The logout call arrives server to server and carries none of the person's cookies. An application whose session is a self-contained signed cookie has nothing to invalidate. It has to acquire a server-side session store, or a revocation list keyed on the session id, before back-channel logout can do anything at all. Working out which of your applications is in that position comes before the plan, not during it. That is the step that turns a five-application consolidation from configuration into software engineering.
The account that survives
Access lingers in a store nobody owns
It is forgotten. What changes is the number of places a revocation has to happen.
What we commit to
Revocation becomes one action in one place, because there is one place. What consolidating identity changes is the shape of that answer.
Evidence has to be assembled from five consoles
Five consoles means five owners and five answers to assemble under time pressure. This follows from five becoming one.
What we commit to
One provider, one record of what was cut and when. The exposure is what made the work fundable, and it is not an engineering argument.
Reading any of this as an audit credential
We do not hold SOC 2, GDPR, or HIPAA certifications ourselves. It says nothing about any audit outcome.
What we commit to
We engineer systems that pass your audits. To be plain: nothing here says we closed an audit finding for this client. We are not going to imply it either.
Five login systems is five places an account can survive a departure, and an account like that is usually not left on purpose. Two published SOC 2 readiness guides, from bastion.tech and screenata.com, list deprovisioning among the exceptions they see most often. The test is concrete. An auditor picks a handful of people who left, and asks for timestamped evidence that their access was revoked inside the window you told the auditor about.
Revocation becomes one action instead of a checklist across five systems, and that follows from five becoming one rather than from anything we can claim about an audit.
Show data table
| Item | Value |
|---|---|
| Auth-related support tickets | 70 percent reduction |
| Licence and development cost, combined | 40 percent reduction |
Two numbers came out of this estate. Auth-related support tickets fell by 70 percent. Licence and development cost fell by 40 percent, counted together as one figure.
Nothing else is plotted beside them. There is no industry baseline for either that we would stand behind, and a borrowed number sitting next to ours would read as proof of ours.
What these numbers do not cover
Where we fit
Five or more applications, each with its own user store
A joiner or leaver process that spans several consoles
Where we are the wrong call
Two applications already behind one directory, and a joiner or leaver process that touches one console
One legacy application that speaks only its own protocol, and nothing else pressing
Take both figures with their edges showing. The 70 percent is a reduction in one estate's auth-related tickets. What those tickets were decides what a 70 percent cut is worth, and that arithmetic is yours, because what we hold is a reduction and not a volume. The 40 percent is licence and development cost together. Read as a licence saving it will build a business case that does not survive its first review.
Neither figure carries a period, and neither carries a timeline. This page establishes no elapsed time, no duration and no measurement window for either percentage, and it establishes no schedule, no concurrency and nothing about the order in which any of the work actually happened. The steps above are set out by what each one depends on, not by when it ran. So payback timing is not a question these two numbers can answer, and anyone modelling one is modelling their own assumption.
Five applications is the size of this estate, and a larger one has more of the hard parts rather than the same amount of them. The tail of accounts that never sign in gets longer too.
An estate in either of those two positions does not need a consolidation of this shape, and a single legacy protocol is often best left federated and said out loud rather than counted as covered. Consolidating identity while each application keeps deciding its own permissions is a finished architecture, not a half-done one. If that is your estate, the work is smaller than this and worth doing without us.
Thousands of monthly active users sign in through one provider. That is a floor rather than a rounded figure, and a login path carrying that many people is tier zero. What that costs to run is a property of this technology rather than of anyone's estate.
Key rotation is an obligation the shared provider introduces. Keycloak documents active and passive key pairs so keys can rotate without cutting existing sessions, and puts a best practice of new keys every three to six months in writing. It also documents how to break offline access by removing old keys too early, which is a thing you only do once.
Realm configuration has to live somewhere reviewed. Keycloak's own guide says the import and export process has limitations to be used as a backup and restore mechanism, so a console export is not the copy anyone should be relying on. Configuration as code, reviewed like code, is the only version of that which survives a bad afternoon.
The integration layer is a standing budget line too. Keycloak deprecated its own client adapters, announced in 2022 and restated in 2023, and 24.0.0 was the last major release to ship them. An integration layer now sits on third-party libraries with their own release cadence, so a provider major upgrade can force a code change in every application behind it.
Send us the estate
Send the list. What each application is, what it authenticates against today, and which store nobody wants to touch. That is what the first conversation is about: which of those stores can be federated as they are, which cannot and why, and which application would be the hard one. Finding that application is what the exercise is for, because it decides whether the rest of the plan is worth writing.
The other good outcome is real. Some estates read this, work out that the job is smaller than they feared, and do it themselves. That is a fine result, and we would rather you reached it than paid somebody to tell you the same thing.

- Scope is agreed in writing before anything starts