26.8.0
Highlights
This release features new capabilities for users and administrators of Keycloak. The highlights of this release are:
-
Issue and verify digital wallet credentials with OID4VCI and OID4VP
-
Automate user provisioning across identity systems with the SCIM API
-
Run multi-cluster deployments without an external cache using stateless mode (now supported)
-
Simpler administration with automatic index creation, reduced memory usage, and enhanced HTTP performance
-
Token exchange delegation for AI agents and automation with consent and FGAP authorization
Read on to learn more about each new feature. If you are upgrading from a previous release, also review the changes listed in the upgrading guide.
Security and Standards
Verifiable Credential Issuance promoted to preview with credential management and revocation
The OpenID for Verifiable Credential Issuance (OID4VCI) feature has been promoted from experimental to preview.
It can now be enabled with --features=preview or --features=oid4vc-vci.
Credential lifecycle management now includes revocation when refresh tokens are revoked, and a new Application Initiated Action (AIA) lets users request credential issuance within an authenticated session.
Key attestation is configurable in the admin console with hardened x5c certificate validation following the HAIP profile.
This release also adds experimental support for the mdoc format, provided by the new experimental feature oid4vc-mdoc.
Integration guides for the Lissi and Valera wallets are available, along with documentation for SD-JWT signing key setup, credential management, and revocation.
Example applications are provided in this release (for illustration, not officially supported):
-
Quickstart OID4VCI deployment - a playground for rapid prototyping with mdoc and SD-JWT credentials
-
OID4VCI Demo in Keycloak FAPI playground - available to show the details of the OID4VCI protocol messages exchanged between wallet and issuer, and to illustrate advanced concepts like proofs, attestation, credential refresh, and more.
The attestation-based client authentication (client-auth-abca), pre-authorized code grant (oid4vc-vci-preauth-code), REST credential offer endpoint (oid4vc-vci-rest-credential-offer), and OpenID4VP (oid4vc-vp) remain experimental features.
Many community members were involved in the development. Many thanks to Awambeng, Babis Routis, ShurongCAO, Pascal Knüppel, Thomas Darimont, Dominik Schlosser, forkimenjeckayang, Francis Pouatcha, Hager Khamis, Ingrid Kamga, Naman Jain, Asish Kumar, Ogen Bertrand, Hugo Hakim Damer, Rohit Behera, rameshkumarkoyya, Shashank RM, Thomas Diesler, Vinod Anandan, Palpable and Stefan Wiedemann for the contributions!
Verify credentials with OID4VP (experimental)
Organizations adopting verifiable credentials need a way to accept credential presentations from digital wallets as part of login flows, without requiring a traditional password.
Keycloak can now act as an OID4VP verifier, enabling authentication flows where users present verifiable credentials from their wallets.
The verifier supports cross-device presentation flows and the direct_post.jwt encrypted response mode.
Trust material for credential verification can be delegated to an external identity provider by alias, and SD-JWT User Attribute and Session mappers are available to extract claims from presented credentials.
Thanks to Dominik Schlosser for this contribution.
React to account status changes with Shared Signals Framework (experimental)
The experimental Shared Signals Framework (SSF) support now emits RISC account-disabled and account-enabled event types when a user is enabled or disabled, extending coverage beyond the CAEP session and credential events that shipped in 26.7. Additionally, the event structure has been revised for better alignment with the CAEP and RISC specifications, and the admin event store no longer receives unvalidated payloads to prevent PII leakage.
For more details, see the Shared Signals Framework guide.
Parameterized (formerly dynamic) scopes preview support (preview)
Parameterized scopes (formerly known as dynamic scopes) allow clients to pass a parameter value along with the scope name in an OAuth 2.0 authorization request. This is especially useful when a scope represents an entity with a large or dynamic set of values (for example a project name like project:12345), preventing the need to pre-define countless individual client scopes in Keycloak.
Parameterized scopes have officially moved from experimental to preview status.
For more details about the feature, see the Server Administration Guide.
Token exchange delegation with consent, FGAP authorization, and audit trail (preview)
Applications such as AI agents and automation tools need limited, consent-based access to act on behalf of a user without requiring administrator privileges or exposing sensitive credentials.
Users can now delegate access to a client application through OAuth consent using the new delegation:client:<client-id> parameterized scope.
The resulting token includes an act claim identifying the client as the actor.
Unlike admin-user delegation, client delegation does not grant Admin API access even if the client holds service account credentials, ensuring that a leaked delegation token cannot escalate privileges.
The delegation:user and delegation:client client scopes are now auto-created as Optional scopes in all realms, and delegation authorization is controlled exclusively through Fine-Grained Admin Permissions V2 using the delegate and delegate-members scopes.
Delegation audit events now include the client identity, and standard token exchange rejects subject tokens carrying delegation claims to prevent bypass.
A new client policy executor allows administrators to restrict the may_act claim in access tokens, giving per-client control over which clients can participate in delegation.
Token exchange delegation support status is now preview.
For more details, see the Token exchange delegation section.
Track impersonation across token lifecycle and downstream services
When an administrator impersonates a user, downstream resource servers and audit systems had no reliable way to identify that a token was issued under impersonation or who the impersonator was.
Token lifecycle events (CODE_TO_TOKEN, REFRESH_TOKEN, and others) are now enriched with impersonator and impersonator_id details, providing a complete audit trail across all token operations performed under impersonation.
Additionally, tokens issued from impersonation sessions now include the act (actor) claim (RFC 8693 Section 4.1) in both access tokens and ID tokens, allowing downstream resource servers to identify the impersonator.
The claim is always present and cannot be disabled.
Secure client cluster node registration
A new client policy executor, secure-client-node-hostname, is available to protect against server-side request forgery (SSRF) via the legacy adapter cluster node registration endpoint (/clients-managements/register-node).
A confidential client could previously register an attacker-chosen hostname, which Keycloak would later use as the destination for management callbacks such as logout propagation and push-revocation.
When the executor is attached to a client policy, node hostnames are validated against an administrator-configured list of regex patterns before being persisted. Registrations that do not match any pattern are rejected.
This protection is opt-in and must be explicitly configured to take effect.
Administrators managing deployments that use the legacy adapter node registration feature should add the secure-client-node-hostname executor to a client policy and configure the allowed hostname patterns.
Hostname patterns match against DNS hostnames and IPv4 addresses. Port suffixes are always rejected. Patterns are matched against the bare hostname or IP address.
Administration
Declarative client management with Admin API v2 (preview)
The Client Admin API v2, introduced as an experimental feature in Keycloak 26.7, has been promoted to preview.
It can now be enabled with --features=preview or --features=client-admin-api:v2.
The API provides strict validation, declarative configuration, and an accurate OpenAPI specification for managing OIDC and SAML clients.
It can be consumed through a Java client, an auto-generated JavaScript client, and a CLI, and the Keycloak Operator uses it to manage clients declaratively via the KeycloakOIDCClient and KeycloakSAMLClient custom resources.
The Operator’s KeycloakOIDCClient and KeycloakSAMLClient custom resources were also promoted to Preview.
For more details, see the Admin API v2 guide and the Managing Keycloak Clients operator guide. Feedback is welcome!
Client Secret Rotation (supported)
Rotating client secrets in production without downtime required manual coordination and risked service interruptions if the old secret was invalidated before all consumers switched to the new one.
Client Secret Rotation allows confidential clients to rotate their secrets through client policies, keeping up to two concurrently active secrets for seamless rotation without downtime. Administrators can plan the rotation schedule and anticipate when applications need to adopt the new secret, reducing the risk of secret leakage.
In this release, Client Secret Rotation is promoted from preview to supported. For more details, see the Server Administration Guide.
Invite users automatically with workflows
Sending invitation emails to newly created users previously required external automation or a call to the Admin REST API’s execute-actions-email endpoint.
The new invite-user workflow step sends an action-token email automatically when a user is created, without requiring external tooling or a custom workflow step provider.
Administrators can configure which required actions the user must complete (defaulting to password update and email verification), and optionally specify a client and redirect URI for the post-completion flow.
For details, see the Defining Steps guide.
Thanks to bilkoua for this contribution.
Protocol mapper allow-list for Admin REST API
Client Policies now provide the allowed-protocol-mappers executor to restrict protocol mapper types that can be created or updated through the dedicated Admin REST API protocol mapper endpoints.
SCIM API (supported)
The SCIM (System for Cross-domain Identity Management) API provides a standards-based interface for managing users and groups within a realm. It enables seamless integration with identity management systems and applications that support the SCIM protocol.
In this release, the SCIM API is promoted from preview to supported. The SCIM API received extensive improvements including support for multivalued user attributes, User Profile permissions, Fine-Grained Admin Permissions in search filters, and improved performance for large user bases. For more details, see the Managing users and groups through SCIM documentation.
Configuring and Running
Multi-cluster v2 (supported)
Multi-cluster v2 enables connecting two or more Keycloak clusters without an external Infinispan cluster by using the stateless feature.
Session data is stored in the database, simplifying the deployment architecture compared to multi-cluster v1.
In this release, multi-cluster v2 and the stateless feature are promoted from preview to supported.
The feature is disabled by default and can be enabled with --features=stateless.
A new deployment guide for bare-metal and VM environments is now available alongside the existing Kubernetes guide.
For more details, see <@links.ha id="multi-cluster-v2-introduction" />.
Multi-cluster v1 (deprecated)
Multi-cluster v1 (the multi-site feature) is deprecated and will be removed in a future major release.
Multi-cluster v2, which uses the stateless feature, is the recommended replacement.
It simplifies the deployment architecture by eliminating the external Infinispan cluster and its cross-site replication.
If you are using --features=multi-site, migrate to --features=stateless.
For migration instructions, see Migrating from multi-cluster v1 to v2 in the High Availability Guide.
Support for encrypted PEM files for TLS certificate and private key
Deploying Keycloak with encrypted private keys previously required converting them to an unencrypted format or using a keystore, adding operational complexity.
Keycloak now supports encrypted PKCS#8 private keys in PEM format for HTTPS configuration.
Use the new --https-certificate-key-file-password option to provide the decryption password.
The management interface also supports this via --https-management-certificate-key-file-password.
For details, see <@links.server id="enabletls"/>.
Login failures now stored in the database
Brute force detection data is now persisted in the database by default, so temporarily locked-out users remain locked out across cluster restarts.
Deployments using the multi-site or clusterless features continue to store login failures in the external Infinispan cluster.
The previous in-memory behavior is available as login-failures:v1 but is deprecated.
For details, see the Upgrading Guide.
First-class CLI options for cluster and node name
The embedded cache cluster name and node name can now be configured with the new --cache-embedded-cluster-name and --cache-embedded-node-name CLI options, replacing the low-level SPI options that were previously required.
By default, the node name is a random value generated on each start, making it difficult to correlate metrics, logs, and JGroups diagnostics across restarts. Setting a stable node name is especially useful for observability tools such as Grafana dashboards and log aggregation.
When deploying with the Keycloak Operator, the node name is now automatically set to the Kubernetes pod name (for example, keycloak-0).
For standalone deployments on Kubernetes, set KC_CACHE_EMBEDDED_NODE_NAME using the downward API to inject the pod name.
For non-Kubernetes deployments, pass --cache-embedded-node-name=<name> with a value that uniquely identifies each node.
Automatic non-blocking index creation for large tables
When upgrading Keycloak with large database tables, index creation was previously skipped during schema migration to avoid blocking startup. Operators had to create the missing indexes manually.
Keycloak now automatically creates skipped indexes in the background after startup using non-blocking index creation on PostgreSQL, Oracle, MySQL/MariaDB, and supported Microsoft SQL Server editions. Invalid PostgreSQL indexes left by failed previous attempts are detected and recreated automatically. On databases without non-blocking support, Keycloak continues to log the SQL for manual execution.
Vert.x-based outbound HTTP client (experimental)
Keycloak uses the Apache HTTP Client for all outgoing connections to external services such as identity providers, OCSP responders, and backchannel logout endpoints. As Keycloak already runs on Vert.x/Netty for inbound traffic, using a separate HTTP stack for outbound connections adds unnecessary complexity and dependency overhead.
Keycloak now provides an experimental Vert.x-based HTTP client that replaces the Apache HTTP Client with Vert.x/Netty for all outgoing connections.
To enable it, start Keycloak with --features=http-client:v2.
When enabled, all outgoing HTTP traffic uses the Vert.x HTTP client. Existing configuration options work the same way.
For more details, see the Configuring outgoing HTTP requests guide.
Helm Chart Operator install (experimental)
Keycloak now releases an experimental Helm chart to install the Operator.
For installation instructions, see the Operator Guide.
Organizations
Shared identity providers across organizations
Identity providers can now be linked to multiple organizations, enabling scenarios such as a single corporate identity provider serving users across different business units or subsidiaries, each represented as a separate organization. Each identity provider link carries its own auto-membership and membership type configuration, allowing fine-grained control over how users are onboarded per organization.
Domain routing has been moved from the identity provider to the domain entity. Each domain can independently specify which identity provider handles authentication and whether users are auto-redirected. The domain gate ensures cross-organization isolation — a user is only auto-added to an organization that claims their email domain, even when multiple organizations share the same identity provider.
New identity provider links created after upgrading default to the Unmanaged membership type. Existing links are migrated with the Managed type to preserve previous behavior.
For setup instructions and common configuration patterns, see Common setup recipes in the Server Administration Guide. For migration details, see the Upgrading Guide.
Themes
Redesigned identity provider buttons on the login page
The social identity provider section on the login page has been refreshed with updated icons, a new divider layout, and improved button labels.
If you have a custom login theme, see the Upgrading Guide for details on what changed.
Upgrading
Before upgrading refer to the migration guide for a complete list of changes.
All resolved issues
Security fixes
- #50444 [CVE-2026-12388] IdP mapper admin role escalation
identity-brokering - #50618 [CVE-2026-14781] OIDC broker applies id_token email_verified to userinfo email, marking unverified addresses as verified
oidc - #51865 [CVE-2026-19608] Name-only group claims let same-name groups satisfy path-specific group policies
authorization-services - #52168 CVE-2026-54515 CVE-2026-59889 com.fasterxml.jackson.core:jackson-databind 2.22.0
dist/quarkus - #52169 CVE-2026-59903 io.netty:netty-codec-http:4.1.136.Final
dist/quarkus
Weaknesses
- #47295 LDAP bind credentials sent to new server when connection URL is changed
ldap - #49022 SAML ECP endpoint returns inconsistent Content-Type on error responses
saml - #49220 Client GET endpoints return raw client secrets to view-clients role holders
admin/rbac - #49239 Stop storing client private keys in the database and deprecate generate endpoints
admin/rbac - #49242 SMTP masked credential substitution does not verify destination fields haven't changed
admin/api - #49610 Document trust boundaries for attribute-based conditions with self-registration enabled
workflows - #49784 UserInfo Endpoint: Add null-check for SignatureProvider when validating JWT bearer tokens
oidc - #49785 UserInfo Endpoint: Handle malformed Content-Type header gracefully
oidc - #50123 Client baseUrl URI-scheme validation missing during realm and partial import
admin/api - #50124 OIDC: Inverted return value in `compareSessionIdWithSessionCookie()` backwards-compatibility path
oidc - #50131 Client Policies: `allowed-protocol-mappers` enforcement missing for Admin REST API protocol mapper operations
admin/api - #50135 OIDC: PAR request URIs stored in single-use cache without realm binding
oidc - #50368 OID4VCI: Account API delete endpoint for issued verifiable credentials missing ownership validation
oid4vc - #50468 Parameterized Scopes: Pre-authentication username enumeration via username/delegation scope types
- #50469 Parameterized Scopes: First-match prefix resolution allows permissive scope to shadow stricter scope
- #50470 Parameterized Scopes: CustomRegexScopeType applies admin regex to unbounded attacker input without length cap
- #50471 SCIM: Missing lower-bound validation on count parameter in list operations
scim - #50473 SCIM: Groups endpoint members operations do not enforce isAdminUser check
scim - #50475 SCIM: PATCH operations list has no size limit — missing maxOperations enforcement
scim - #50489 Client API v2: Temporary client creation via addClient() shim bypasses realm-level authorization
admin/api-v2 - #50493 Client API v2: Operator disables TLS hostname verification for admin connection
admin/api-v2 - #50517 OID4VCI: key_attestations_required not enforced when key_attestation header absent from proof JWT
oid4vc - #50518 OID4VCI: Key attestation x5c chain validated against system cacerts with no EKU or revocation
oid4vc - #50520 OID4VCI: Unbounded expire parameter on /create-credential-offer allows indefinite pre-auth codes
oid4vc - #50521 OID4VCI: getAttestationRequirements() hardcodes proof-type key to jwt ignoring other types
oid4vc - #50523 OID4VCI: LD-VC signer fetches remote @context URLs over HTTP with no allowlist or cache
oid4vc - #50524 OID4VCI: User-editable did attribute used as credential subject with realm-local uniqueness only
oid4vc - #50533 Identity Broker v2: Wrong-IdP token returned after account-linking due to un-namespaced session note
oidc - #50602 Handling HTTP/2 connection coalescing issues originating from wildcard certificates
dist/quarkus - #50749 OID4VC JWT proof JWK claim type confusion crashes proof validation
oid4vc - #50934 Credential request decryption accepts RSA1_5 for RSA-OAEP-256 encryption keys
oid4vc - #50965 URI client-policy executors omit OIDC front-channel logout URI
oidc - #50985 SCIM Users filter leaks hidden group membership under FGAP
scim - #50986 SCIM Groups filter leaks hidden user membership under FGAP
scim - #50987 SCIM reads and filters bypass user-profile view permissions for mapped attributes
scim - #50988 Workflow group membership events confuse slash-named groups with nested paths
workflows - #50989 Workflow role grant events match client and realm roles by bare name
workflows - #50991 SCIM user writes bypass user-profile edit permissions for custom attributes
scim - #50999 Same-second refresh-token rotation allows stale token replay
oidc - #51109 SD-JWT verification accepts signatures whose algorithm differs from the JWS header
oidc - #51127 Persistent User Sessions: cache-miss unconditionally re-hydrates cache from DB, resurrecting deleted sessions
storage - #51139 Server info exposes database operational details to view-realm administrators
dist/quarkus - #51158 User partial filters ignore ancestor group membership denies
admin/fine-grained-permissions - #51211 SAML: Add signature verification for inbound LogoutResponse messages
saml - #51212 JOSE: Base64Url decoder throws unchecked exception on padding-only input
oidc - #51241 Client update admin events retain private-key attributes
admin/api - #51242 Registration access token regeneration stores live bearer tokens in admin events
admin/api - #51243 RP-initiated logout can suppress upstream broker logout with forged initiating_idp
oidc - #51276 Unrestricted Class.forName() on query parameter in ComponentResource.getSubcomponentConfig
admin/api - #51311 Unauthenticated NullPointerException (HTTP 500) on OIDC Dynamic Client Registration PUT via the "scope" field (CWE-476)
oidc - #51328 Client type read-only client properties can be bypassed during registration
oidc - #51535 Admin API v2 client update does not clean up stale rotated secret attributes
admin/api-v2 - #51699 Missing security headers on root-path redirect when http-relative-path is configured
dist/quarkus - #52013 [OID4VCI] unauthenticated RSA1_5 padding oracle in OID4VCI credential requests
oid4vc - #52058 Add warning about dynamic urls to reflect the danger of hostname pollution
docs - #52105 OID4VC issued credential deletion not scoped to path user or realm
oid4vc - #52106 SAML metadata key cache is not invalidated on client updates
saml - #52398 Concurrent completion of one WebAuthn registration ceremony persists multiple passwordless credentials
authentication/webauthn - #52400 LDAP password-policy response control parser defects — warning/error tag collision (forced-password-change forgery and suppression) plus uncaught NumberFormatException login failure
ldap - #52598 SCIM membership PATCH events omit the changed relationship from audit trail
scim - #52599 SCIM legacy query roles infer cross-resource memberships when FGAP is disabled
scim - #52640 SCIM Group DELETE bypasses administrative-resource protection through cascade
- #52642 SCIM user deletion skips security-state cleanup
- #52644 Absence-based completion predicate cannot distinguish consumed from never-persisted events
- #52645 Bulk HQL executeUpdate bypasses AsyncCommitIntegrator security classification
- #52646 Concurrent failures at brute-force reset boundary can erase newly recorded attempts
- #52650 LoginFailureEntity async commit classification can discard failure counters after failover
infinispan - #52651 Multi-Cluster v2 RPO "No data loss" conflicts with default async commit of ephemeral data
docs - #52664 Password denylist can be bypassed under Turkish locale
authentication - #52665 Same-name client role authorizes victim-targeted credential offers via role namespace confusion
oid4vc - #52666 Reusing a rotated OID4VCI refresh token repeatedly reissues credential authority
oid4vc - #52667 User-editable mapped attribute can extend an SD-JWT credential beyond the issuer-configured lifetime
oid4vc - #52668 Credential issuance ignores the administrator-approved attribute snapshot
docs - #52669 Unauthenticated credential requests trigger private-key JWE decryption before bearer authentication
oid4vc - #52670 Refreshing a stolen targeted offer lets another user bypass offer-required issuance
oid4vc - #52671 OID4VCI SD-JWT issuance makes array claims all-or-nothing disclosures
oid4vc - #52681 kcadm preserves world-readable permissions on existing config files
admin/api-v2 - #52684 SCIM search writes raw filter values to debug logs
scim - #52691 Token exchange provider routing allows delegation tokens to bypass actor validation via standard exchange
token-exchange - #52696 Recovered sites can enforce stale security configuration for up to one hour
storage - #52732 [OID4VCI] Make sure that OID4VCI access token usable just for credential endpoint
oid4vc - #52919 OID4VCI: Preventing memory leak and adding decompression limit
oid4vc - #53166 Realm import resets organization-IdP link policy to permissive defaults
identity-brokering - #53307 Identity-provider reads disclose organization links outside the caller's scope
identity-brokering
Deprecated features
- #44062 Should Kerberos Credential delegation be deprecated?
- #51921 Deprecate legacy OIDC client switches from 'OpenID Connect Compatibility Modes'
oidc - #52121 Deprecate volatile sessions and allow opting out of session caching
- #52923 Deprecate 'Full scope allowed' client switch
oidc - #53219 Deprecate other client registration providers than OIDC
Removed features
- #51897 Deprecate route from AUTH_SESSION_ID cookie for sticky sessions
- #52130 Deprecate clusterless feature
- #52480 EOL Keycloak Realm Operator
New features
- #16738 Supported client secret rotation
- #48899 SSF: Add support for RiscAccountPurged event
ssf - #50644 [OID4VP] Support direct_post.jwt (encrypted) response mode
authentication - #50876 update admin client tests to use sort and filter
Enhancements
- #16947 group.spec.ts does not contain example of how to
These notes run past the length kept in the archive. The rest is on the publisher’s page.