// Release notes should contain only headline-worthy new features,
// assuming that people who migrate will read the upgrading guide anyway.

This release features new capabilities for users and administrators of {project_name}. The highlights of this release are:

* *JWT Authorization Grant*, enabling external-to-internal token exchange using externally signed JWT assertions.
* *Federated client authentication*, eliminating the need to manage individual client secrets in {project_name}.
* *Workflows*, enabling administrators to automate realm administrative tasks such as user and client lifecycle management.
* *Zero-downtime patch releases*, allowing rolling updates within a minor release stream without service downtime.
* The *Keycloak Test Framework*, replacing the previous Arquillian-based solution.

All of these features are now fully supported and no longer in preview.
Read on to learn more about each new feature.
If you are upgrading from a previous release, https://www.keycloak.org/docs/latest/upgrading/index.html[also review the changes listed in the upgrading guide].

= Security and Standards

== JWT Authorization Grant (supported)

JWT Authorization Grant (https://datatracker.ietf.org/doc/html/rfc7523[RFC 7523]) is designed to implement external-to-internal token exchange use cases. This grant allows using externally signed JWT assertions to request OAuth 2.0 access tokens.

In this release, JWT Authorization Grant is promoted from preview to supported. See the link:{securing_apps_base_link}/jwt-authorization-grant[JWT Authorization Grant guide] for additional details.

== Federated client authentication (supported)

Federated client authentication allows clients to leverage existing credentials once a trust relationship with another issuer exists. It eliminates the need to assign and manage individual secrets for each client in {project_name}.

Federated client authentication is now promoted to supported, including support for client assertions issued by external OpenID Connect identity providers and Kubernetes Service Accounts.

Since the OAuth SPIFFE Client Authentication specification is still in draft status, this feature remains a preview feature in {project_name}.

== New guide about Demonstrating Proof-of-Possession (DPoP)

A new guide for OAuth 2.0 Demonstrating Proof-of-Possession (DPoP) in the {securing_apps_name} provides information on how to mitigate the risk of stolen tokens by making tokens sender-constrained.

See https://www.keycloak.org/nightly/securing-apps/dpop[Securing applications with DPoP] for more details.

== Identity Brokering APIs V2 (preview)

A new preview version 2 for the Identity Brokering APIs is introduced in this release. When brokering is used during the authentication process, {project_name} allows you to store tokens and responses issued by the external Identity Provider. Applications can call a specific endpoint to retrieve those tokens, which, in turn, can be used to get extra user information or invoke endpoints in the external trust domain. The new version improves the token retrieval endpoint to substitute the internal to external Token Exchange (use case for the link:{securing_apps_token_exchange_link}#_legacy-token-exchange[legacy Token Exchange V1]).

For more information, see the chapter link:{developerguide_link}#_identity-brokering-apis[Identity Brokering APIs] in the {developerguide_name}.

== Step-up authentication for SAML (preview)

The feature `step-up-authentication-saml` extends the step-up authentication to include the SAML protocol and clients. This feature is in preview mode. Additional information is available in the link:{adminguide_link}#_step-up-authentication-saml[{adminguide_name}].


== OAuth Client ID Metadata Document (experimental)

https://www.ietf.org/archive/id/draft-ietf-oauth-client-id-metadata-document-01.html[OAuth Client ID Metadata Document (CIMD)] is an emerging standard that defines a JSON document format for describing OAuth 2.0 client metadata. Since version 2025-11-25, the Model Context Protocol (MCP) requires an authorization server to comply with CIMD. {project_name} now includes experimental support for CIMD, allowing it to serve as an authorization server for MCP version 2025-11-25 or later.

See link:{securing_apps_base_link}/mcp-authz-server[Integrating with Model Context Protocol (MCP)] for the updated guide including CIMD.

ifeval::[{project_community}==true]
Many thanks to https://github.com/tnorimat[Takashi Norimatsu] for the contribution.
endif::[]

= Administration

== Workflows (supported)

Workflows allow administrators to automate and orchestrate realm administrative tasks, bringing key capabilities of Identity Governance and Administration (IGA) to {project_name}. By defining workflows in YAML format, you can automate the lifecycle of realm resources such as users and clients based on events, conditions, and schedules.

In this release, Workflows is promoted from preview to supported. This release also includes new built-in steps, a troubleshooting guide, and various improvements to the workflow engine.

For more details, see the link:{adminguide_link}#_managing_workflows[Managing workflows] chapter in the {adminguide_name}.

== Organization groups

Organizations now support isolated group hierarchies, allowing each organization to manage its own teams and departments without naming conflicts across the realm. This update includes Identity Provider mappers to automatically assign federated users to organization groups based on external claims. Group membership is automatically included in OIDC tokens and SAML assertions when an organization context is requested.

For more details, see the link:{adminguide_link}#pass:a[_managing_groups_][Managing organization groups] guide.

== New Groups scope for user membership changes

Fine-Grained Admin Permissions (FGAP) now includes a new `Groups` scope: `manage-membership-of-members`.

This scope is now used as the group-side bridge for evaluating user-side `manage-group-membership` permissions based on a user's current group memberships.
The existing `manage-membership` scope keeps its current behavior for target group membership management operations.

== Looking up client secrets via the Vault SPI

Secrets for clients can now be managed and looked up by the Vault SPI.

Thank you to https://github.com/tsaarni[Tero Saarni] for contributing this change.

== Forcing password change for LDAP users

There is now initial support for LDAP password policy control.
The support is limited to prompting users to update their password when the LDAP server indicates that the password must be changed.
Previously, {project_name} let the user in and ignored the mandatory password reset.
There is a new optional setting "`Enable LDAP password policy`" in the LDAP advanced settings to enable this.

Thank you to https://github.com/tsaarni[Tero Saarni] for contributing this change.

= Configuring and Running

== Java 25 support

{project_name} now supports running with OpenJDK 25.
The server container image continues to use OpenJDK 21 for now to support FIPS mode. For details, see the
note in the FIPS guide.

== Zero-downtime patch releases (supported)

Zero-downtime patch releases allow you to perform rolling updates when upgrading to a newer patch version within the same `major.minor` release stream without service downtime.

In this release, zero-downtime patch releases are promoted to supported and enabled by default.
When using the {project_name} Operator, set the update strategy to `Auto` to benefit from this functionality.

For more details on the Operator configuration, see the https://www.keycloak.org/operator/rolling-updates[Avoiding downtime with rolling updates] guide.

== Installation instructions for CloudNativePG

For those running {project_name} on Kubernetes, there is now a guide on how to deploy a PostgreSQL database on Kubernetes by leveraging the CloudNativePG Operator and how to connect {project_name} to the database.

See https://www.keycloak.org/nightly/high-availability/single-cluster/deploy-cnpg[Deploying CloudNativePG in multiple availability zones] in the {highavailabilityguide_name} for details.

== Simplified database operations

Several new command line options simplify the database operations for {project_name} and remove the need to use raw JDBC connection options:

* Configure TLS for the database connection.
* Database connection timeouts.
* Transaction timeouts with production-ready defaults.

It also verifies the correct UTF-8 character encoding of the database at startup and prints a warning if this is not the case.

When running on orchestrators like Kubernetes, the startup and liveness probes return UP during database migrations, simplifying upgrades by removing the need to adjust the probes during upgrades.

See the migration guide for additional details on each aspect.

== Graceful shutdown of HTTP stack

To allow rolling updates for configuration changes or version updates, a graceful shutdown of {project_name} nodes prevents users from seeing error responses when logging in or refreshing their tokens when nodes shut down.

Starting with this version, {project_name} supports a graceful shutdown of the HTTP stack.
This includes delaying a shutdown after receiving a termination signal, connection draining for HTTP/1.1 and HTTP/2 connections during that period, and a shutdown timeout to finish ongoing requests.

The defaults are a shutdown delay and a shutdown timeout of one second each.
This should be a good fit for setups where the reverse proxy is using TLS edge termination or re-encryption and the reverse proxy is notified about the {project_name} node shutting down at the same time as the {project_name} node.
This is a common setup, for example, in Kubernetes environments.

Users should adjust those values depending on their proxy setup.
See the section https://www.keycloak.org/server/reverseproxy#graceful-http-shutdown[Graceful HTTP shutdown] in the reverse proxy guide for more information.

== New `KCRAW_` prefix for environment variables to preserve literal values

{project_name} now supports a `KCRAW_` prefix for environment variables to preserve values containing `$` characters exactly as written, without expression evaluation.

When using the standard `KC_` prefix, {project_name} (via SmallRye Config) evaluates expressions in values (for example, `${some_key}` is resolved and `$$` is collapsed to `$`).
This can silently modify passwords or secrets injected by a secrets manager or orchestration tool where manual escaping is not feasible.

Setting `KCRAW_<KEY>` instead of `KC_<KEY>` preserves the value exactly as provided.

See the link:{server_guide_base_link}/configuration#kcraw-prefix[Preserving literal values with the KCRAW_ prefix] section in the Server Configuration guide for details.

== Automatic reload of lists with disallowed passwords

When a list of disallowed passwords (also known as blacklist) changes, it is automatically reloaded. This avoids the need for a server restart when the list changes.

Thank you to https://github.com/tsaarni[Tero Saarni] for contributing this change.

== Automatic truststore initialization on Kubernetes and OpenShift

{project_name} now automatically discovers and trusts cluster certificate authorities when running on Kubernetes or OpenShift, without requiring the Operator to preconfigure the truststore.

If present in the container filesystem, the following certificates are added to the system truststore at startup:

* `/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`).

Most deployments do not require any action. If you relied on the Operator to manage these truststore entries previously, the server now performs the same function directly.

== Client certificate lookup providers for Traefik and Envoy

You can now use new client certificate lookup providers for Traefik and Envoy proxies.
For details, see the link:{server_guide_base_link}/reverseproxy#_enabling_client_certificate_lookup[Enabling Client Certificate Lookup] section of the documentation.

== Configurable Kubernetes Service name and port in the Keycloak Operator

The {project_name} Operator now supports overriding the name and port of the Kubernetes Service it creates for a {project_name} deployment.

Previously, the Service name was always derived as `<cr-name>-service` and the Service port always matched the container port.
You can now use the `spec.http.serviceName`, `spec.http.serviceHttpsPort`, and `spec.http.serviceHttpPort` fields to
configure these independently.

For more details, see the https://www.keycloak.org/operator/advanced-configuration[Advanced configuration] guide.

== Sensitive information is not displayed in the HTTP Access log

If you are using the HTTP Access logging capability, sensitive information is omitted.
This means that tokens in the 'Authorization' HTTP header and specific sensitive cookies are not shown.

For more information, see https://www.keycloak.org/server/logging#http-access-logging[Configuring HTTP access logging].

== Configurable log file rotation

It is now possible to configure log file rotation when using {project_name}'s built-in file logging handler.
This includes a simple option to fully disable log rotation, which is useful when using an external log rotation solution such as `logrotate`.

To disable log file rotation:

[source,bash]
----
bin/kc.sh start --log="console,file" --log-file-rotation-enabled=false
----

For more information, see the https://www.keycloak.org/server/logging/file[File logging] guide.

== HTTP access logs in a dedicated file

HTTP access logs can now be written to a dedicated file, separate from the server logs.
This makes it easier to process and archive access logs independently for security auditing and compliance monitoring.

For more information, see https://www.keycloak.org/server/logging#http-access-logging[Configuring HTTP access logging].

== Customizable service fields in JSON log output

{project_name} now provides native options to customize the `service.name` and `service.environment` fields in JSON log output across all log handlers (console, file, and syslog).

Previously, when using the ECS format, `service.name` and `service.environment` could not be overridden through {project_name} configuration.
This made it difficult to align JSON log fields with OpenTelemetry resource attributes.

You can now set these fields using `log-service-name` and `log-service-environment`.

For more information, see the https://www.keycloak.org/server/logging#customize-service-fields[Configuring logging] guide.

== New and updated translations

New translations for Indonesian and Armenian were added. A warm welcome to the new language maintainers for these languages!
There are also new language maintainers for the Swedish translation, who translated all remaining message keys. Thank you so much!

Follow the translation progress on the https://www.keycloak.org/translations[translation status page], help translate, and read the translation guide on how to add additional languages.

== Right-to-left language support in the Account UI

Support for right-to-left (RTL) languages was added to the Login UI, Admin UI, and email templates several releases ago. This release adds initial RTL support to the Account UI, which completes this effort.

= Observability

== Telemetry configuration via the Keycloak CR

{project_name} now supports configuring the OpenTelemetry properties via the Keycloak CR when using the Operator.
These properties are shared among the available OpenTelemetry components - logs, metrics, and traces.

For more details, see the link:{telemetryguide_link}[{telemetryguide_name}] guide.

== Custom request headers for OpenTelemetry

It is now possible to set request headers for exporting telemetry via OpenTelemetry Protocol (OTLP).
This is mainly useful for providing tokens in the request.

You can specify these headers via the `telemetry-header-<header>` wildcard option, which accepts any custom header name.
Alternatively, use `telemetry-logs-header-<header>` for OpenTelemetry Logs or `telemetry-metrics-header-<header>` for OpenTelemetry Metrics.

For more details, see the link:{telemetryguide_link}[{telemetryguide_name}] guide.

== Service Monitor annotations and labels via the Keycloak CR

It is now possible to configure service monitor labels and annotations via the Keycloak CR when using the Operator.

For more details, see the link:https://www.keycloak.org/operator/advanced-configuration#_servicemonitor[Advanced Configuration Operator] guide.

= Extension Development

== Keycloak Test Framework (supported)

The Keycloak Test Framework, based on JUnit 6, is now fully supported.

It replaces the previous solution built on top of Arquillian and JUnit 4.
Behind the scenes, the framework handles the lifecycle of Keycloak, the database, and any injected resources such as realms and clients.

Tests simply declare what they want, including specific configuration, and the framework takes care of the rest.

For more information, see https://github.com/keycloak/keycloak/tree/main/test-framework#readme[Keycloak Test Framework].
