Skip to main content

Keycloak 26.8.0: SCIM and Multi-Cluster v2 Go Supported

· 10 min read
GR Patil
Phase Two

Bottom line: not urgent — plan it, don't rush it. Keycloak 26.8.0 fixes seven CVEs, published as six medium and one low, none high or critical. Schedule it because SCIM, multi-cluster v2 and client secret rotation move from preview to supported, and brute-force lockouts now persist to your database by default.

Should you upgrade?​

If you…When
Let restricted admins manage identity providersSoon. They can grant themselves realm-admin; only 26.8.0 has the fix
Broker OIDC with trustEmail=true and link on emailSoon, unless you control that provider
Use group policies with one group name in two pathsSoon
Want SCIM, stateless or secret rotation supportedPlan it
Everyone elseNormal cycle, after the breaking changes

What's new​

This is a feature release that happens to carry CVEs, not the other way round.

SCIM is supported. A standards-based interface for managing users and groups in a realm, so an IdP or an HR system pushes joiners, movers and leavers instead of you writing against the Admin API. The promotion brings multivalued user attributes, User Profile permissions, Fine-Grained Admin Permissions honoured in search filters, and performance work for large user bases.

Multi-cluster v2 is supported, enabled with --features=stateless. Two or more clusters share session state through the database, with no external Infinispan cluster and no cross-site replication to run, and there is now a bare-metal and VM deployment guide alongside the Kubernetes one. Multi-cluster v1 — the multi-site feature — is deprecated and will be removed in a future major, so if you run it, that migration is on your roadmap whether or not you take 26.8.0.

Client secret rotation is supported. Driven by client policies, with up to two secrets live at once, so consumers move to the new one on their own schedule rather than inside a window where the old one is already dead.

Preview​

Token exchange delegation lets a user consent to a client acting on their behalf through a new delegation:client:<client-id> parameterized scope. The issued token carries an act claim naming the actor, and the part that matters if you are pointing agents at this: it cannot reach the Admin API even when the client holds service-account credentials, so a leaked delegation token does not escalate into one. Authorization runs exclusively through FGAP v2's delegate and delegate-members scopes, standard token exchange now rejects subject tokens carrying delegation claims, and a new client policy executor restricts may_act per client. Separately, tokens issued from an impersonation session now always carry act and the impersonator's identity — not optional, not disableable.

Verifiable credential issuance (OID4VCI) moves to preview (--features=oid4vc-vci), adding revocation when refresh tokens are revoked, an Application Initiated Action so a user can request a credential inside a session, and configurable key attestation. Acting as a verifier (OID4VP) and the mdoc format stay experimental.

Admin API v2 for clients moves to preview (--features=client-admin-api:v2): strict validation, an accurate OpenAPI spec, a generated JavaScript client and a CLI. The Operator's KeycloakOIDCClient and KeycloakSAMLClient custom resources were promoted with it — declarative client management without a reconciler of your own. Parameterized scopes (formerly dynamic scopes) also reach preview.

Operational changes worth knowing​

  • Indexes skipped during migration now build themselves. An upgrade on a large table used to skip index creation and leave it to you; Keycloak now builds them in the background after startup, non-blocking, on PostgreSQL, Oracle, MySQL/MariaDB and supported SQL Server editions, and recreates invalid PostgreSQL indexes left by a failed earlier attempt.
  • Cluster and node names are first-class options — --cache-embedded-cluster-name and --cache-embedded-node-name, replacing low-level SPI configuration. The node name used to be random on every start, which made metrics, logs and JGroups diagnostics hard to correlate; under the Operator it is now the pod name.
  • Encrypted PKCS#8 private keys work for HTTPS via --https-certificate-key-file-password, so a key no longer has to be decrypted or wrapped in a keystore first.
  • An SSRF guard for legacy adapter node registration, if you turn it on. A confidential client could register an attacker-chosen hostname at /clients-managements/register-node, which Keycloak would then call for management callbacks such as logout propagation. The new secure-client-node-hostname executor validates hostnames against configured patterns — opt-in, and inert until you attach it to a client policy.
  • An invite-user workflow step sends the action-token email when a user is created, instead of an external call to execute-actions-email.
  • Experimental: a Vert.x-based outbound HTTP client (--features=http-client:v2) replacing Apache HTTP Client for all outgoing connections, a Helm chart for installing the Operator, and Shared Signals emitting RISC account-disabled and account-enabled events.

Organizations: shared identity providers​

An identity provider can now be linked to more than one organization — one corporate IdP serving several business units or subsidiaries, each its own organization, each link carrying its own auto-membership and membership-type configuration. Domain routing moves off the identity provider and onto the domain, so each domain names the provider that handles it and whether to auto-redirect, and a domain gate keeps a user from being auto-added to an organization that does not claim their email domain.

Read that as Keycloak's native Organizations gaining a capability our extension shipped more than two years ago. Phase Two Organizations has supported shared IdPs since July 2024 (keycloak-orgs#249, closed 9 July 2024) — three months before native Organizations existed at all, which arrived in 26.0 on 4 October 2024. The driving case has not changed either: customers with hundreds of organizations authenticating against a single Google Workspace OIDC integration rather than hundreds of separate SAML ones.

The two implementations are not the same thing, so this is not a migration you are behind on. If you run our Organizations extension, you already have shared IdPs and 26.8.0 changes nothing for you. If you are on native Organizations, this is where that gap closes, on upstream's own model — the domain gate and the MANAGED/Unmanaged membership types are native concepts, and the IdP-link migration under Breaking changes below is yours, not ours.

Security fixes​

Seven distinct CVE identifiers appear in the notes: five under Security fixes (one bundles two jackson-databind CVEs) and one under Bugs. Four are Keycloak; three are shipped libraries, not a failed Keycloak control. Severities as published.

CVE / advisorySeverityWhat it is
CVE-2026-12388 / GHSA-jxqv-2jjx-692hmedium 6.5A restricted IdP admin adds a Hardcoded Role mapper and takes realm-admin
CVE-2026-14781 / GHSA-c96p-56gh-3pvwmedium 4.8OIDC broker applies the id_token's email_verified to a different userinfo address
CVE-2026-19608 / GHSA-qxf7-g44v-fgwhmedium 5.3Name-only group claims let a same-named group satisfy a path-specific policy
CVE-2026-4633 / GHSA-rhgq-f8x5-j2jclow 3.7Identity-first login reveals which email domains are Organizations, and which accounts exist
CVE-2026-54515 / GHSA-5jmj-h7xm-6q6vmedium 5.3jackson-databind: case-insensitive matching restores @JsonIgnoreProperties fields
CVE-2026-59889 / GHSA-5gvw-p9qm-jgwhmedium 6.5jackson-databind: @JsonView not enforced on @JsonUnwrapped containers
CVE-2026-59903 / GHSA-8c42-7qj2-3j46medium 6.5Netty's CorsHandler overwrites your Vary header, enabling CDN cache poisoning

CVE-2026-12388 is the one that could change your week. It needs an administrator account, but a narrow one: if you delegate identity-provider management without granting realm administration, that boundary does not hold, and no setting closes it.

CVE-2026-4633's advisory does not describe this fix. Its range, < 26.6.1 and < 26.4.12, covers an earlier instance of the same flaw; upstream reused the identifier for a second instance fixed here without updating the advisory. On 26.6 or 26.7 the range says you are patched; against this one you are not.

If you run 26.7, 26.6 or 26.4​

No backport of the four Keycloak CVEs has landed on another live branch. Verified 1 October against branch histories and each tag's Quarkus BOM:

BranchNewest releaseNewest tagThese fixesImageOn CockroachDB
26.826.8.026.8.0all seven26.8.026.8.0
26.726.7.526.7.5dependencies only26.7.526.7.5
26.626.6.4 (June)26.6.7jackson only26.6.726.6.7
26.426.4.7 (Dec 2025)26.4.16jackson only26.4.1626.4.7 — see below

Those are tags on quay.io/phasetwo/keycloak and, for CockroachDB, quay.io/phasetwo/keycloak-crdb. Both 26.8.0 images were built and pushed this morning, within about an hour of the upstream release, linux/amd64 and linux/arm64:

docker pull quay.io/phasetwo/keycloak:26.8.0
docker pull quay.io/phasetwo/keycloak-crdb:26.8.0

The vanilla image is stock Keycloak built from the tag's own Dockerfile, with no Phase Two code in it — that is a different image. The CockroachDB one carries the CockroachDB port on top of the same tag.

One gap worth stating plainly: the CockroachDB line stops at 26.4.7 on the 26.4 branch. We build the 26.4 backport tags for the vanilla image up to 26.4.16, but have not extended the CockroachDB build to them, so a CockroachDB deployment on 26.4 has nothing newer than December 2025. If that is you, tell us and we will look at it.

26.7.5 picked up Netty 4.1.138 via Quarkus 3.33.4 without naming CVE-2026-59903; 26.6.7 and 26.4.16 remain on 4.1.136. CVE-2026-19608 and the Netty fix carry backport/26.6 and backport/26.7 labels — intended, but neither commit is on those branches yet. We publish images for backport tags upstream never announces, which is why the 26.6 and 26.4 rows have a tag newer than their newest release. 26.5 is archived and will get nothing.

Breaking changes and migration​

Four to rehearse. Login failures now persist to the database by default, adding DB load (login-failures:v1 restores the old behaviour, deprecated). Organization IdP links became many-to-many: existing ones migrate as MANAGED, new ones default to Unmanaged. A custom social-providers.ftl needs testing against the redesigned login page. And client GET endpoints no longer return secrets to view-clients holders, breaking view-only tooling that read them.

How to upgrade​

Read the migration changes, then rehearse on staging: login failures is the change with a capacity consequence, and indexes skipped during migration now build in the background afterwards. Our production checklist covers the exposure questions above; 26.7.5, published twelve hours before this one, was the last release we covered.

Our managed Keycloak clusters are patched in our maintenance windows, under SOC 2 Type II and ISO 27001. Talk to us if you would rather not schedule this one.