Chapter 2. Release-specific changes


2.1. Breaking changes for 26.6.7

Breaking changes are identified as those that might require changes for existing users to their configurations or applications. In minor or patch releases, Red Hat build of Keycloak will only introduce breaking changes to fix bugs.

Two changes affect how claims are handled in the authorization services token endpoint:

  • Claims with the kc. prefix are now reserved for server-controlled evaluation context attributes (such as kc.time.date_time, kc.client.id, and kc.realm.name). User-supplied claims with this prefix, whether pushed via claim_token or via the UMA permission ticket, are filtered out before policy evaluation. If your authorization policies rely on custom claims that start with kc., rename them to use a different prefix.
  • When both a UMA permission ticket and a claim_token contain claims with the same key, ticket claims now take precedence. Previously, claim_token claims would silently override ticket claims on collision. This change ensures that claims set by the resource server when creating the permission ticket cannot be overridden by the requesting party.

Redirect URIs (redirect_uri and post_logout_redirect_uri) containing OIDC response parameters such as state, code, or session_state are now rejected by default. These parameters conflict with the parameters that Red Hat build of Keycloak attaches to the redirect URI after authentication or logout, potentially causing HTTP Parameter Pollution. This check also covers parameters in the URI fragment (used with response_mode=fragment).

If you used post_logout_redirect_uri pointing directly to the Red Hat build of Keycloak OIDC login page (for example post_logout_redirect_uri=\https://mykchost/realms/myrealm/protocol/openid-connect/auth?response_type=code&client_id=myclient…​), replace it with a callback URL pointing to your application (for example post_logout_redirect_uri=\https://myapp/logout-callback) and ensure that opening that callback URL in your application redirects to Red Hat build of Keycloak OIDC login.

To temporarily allow the previous behavior, enable the allow-oidc-params-in-redirect-uris server option in the OpenID Connect provider configuration. A per-client override is also available via the allow.oidc.params.in.redirect.uris client attribute, allowing gradual migration of individual clients. Both options are deprecated and will be removed in Red Hat build of Keycloak 27.

2.2. Breaking changes for 26.6.6

2.2.1. The view-system admin role no longer exists

Since version 26.5.4, when introduced, the view-system admin role was marked as deprecated. In this release, the role has been removed for security reasons.

Access to full server information is now restricted to users in the master realm holding the manage-realm role.

If you are still relying on the view-system role, you should consider accessing the full server information using a user (or service account) from the master realm and granted with manage-realm admin roles.

Before upgrading, you should check if any of your users, service accounts, or groups are still relying on the view-system role and review their access controls to ensure they have the necessary permissions to access the server information after the upgrade. The manage-realm admin role is a high-privileged role and should only be granted to highly-trusted accounts.

The deprecated legacy client-initiated account linking endpoint (/realms/{realm}/broker/{provider}/link) is now disabled by default. Migrate to Application Initiated Actions (AIA) with kc_action=idp_link. See Client initiated account linking for details.

To temporarily restore the previous behavior, see OpenID Connect provider configuration and enable allow-client-initiated-account-linking server option. This option is deprecated and will be removed in a future release.

2.3. Breaking changes for 26.6.5

The client scope assignment endpoints on a specific client now require the caller to have manage permission on client scopes, in addition to the existing manage permission on the target client. The listing endpoints for default and optional client scopes now return an empty list if the caller lacks view permission on client scopes.

If you have delegated administrators that assign client scopes using Fine-Grained Admin Permissions, ensure they also have the manage-clients realm admin role or a type-level manage permission on the Clients resource type.

In this release, access to the Admin API is only granted to users with admin roles that are directly assigned to them, either through direct role assignments or group memberships. Admin roles granted via protocol mappers will no longer grant Admin API access.

This change was made to enhance security in realm administration delegation scenarios. Developers with limited realm administration permissions who have access to manage client protocol mappers or client scopes could previously map admin roles into tokens and gain unintended access to the Admin API. This is no longer possible.

If your existing deployment was relying on admin roles granted via protocol mappers to access the Admin API, you should update your configuration to directly assign admin roles to users or groups instead.

To verify if your deployment is affected, review any client protocol mappers that map admin roles to tokens. For each mapper found, ensure the affected users and service accounts have the required admin roles directly assigned either through direct role assignments or through group memberships. You can verify this in the Keycloak Admin Console by checking the user’s role assignments and group memberships in the target realm.

2.4. Breaking changes for 26.6.4

The Java Keystore provider allows the realm administrator to load keys from an encrypted Java keystore file instead of the Red Hat build of Keycloak’s database. Since this release, the path of the file is restricted to be inside a folder whose name should be the realm name and, in turn, this realm folder should be inside a fixed main directory for keystores (by default the data directory, ${kc.home.dir}/data). For example, for a realm called test, all keystore files should be located under ${kc.home.dir}/data/test. This way, Red Hat build of Keycloak avoids leaking information from the File System and the keys are isolated between realms.

The main keystores directory, where the different realm folders are located, can be customized using a provider startup option:

kc.[sh|bat] start --spi-keys--java-keystore--keystores-path /path/to/keystores

When a keystore is created or updated, the keystore configuration option is checked to be a file under the commented realm folder. If the keystore is outside its boundaries, the operation fails. This new behavior means that existing keystores continue working but cannot be updated or modified until the file is copied to an allowed path. Imports from a previous configuration, with store files outside the realm folder, will fail in the same way.

If you are using a Java Keystore file to provide keys for a realm, please copy the keystore inside the appropriate realm folder and update the java-keystore provider configuration accordingly.

For more information, see Configuring realm keys chapter in the Server Administration Guide.

2.5. Breaking changes for 26.6.3

The wildcard comparison for valid redirect URIs does not affect the hostname anymore. Previously patterns like https://example.com* were accepted and lead to allow unintended domains like https://example.com.other.domain.com. Since this release, the hostname does not accept such type of wildcard and those patterns will be managed as if the wildcard is after the hostname https://example.com/*. The full wildcard for the hostname https://* is still accepted because its interpretation cannot be misunderstood.

Note that OAuth 2.0 recommends exact string matching in the Security Best Current Practice and draft for OAuth 2.1 enforces it. Red Hat build of Keycloak recommends to not use any wildcard valid redirect URI for clients. See Unspecific redirect URIs in the Server Administration Guide for more information.

2.6. Breaking changes for 26.6.2

Breaking changes are identified as those that might require changes for existing users to their configurations or applications. In minor or patch releases, Red Hat build of Keycloak will only introduce breaking changes to fix bugs.

2.6.1. Loopback Hostname Verification on Windows

Setups on Windows that previously relied on custom machine names or non-standard hostnames for loopback (for example, 127.0.0.1 resolving to a custom name) may require updates to their trusted domain configuration. Only localhost and *.localhost are now recognized for loopback verification.

Red Hat build of Keycloak now consistently normalizes loopback addresses to localhost for domain verification across all platforms. This change ensures predictable behavior for trusted domain checks, regardless of the underlying OS.

2.6.2. Validation of client session timeouts

Previous versions did not validate client settings against the realm settings for SSO session idle and max lifetime, including the remember me settings of the realm. This leads to those settings either not being effective with unexpected results to administrators, or to refresh tokens issued where the user session might have already expired when the client was trying to refresh the token.

Red Hat build of Keycloak now validates when creating or updating realms that on the realm level the Client session settings do not exceed the SSO session settings.

It also validates that a client specific settings for Client Session Idle and Client Session Max does not exceed the realm settings when a client is created or updated, and will show a validation error when the validation fails. It does currently not validate an individual’s client settings when the realm SSO settings or remember me changes, though this might change in future releases.

You are only affected by the change:

  • if you have configured a client-specific Client Session Idle and Client Session Max setting in the Advanced tab of the client configuration that exceeds the realm settings, or
  • if you configured on the realm level client session settings that exceed the realm session settings.

If you are affected by the change, you will see error messages the next time you update or import an affected client or realm.

In this version, JavaScript-based policies can only be deployed if the scripts feature is enabled.

Until now, JavaScript-based policies were always enabled regardless of the scripts feature flag. However, this behavior was causing confusion as users expected that disabling the scripts feature would also disable JavaScript-based policies. It was also not aligned with how other script-based features work in Red Hat build of Keycloak.

If you have existing JavaScript-based policies, make sure to enable the scripts feature when starting Red Hat build of Keycloak.

The 'secure-client-uris' client policy executor has been updated to enforce stricter validation on Client URIs. This aligns with FAPI 2.0 security requirements by mandating TLS (HTTPS) for client endpoints.

HTTPS Enforcement: The following URIs must now use the https scheme. Existing clients configured with http in these fields will fail validation during updates: 'Post logout redirect URIs', 'Logo URL', 'Policy URL', and 'Terms of Service URL'.

Expanded Wildcard Support: The + wildcard character is now allowed in 'Valid post logout redirect URIs' and 'Web origins'. Configuring + defers validation to the client’s standard 'Valid redirect URIs'. Since redirect URIs are already checked for HTTPS, using the wildcard maintains FAPI 2.0 compliance while reducing configuration duplication.

Administrators must ensure that all configured URIs for the fields listed above use https. Clients attempting to update or register with http in these fields will fail validation when using the 'secure-client-uris' executor.

The JWT authorization grant and the client assertion authentication use the issuer claim passed in the assertion to locate the Identity Provider defined in Red Hat build of Keycloak, and that provider validates the claims and signature in the assertion. Since this version, the issuer configuration option must uniquely identify one provider. The grant operation or the assertion client authentication fails if more providers are returned for a single issuer. In the same way, the Identity Providers, when configured to allow the JWT authorization grant or client assertions, are validated to have a unique issuer defined in their configuration. Any update or add operation will fail if the issuer collides with another provider.

If you have identity providers defined with the same issuer and tested the JWT authorization grants or client assertions features, please update the providers accordingly before the upgrade. You can update the issuer or disable the provider to avoid the duplicates.

Red Hat build of Keycloak now opens its HTTP(S) and Management ports while initialization is still in progress when the health endpoints are enabled. This resolves problems with long-running migrations on platforms like Kubernetes where a migration might otherwise be aborted, leaving the database in a potentially inconsistent state.

If you use a proxy or load balancer, configure an HTTP health check with the path /health/ready to ensure traffic is only routed to the server once it is fully ready.

If this behavior is not desired or an HTTP health check is not possible, start Red Hat build of Keycloak with --server-async-bootstrap=false to revert to the previous behavior where ports are opened only after initialization completes.

Now Red Hat build of Keycloak, when acting as a SAML Service Provider (SP) in identity brokering or in the adapter, validates the SubjectConfirmationData for the type urn:oasis:names:tc:SAML:2.0:cm:bearer defined in the standard. The elements NotBefore, NotOnOrAfter and Recipient, when present in the assertion, are checked to be in the valid time range and to be the correct destination URI respectively. Previously, similar values were checked for other parts of the SAML response (for example the Conditions element or the destination attribute).

To prepare for the upgrade, verify that the Identity Provider or adapter configurations allow for a sufficient clock skew for the time attributes.

If you see any issue after the upgrade related to this element, please configure the external IdP to set the correct values for the subject confirmation element.

Since this release, the HTTP connections originated from the Red Hat build of Keycloak server do not follow redirects by default. The HTTP result will be the redirect status (3xx) code, and the Location header will not be automatically fetched. With this change, the server avoids retrieving unwanted redirects that can bypass allowed URLs defined by client policies or other future configurations.

The new option allow-redirects (SPI connections-http-client, provider default) is available to revert to the previous behavior. This option is deprecated and will be removed in a future version.

bin/kc.[sh|bat] start --spi-connections-http-client--default--allow-redirects true

For more details, see Configuring Outgoing HTTP requests.

In previous versions of Red Hat build of Keycloak, client scope evaluation allow generating tokens without necessarily having the necessary admin roles or permissions to access the user.

In this release, client scope evaluation now requires at the very least the view-users admin role granted to the realm administrator or any permission that grants the view scope on the user.

The OAuth2 token introspection endpoint now validates that the authenticated client is present in the token’s audience (aud) claim before allowing introspection.

Previously, any authenticated client could introspect any valid token. Now, the introspection endpoint returns {"active": false} if the authenticated client is not in the token’s audience.

2.6.10.1. Migration

To temporarily restore the previous behavior, enable the backwards compatibility option either server-wide or per-client.

To enable the server-wide configuration option allow-token-introspection-without-audience-check, see OpenID Connect provider configuration.

For the per-client option, navigate to Clients select the client that performs the introspection Advanced OpenID Connect Compatibility Modes enable Allow token introspection without audience check.

Note

The per-client option is configured on the client that performs the introspection (the authenticated client), not the client that issued the token.

Warning

Both server-wide and per-client options are deprecated and will be removed in a future release. They log warnings for each introspection request without audience validation.

Recommended migration path:

  1. After upgrade: Enable server-wide option temporarily to restore previous behavior
  2. Identify affected clients: Monitor server logs for warnings about introspection without audience validation
  3. Fix each client: Either add audience protocol mapper to include introspecting client in token’s aud, or enable per-client option
  4. Test and disable: Verify all introspection flows work, then disable server-wide option
Note

For lightweight access tokens, the audience claim may only be present in the introspection response (not in the token itself). The audience check validates the transformed token returned by introspection, ensuring proper validation for both standard and lightweight tokens.

The UserInfo endpoint now rejects lightweight access tokens by default. Lightweight access tokens contain minimal claims and are designed for token introspection.

Previously, lightweight access tokens were accepted by the UserInfo endpoint. Now, the UserInfo endpoint returns a 401 Unauthorized error when called with a lightweight access token.

2.6.11.1. Migration

To temporarily restore the previous behavior, enable the backwards compatibility option either server-wide or per-client. To enable the server-wide configuration option allow-userinfo-with-lightweight-access-token, see OpenID Connect provider configuration.

For the per-client option, navigate to Clients select the client that issues tokens Advanced OpenID Connect Compatibility Modes enable Allow UserInfo with lightweight access token.

Note

The per-client option is configured on the client that issues the token (the azp claim).

Warning

Both server-wide and per-client options are deprecated and will be removed in a future release. They log warnings for each UserInfo request with a lightweight token.

Recommended alternatives to lightweight tokens for UserInfo:

  1. Use token introspection instead: The token introspection endpoint is designed to work with lightweight tokens and will return the full claims
  2. Exchange lightweight token for full access token: Use token exchange to convert a lightweight token to a full access token, then call UserInfo with the full token

2.7. Notable changes at 26.6.7

Notable changes may include internal behavior changes that prevent common misconfigurations, bugs that are fixed, or chenges to simplify running Red Hat build of Keycloak. It also lists significant changes to internal APIs.

When Fine-Grained Admin Permissions is enabled and a delegated administrator has view permission on a group but not on its ancestors, the Admin REST API now returns the full group hierarchy with non-viewable ancestor groups represented as stripped representations. Stripped ancestor representations contain only id, name, path, parentId, and description — sensitive fields such as attributes, realmRoles, clientRoles, and access are omitted.

The subGroupCount field on stripped ancestors reflects the number of visible children included in the response, not the total number of children in the database. This prevents leaking information about groups the administrator cannot access.

In the admin console, non-viewable ancestor groups now appear greyed out and are not clickable in the group tree and breadcrumb navigation. Clicking a viewable child group navigates to its details as expected. Note that when a delegated administrator has view permission only on groups that are not at the top level, the Groups page initially appears empty. The administrator must use the search field to locate their permitted groups.

2.8. Notable changes at 26.6.4

Registration Access Tokens (RAT) can no longer be used to retrieve, update, or delete a client when the client is disabled.

If you attempt to use a RAT to manage a disabled client, the request will be rejected with an HTTP 401 Unauthorized response. To manage a disabled client, you must use admin credentials instead of the client’s RAT.

Note that a RAT can still be used to disable a client, but once the client is disabled, the RAT can no longer be used to enable it again or perform other operations.

2.9. Notable changes at 26.6.3

When the OIDC token endpoint request (or OAuth2 token endpoint request) is sent, a new limit exists for the maximum length of the "token" OIDC/OAuth2 parameter. The maximum length of each "normal" parameter is still 4,000 characters as in the previous version. However, the maximum length of the "token" parameter is increased to 20,000 characters. Also, when the limit for the "token" parameter is reached, the parameter will not be ignored, but the request will fail.

A "token" parameter is considered a parameter containing a potentially long value, such as a long JWT or SAML assertion, with unbounded data, such as possibly a large number off roles inside JWT. Therefore, it applies for parameters such as subject_token, which was sent in case of the Token exchange grant.

If you want to increase or lower those numbers, start the server with the option req-token-params-default-max-size for the default maximum length of the OIDC/OAuth2 token parameter. You can instead use something such as req-params-max-size for one specific parameter. For more details, see the login-protocol provider configuration in the All provider configuration chapter.

Cross-origin requests sent to OIDC endpoints (such as the token, userinfo, token revocation, logout, and PAR endpoints) are now validated against the client’s configured Web Origins before the endpoint reaches its authentication and request-processing logic. Previously, requests carrying an Origin header that did not match any of the client’s allowed Web Origins could be processed up to the point where the response was about to be returned, which could result in inconsistent error responses depending on how far the request progressed.

After this change, such requests are rejected immediately with a CORS failure returning Forbidden (403) HTTP error status. There is no behavior change for same-origin requests (no Origin header) or for cross-origin requests whose Origin is already permitted by the client’s Web Origins configuration.

This change might affect custom Red Hat build of Keycloak extensions.

The implicit transaction handling in Red Hat build of Keycloak previously assumed that a transaction is started once per session, which is usually request-scoped. If it was started a second time, this might have led to an inconsistent state.

Starting with this version, this is now enforced and a session’s transaction can only be started once. This prevents difficult-to-track errors and lost commits. It also ensures that at the start of the transaction, all nested transactions are started if they have not been started earlier.

A transaction is started automatically before the REST endpoint code is invoked, even if the session was created earlier in a filter.

As before, transactions can be nested, which will pause the outer transaction once the nested transaction starts, and will resume the outer transaction once the nested transaction ends.

2.9.4. Validation of client_session_host parameter

The client_session_host parameter is now validated against the client’s registered nodes and management URL.

This parameter is sent by clients during token refresh and is used when the ${application.session.host} placeholder is present in a client’s backchannel logout URL configuration.

It was primarily used by legacy adapters that have been removed.

This improves security by ensuring that only trusted, pre-registered hosts can be used in backchannel logout URLs.

2.10. Notable changes at 26.6.2

Notable changes may include internal behavior changes that prevent common misconfigurations, bugs that are fixed, or changes to simplify running Red Hat build of Keycloak. It also lists significant changes to internal APIs.

The Welcome Page, used to create the initial administrative user, now includes optional fields for First name, Last name, and Email. These fields allow administrators to provide additional profile information when creating the initial admin user. All new fields are optional and do not affect the existing functionality.

2.10.2. PostgreSQL version updates

The latest major release of PostgreSQL 18 is now supported.

We also updated the docs on how to use a TLS certificate for the JDBC-connection when connecting to a PostgreSQL database.

2.10.3. EnterpriseDB Advanced 18 support

EDB 18 is now tested and supported in addition to the existing EDB 17 support.

The UserProfile interface has a new method toRepresentation(boolean). This method allows clients to specify whether to include only the basic attributes in representations or all of them.

The UserProfile interface is a private API and should not be implemented by custom code. However, if you have extensions that implement this interface, you will need to update your code to accommodate this new method.

2.10.5. Additional LOGOUT events

When logging out sessions via the Account Console Red Hat build of Keycloak now creates LOGOUT user events to track this activity. The events are connected to the account client.

When the number of sessions for a user is limited, and you have configured the oldest session to be logged out once the limit is reached, Red Hat build of Keycloak now creates LOGOUT user events to track this. The events are connected to the client that triggered the new login.

2.10.6. Identity Provider refactoring

The private SPI for identity providers has been refactored. This is to allow identity providers to support more use -cases than federated user authentication.

For anyone implementing a custom federated user authentication identity provider and are not extending one provided by Keycloak or AbstractIdentityProvider you need to update your implementation to implement the new UserAuthenticationIdentityProvider interface (all methods remain the same, they have just been moved).

Additionally, both IdentityProviderModel and IdentityProviderRepresentation are now using Boolean values to allow configuration like isHideOnLogin to be null in order to not include these in Identity Provider types that do not need these configurations.

The Account UI and its REST API now shows offline sessions of a user together with regular sessions in the Device Activity tab. A user can log out of those sessions like any other session, including the option Sign out all devices.

When localization for a realm is enabled and a translation for a message key is unavailable for the language the user selected, Red Hat build of Keycloak now attempts to find a matching message key with the realm’s default locale before defaulting to English.

The SPIFFE Identity Provider preview feature now uses the trustDomain configuration instead of issuer. This change was done to make it more explicit that a trustDomain is configured and not the iss of the token, which is usually not set in SPIFFE JWT SVIDs.

On MS SQL Server, the default transaction isolation level is READ_COMMITTED, which can lead to deadlocks during high load. Therefore, the recommended isolation level for Red Hat build of Keycloak is READ_COMMITTED_SNAPSHOT.

Use the following statement to changes this for your database:

ALTER DATABASE [your-database-name] SET READ_COMMITTED_SNAPSHOT ON;

2.10.11. session_state and sid are no longer UUIDs

In OpenID connect, there are several places where the protocol shares a session_state and a sid. The specifications define it as an opaque string. Previous versions of Red Hat build of Keycloak used a UUID for it, while the current version now uses a random base64-encoded string. The length of the string was reduced from 36 characters to 24 characters, although it might increase in the future if additional randomness is required.

The log-console-color previously defaulted to false, but it will now instead check if the terminal supports color.

You may still explicitly disable color support by setting the option to false.

Message keys in translations and error messages generated in the backend no longer support HTML or HTML entities for the login theme. The only exception is the message key termsText which is used to display the terms and conditions for the respective required action that still allows for a limited set of HTML as before. For the Legacy Login Theme, HTML and HTML entities are still partially supported for backward compatibility.

The default login themes have already been updated. If you used them in your translations, please update your translation to use the UTF-8 equivalent if you used HTML entities, and replace HTML with plain text.

If you are running on PostgreSQL as a database for Red Hat build of Keycloak, ensure that the database user has SELECT permissions to the following tables to ensure an efficient upgrade: pg_class, pg_namespace.

This is used during upgrades of Red Hat build of Keycloak to determine an estimated number of rows in a table. If Red Hat build of Keycloak does not have permissions to access these tables, it will log a warning and proceed with the less efficient SELECT COUNT(*) ... operation during the upgrade to determine the number of rows in tables affected by schema changes.

Previous entries in the loginFailures cache never expired, and entries accumulated as users entered wrong credentials, increasing the memory consumption.

Starting with this release, entries will expire based on the “Failure reset time” configured in the “Brute force detection” for the modes “Lockout temporarily” and “Lockout permanently after temporary lockout”. For “Lockout permanently”, entries will not expire as before, as this mode does not have a “Failure reset time”.

In previous versions, the HTTP client (SPI connections-http-client, provider default) had no default for the connection request timeout, which meant unlimited time. In situations with long-running out-going HTTP requests this would cause pool contention.

In this release, the default is 5000 milliseconds. You may adjust the default with a new provider option:

  • Connection request timeout property: connection-request-timeout-millis (default: 5000)

In previous versions, OCSP requests used hardcoded connection and socket timeouts of 10 seconds. In this release, OCSP requests inherit timeouts from the outgoing HTTP client configuration (SPI connections-http-client, provider default).

  • Socket timeout property: socket-timeout-millis (default: 5000)
  • Establish connection timeout property: establish-connection-timeout-millis (default: not set / -1)

If you relied on the previous 10-second behavior, explicitly set the HTTP client timeouts.

When enabling authorization on a new client (creating a Resource Server), Red Hat build of Keycloak no longer automatically creates a “Default Resource”, a “Default Policy”, and a “Default Permission”.

Previously, a single instance of Red Hat build of Keycloak would check and remove expired entries using a cluster-aware scheduled task, with each node attempting to trigger this task every 15 minutes. This led to a situation that the more instances a cluster had, the more often this ran, although it would never run concurrently on two nodes at the same time.

Starting from this version, removal is handled by all Red Hat build of Keycloak instances, with each instance handling the expiration of sessions in different realms. Additionally, a new SPI option has been added to control the frequency of the internal deletion task: --spi-user-sessions—​infinispan—​session-expiration-period (value in seconds). By default, this runs every three minutes. If you now add more instances to a clusters, the expiration is still run at the same interval.

Previously, Red Hat build of Keycloak deleted sessions from the database only once the session idle time including the remember-me idle time had passed.

With the new setup and persistent user sessions enabled, sessions are deleted more timely based on the realm settings on session lifetime and idle time, including the remember me settings. For this, the table OFFLINE_USER_SESSION now has a new column REMEMBER_ME, that is filled for new sessions and updated incrementally for existing sessions. The deletion is triggered currently three minutes after the session has expired to allow for clock skew between instances. Note that this interval can change in future release as we optimize this functionality.

This adds new indexes on OFFLINE_USER_SESSION table to improve performance when retrieving or deleting client sessions.

If those tables contain more than 300000 entries, Red Hat build of Keycloak will skip the index creation by default during the automatic schema migration and instead log the SQL statement on the console during migration to be applied manually after Red Hat build of Keycloak’s startup. See the Upgrading Guide for details on how to configure a different limit.

For each expired user session there is a new user event USER_SESSION_DELETED fired. As part of this change, the process now deletes rows from the table in small batches, instead of issuing a delete statements that affects the whole table. This should allow for better response times when there are a lot of sessions in the table.

When persistent sessions are enabled, session data is available in the database and Infinispan session caches are configured to have num_owners=1. Consequently, state-transfer for embedded caches provides no additional availability for session data, whilst adding significant overhead when Red Hat build of Keycloak nodes leave or join the cluster. Therefore, we now disable state-transfer when the persistent-user-session feature is enabled. Similarly, we now also disable state-transfer for offline session caches when the persistent-user-session feature is disabled.

Organizations can have custom attributes named id. When both organization attributes and organization ID are included in tokens via the organization membership mapper configuration, the organization ID will override any custom id attribute value. Previously, the organization ID was added first and could be overridden by custom attributes. This ensures that the id field in the organization claims always contains the actual organization ID.

If you have a custom organization attribute named id and rely on its value in tokens, you should rename the attribute to avoid it being overridden by the organization ID.

2.10.23. Usage of second-class options

In prior releases, the introduction of a first-class option with a default would cause the second-class option (typically spi or quarkus properties) to no longer be used at all.

For example, spi-truststore—​file—​hostname-verification-policy was marked as deprecated after the introduction of tls-hostname-verifier. However, since tls-hostname-verifier included a default, direct usage of spi-truststore—​file—​hostname-verification-policy was no longer considered.

To ensure that the further introduction of new first-class options does not immediately break existing configurations, the logic for determining the value of a second-class option will now consider the direct usage of the second-class value ahead of a default, or derived default, from the first-class option.

Please review the server startup to see if there are any warnings about the continued usage of second-class options, and update them accordingly.

2.10.24. New option for transaction timeout

A new option transaction-default-timeout has been introduced to configure the default transaction timeout in Red Hat build of Keycloak.

While using Quarkus properties directly is not the supported way to configure Red Hat build of Keycloak, some users may have used quarkus.transaction-manager.default-transaction-timeout to customize the transaction timeout. If you are using this Quarkus property, the new transaction-default-timeout CLI option, when set, will take precedence and override your configuration when upgrading to this version.

To maintain your desired transaction timeout configuration, migrate to using the transaction-default-timeout CLI option and remove the quarkus.transaction-manager.default-transaction-timeout property from your configuration.

2.10.25. Dev Mode defaults to localhost

When running the server in dev mode on a platform other than Windows Subsystem For Linux, the http-host setting will default to localhost. This ensures your dev instance won’t be accessible from other machines. If you want the previous behavior of binding to all interfaces, then explicitly set http-host to 0.0.0.0.

2.10.26. Graceful shutdown of HTTP stack

Starting with this version, Red Hat build of Keycloak will apply a shutdown delay and a shutdown timeout of one second each to allow a graceful termination.

Users should adjust those values depending on their proxy setup. For more details, see Graceful HTTP shutdown.

With proxy-headers set to xforwarded, the server can determine the proxy context path from the X-Forwarded-Prefix header.

2.10.28. New brute force locking mechanism

There is a new brute force locking mechanism applied to all brute force modes. It is called Secondary Authentication Failures Lockout. The brute force protector counts secondary authentication failures only (for example OTP), and when the maximum specified number is reached, the account is permanently locked even in temporary locking modes. This prevents attacks on second factor authenticators such as OTP when the attacker has already guessed the password.

This new brute force locking mechanism also changes the original behavior of brute force protection. It is applied only to a subset of authentication mechanisms (passwords, OTP, and recovery codes).

2.10.29. Client secret authentication method

OIDC specification has multiple client authentication methods. Two of them, client_secret_basic and client_secret_post, are implemented in Red Hat build of Keycloak by Client Id and Secret client authenticator. Until now, when the OIDC client registration request was sent with the attribute token_endpoint_auth_method set to client_secret_basic or client_secret_post, Red Hat build of Keycloak allowed the client to authenticate with both client_secret_basic and client_secret_post methods and did not preserve the single method specified in the OIDC client registration request. Now the specified method is respected, so for example when the OIDC client registration is sent with token_endpoint_auth_method set to client_secret_post, then it is required to authenticate the client with the client secret sent as a parameter in the POST request body.

It is still possible to make the OIDC client allow both methods, and clients migrated from previous versions are set by default to allow authentication with both methods.

Zero-downtime patch releases are now enabled by default. This feature, previously in preview as rolling-updates:v2, allows you to perform rolling updates when upgrading to a newer patch version within the same major.minor release stream without service downtime.

The rolling-updates:v2 feature flag is no longer required.

When using the Red Hat build of Keycloak Operator, set the update strategy to Auto to benefit from this functionality.

For more details, see Avoiding downtime with rolling updates.

2.10.31. Infinispan 16 upgrade

Red Hat build of Keycloak now uses Infinispan 16.0 for embedded distributed caching. This upgrade brings improved performance, enhanced security, and better support for zero-downtime upgrades in patch releases.

If you are using an external Data Grid server, for example in a multi-cluster setup, you should upgrade to version 16.0 as this is the version Red Hat build of Keycloak was tested with.

When upgrading the external Data Grid, the following changes are necessary:

  1. Enable the legacy metrics to ensure that alerts and dashboard still receive the same metrics as before. See External Data Grid metrics and where to add legacy: true to the ConfigMap.
  2. Define indexing.startupMode=NONE in your Cache configurations. See Deploying Data Grid for examples.

Previous versions of Red Hat build of Keycloak tested the issued-at timestamp with a clock-skew of zero seconds by default if this value was provided in a token. By default, access tokens issued by Red Hat build of Keycloak used for the admin API or for the user info endpoint do not contain a not-before claim, but customized setups might have it. In a setup with such a claim configured and with clocks that were not fully synchronized, this could lead to rejecting tokens on a node that lagged behind, as it would consider the tokens not valid yet.

Starting with this version, Red Hat build of Keycloak will honor a clock skew of 10 seconds for the issued-at timestamp by default, which is aligned with best practices such as the FAPI 2.0 Security Profile.

This applies to all places where no explicit clock skew is configured, except for JWT Client Assertions that have a hardcoded clock skew of 15 seconds. It does not affect any explicitly configured clock skew, for example in identity providers, where an individual clock skew can be configured.

2.10.33. The base themes are now abstract

All the base themes are now tagged as abstract, and they are not listed in the Admin Console to be selected (Realm Settings Themes tab). They were always intended to be only extended but not used directly. If you use one of them, it will continue working (or not working) in the same way, but cannot be selected using the Admin Console anymore. Please select one of the available default themes or create your own one.

Red Hat build of Keycloak now automatically discovers and trusts cluster certificate authorities when running on Kubernetes or OpenShift, without relying on the Operator to preconfigure the truststore. Specifically, if present in the container filesystem, the following files are added to the system truststore at runtime:

  • /var/run/secrets/kubernetes.io/serviceaccount/ca.crt (Kubernetes service account CA)
  • /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt (OpenShift service CA)

This behavior is enabled by default and can be controlled with the server option:

  • --truststore-kubernetes-enabled=true|false (default: true)

No changes are required for most deployments. If you previously relied on the Operator to manage these truststore entries, the server now performs the same function directly.

Warning

when https-client-auth is set to required or request without an explicit https-trust-store-file, mTLS client certificate validation falls back to the system truststore. With truststore-kubernetes-enabled=true, this means certificates signed by the Kubernetes cluster CA will be accepted as valid client certificates. If this is not desired, either set https-trust-store-file explicitly or disable truststore-kubernetes-enabled.

For more details, see Cluster CA certificates (Kubernetes and OpenShift).

If you are deploying Red Hat build of Keycloak by using the Red Hat build of Keycloak Operator and your deployment relies on trusting the Kubernetes CA, upgrade custom Keycloak images first. This ensures that the Kubernetes CAs remain trusted for the entire duration of the upgrade.

If you cannot upgrade the custom image first or if you are able to simultaneously upgrade the operator with the custom images, consider explicitly configuring the truststore path in the Keycloak Custom Resource before changing the Operator version. This strategy ensures that Pods using older custom images continue to trust the cluster CA during the upgrade procedure:

apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
  name: keycloak
spec:
  automountServiceAccountToken: true
  additionalOptions:
    - name: truststore-paths
      value: "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt,/var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt"

A new REALM_ID column has been added to the OFFLINE_CLIENT_SESSION table. During the automatic schema migration, Red Hat build of Keycloak populates this column by copying the REALM_ID value from the corresponding row in the OFFLINE_USER_SESSION table, matching on USER_SESSION_ID and OFFLINE_FLAG.

This migration can take a significant amount of time depending on the number of rows in the table and the available system resources. From our tests with PostgreSQL, a table with 10 million rows takes approximately 1,320 seconds to update, processing approximately 7,500 rows per second.

We recommend increasing the transaction timeout to accommodate larger tables. See Migration timeout configuration for details on how to configure a longer timeout.

Alternatively, you can perform the migration manually. See Manual relational database migration for details on how to apply the database changes manually.

Warning

This migration requires downtime. Do not run Red Hat build of Keycloak 26.6 alongside older versions during or after this migration. Older versions do not populate the new REALM_ID column, which prevents Red Hat build of Keycloak 26.6 from finding the data. In the worst case, if the data is not found, Red Hat build of Keycloak may attempt to insert a row with the same primary key, causing constraint violations.

2.10.37. UserSessionProvider API changes

The internal UserSessionProvider interface received new methods for efficient streaming of user sessions, in both speed and memory. The streaming instances are read-only, meaning they will not change. The previous methods have been deprecated. Custom providers should implement these new methods to avoid performance penalties. They should avoid keeping the returned items in memory, for example by binding them to the current transaction, in case the invoker needs to analyze all data.

A similar change was done for the UserSessionPersisterProvider.

Authentication failures resulting in an invalid_grant now correctly return an HTTP 400 status code instead of 401 for the Resource Owner Password Credentials and UMA Permission grants. This change was done to properly follow the OAuth 2.0 Authorization Framework specification.

Standard Token Exchange now rejects all sender-constrained tokens (as defined in RFC 7800) used as the subject_token parameter. This includes both DPoP-bound tokens and X.509 certificate-bound tokens (mTLS).

This change ensures better security and alignment with the OAuth 2.0 Token Exchange specification. Sender-constrained tokens are bound to specific clients and should not be exchanged across different contexts.

If you attempt to exchange a sender-constrained token, the request will be rejected with an invalid_request error. For more details, see Token Exchange.

With the clusterless feature enabled and persistent-user-sessions disabled, a re-index is required due to schema changes. Red Hat build of Keycloak triggers the re-index on startup, but this may delay server startup depending on the number of sessions stored, and/or return incorrect results during the re-index process.

When running with the MS SQL server, Red Hat build of Keycloak needs to ensure consistent and predictable string parameter handling with the database. Starting with this release, and when using the MS SQL Server JDBC driver, Red Hat build of Keycloak sets the sendStringParametersAsUnicode property to false by default. This change prevents the driver from automatically sending string parameters as Unicode unless explicitly required, which can reduce overhead and avoid unexpected performance or query-plan issues in some environments.

You can override this behavior by setting your own value for the sendStringParametersAsUnicode property in the database connection URL or configuration, for example by adding ;sendStringParametersAsUnicode=true to the connection URL.

New CLI options are now available to configure TLS encryption for database connections in a vendor-independent way:

  • db-tls-mode: Sets the TLS mode for the database connection. Valid values are disabled (default) and verify-server. When set to disabled, Red Hat build of Keycloak does not configure TLS and the driver’s default behavior applies. When set to verify-server, encryption and server identity verification are enabled.
  • db-tls-trust-store-file: The path to the truststore file containing the database server certificate or Certificate Authority (CA) certificate.
  • db-tls-trust-store-password: The password to access the truststore file.
  • db-tls-trust-store-type: The type of the truststore file (for example, JKS or PKCS12).

These options replace the need to configure vendor-specific JDBC properties manually. Red Hat build of Keycloak automatically translates them to the appropriate driver-specific settings.

As an alternative to specifying a truststore file with db-tls-trust-store-file, you can use --truststore-paths to add the certificate to the Java truststore.

For more details, see Secure the database connection.

Also, two new CLI options are now available to control transaction timeout behavior:

  • transaction-default-timeout: Controls the transaction timeout for regular transactions. The default value is 5 minutes, which is the same value used by the current Red Hat build of Keycloak version.
  • transaction-setup-timeout: Controls the timeout for transactions used by database schema migration, import, and export commands. The default value is 30 minutes, as these operations may take a while to complete for large datasets.

The provider configuration spi-dblock—​jpa—​lock-wait-timeout option has been replaced with the CLI option transaction-setup-timeout.

The USER_ENTITY table now has a new column LAST_MODIFIED_TIMESTAMP, and the KEYCLOAK_GROUP table now has two new columns CREATED_TIMESTAMP and LAST_MODIFIED_TIMESTAMP. These columns track when users and groups were created and last modified.

For existing users and groups created before this upgrade, these columns will be NULL. Newly created or modified resources will have these timestamps populated automatically.

Red Hat build of Keycloak will log a warning if the database is not configured to use UTF-8 encoding. This check applies to all supported databases.

For details on configuring UTF-8 encoding for your database, see Configuring the database.

As part of this change, the database configuration documentation has been updated:

  • For MySQL and MariaDB, the documentation now recommends using utf8mb4 as the character set. The previously documented utf8mb3 (or utf8) character set has been removed from the documentation due to its limitations in storing certain Unicode characters.
  • Previously recommended JDBC driver settings for Oracle, MySQL, and MariaDB have been removed from the documentation, as current versions of these databases use appropriate default values.

A new CLI option --db-connect-timeout sets the JDBC driver connection timeout and login timeout. It defaults to 10s to improve failover behavior and startup resilience during network issues.

Red Hat build of Keycloak now supports a KCRAW_ prefix for environment variables as an alternative to the standard KC_ prefix. If you are already using the KCRAW_ prefix for another purpose, please migrate to a new key prefix.

For more details, see Preserving literal values with the KCRAW_ prefix.

Previously virtual threads were used when at least two CPU cores were available. Starting with this version, virtual threads are only used when at least four CPU cores are available. This change should prevent deadlocks due to pinned virtual threads.

2.10.48. Accepting URL paths without a semicolon

Previously Red Hat build of Keycloak accepted HTTP requests with paths containing a semicolon (;). When processing them, it handled them as of RFC 3986 as a separator for matrix parameters, which basically ignored those parts. As this has led to a hard-to-configure URL filtering, for example, in reverse proxies, this is now disabled, and Red Hat build of Keycloak responds with an HTTP 400 response code.

To analyze rejected requests in the server log, enable debug logging for org.keycloak.quarkus.runtime.services.RejectNonNormalizedPathFilter.

To revert to the previous behavior and to accept matrix parameters set the option http-accept-non-normalized-paths to true. With this configuration, enable and review the HTTP access log to identify problematic requests.

In version 26.4.0, the server-info endpoint changed to return only the system information for administrators in the admin realm. Nevertheless, the version property was detected to be needed by some products that interact with Red Hat build of Keycloak. Now that property is included for administrators in the realm with permission manage-realm.

The workaround of the view-system permission is more restricted too. It can only be assigned by administrators in the master realm. For more details, see Delegating realm administration using permissions. This permission will be deleted in a future version.

Since this release, the Red Hat build of Keycloak SAML implementation limits the data that can be inflated through the REDIRECT binding. The default maximum size is 128KB, the decompression stops when that value is exceeded and returns an error. The option spi-login-protocol—​saml—​max-inflating-size can be used to increase the default limit.

Increasing limit to 512KB

bin/kc.[sh|bat] --spi-login-protocol--saml--max-inflating-size=524288

The same restriction is applied for the Red Hat build of Keycloak SAML Galleon feature pack. Although, in this case, you need to add a system property to the Wildfly/EAP server to change the default maximum size: -Dorg.keycloak.adapters.saml.maxInflatingSize=524288.

Specific sensitive information is omitted from the HTTP Access log, such as the value of the Authorization HTTP header. Moreover, values of specific sensitive Red Hat build of Keycloak cookies, such as KEYCLOAK_SESSION, KEYCLOAK_IDENTITY, or AUTH_SESSION_ID, are also omitted.

When the OIDC token endpoint request (or OAuth2 token endpoint request) is sent, a new limit exists for the maximum length of every OIDC/OAuth2 parameter. The maximum length of each parameter is 4,000 characters, which is aligned with the same limit, which already exists for the parameters sent to OIDC/OAuth authentication request.

To adjust those numbers, start the server with the req-params-default-max-size option for the default maximum length of the OIDC/OAuth2 parameters. Alternatively, you can use something such as req-params-max-size for one specific parameter. For more details, see login protocol configuration topic.

The WebAuthn policy presents the option Acceptable AAGUIDs to restrict the authenticators that are allowed to register new credentials. The AAGUID (Authenticator Attestation Global Unique Identifier) is an identifier for the authenticator’s type (such as make and model). This option requires the Attestation conveyance preference to be configured too (normally Direct), in order to force the authenticator to include the attestation inside the registration data.

Since this release, when this option is set up, the attestation is required to be present and signed with a valid certificate for the Red Hat build of Keycloak trust-store. The None attestation format is explicitly not permitted. Previously, there were some corner cases in which a self attestation was accepted. The change is expected to be harmless, but maybe there are combinations of authenticators and WebAuthn policies that can present issues.

For more details, see Managing policy in the Server Administration Guide.

A new cluster event was introduced to synchronize workflow scheduled settings across cluster nodes. You might see errors when updating workflow definitions during a rolling update when upgrading from 26.6.x. Defer updating workflow definitions until the rolling update has completed.

Since this release, all Required Actions are now one-time actions by default to ensure they cannot be reused once completed. This change impacts the email action tokens created by the execute-actions-email endpoint, which is executed via the Credential reset button in the Admin Console. Any action token generated through this endpoint (with whatever reset actions) is now strictly one-time use, ensuring that once a user completes the required steps, the token is immediately invalidated.

Red Hat logoGithubRedditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat Documentation

Legal Notice

Theme

© 2026 Red Hat
Back to top