// ------------------------ Breaking changes ------------------------  //
== Breaking changes

=== Method `UserProfile#toRepresentation(boolean)` added

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.

Breaking changes are identified as those that might require changes for existing users to their configurations or applications.
In minor or patch releases, {project_name} will only introduce breaking changes to fix bugs.

=== Corrected encoding when sending OpenID Connect client secrets when acting as a broker

In a scenario where {project_name} acts as a broker and connects via OpenID Connect to another identity provider, it now sends the client credentials via basic authentication in the correct encoding as specified in RFC 6749.
You are not affected if you configured {project_name} to send the credentials in the request body.

This prevents problems with client IDs or passwords that contain, for example, a colon or a percentage sign.

To revert to the old behavior, change the client authentication to the deprecated option *Client secret sent as HTTP Basic authentication without URL encoding* (`client_secret_basic_unencoded`).

=== Identity Provider refactoring

The private SPI for identity providers have 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.

=== Accepting only normalized paths in requests

Previously {project_name} accepted HTTP requests with paths containing double dots (`..`) or double slashes (`//`). When processing them, it normalized the path by collapsing double slashes and normalized the path according to RFC 3986.
As this has led to a hard-to-configure URL filtering, for example, in reverse proxies, the normalization is now disabled, and {project_name} 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 previoius behavior and to accept non-normalized URLs, set the option `http-accept-non-normalized-paths` to `true`. With this configuration, enable and review the HTTP access log to identify problematic requests.

// ------------------------ Notable changes ------------------------ //
== Notable changes

Notable changes may include internal behavior changes that prevent common misconfigurations, bugs that are fixed, or changes to simplify running {project_name}.

=== SPIFFE Identity Provider configuration changed

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.

=== `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 {project_name} 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.

=== `log-console-color` will automatically enable if supported by the terminal

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`.

=== Some message keys no longer support HTML entities

The following message keys in translations no longer support HTML entities: `backToLogin`, `backToApplication`, `proceedWithAction`.

The default themes have already been updated. If you used them in your translations, please update your translation to use the UTF-8 equivalent.

=== User sessions created with "Remember Me" are no longer valid if "Remember Me" is disabled for the realm

When the "Remember Me" option is disabled in the realm settings, all user sessions previously created with the "Remember Me" flag are now considered invalid.
Users will be required to log in again, and any associated refresh tokens will no longer be usable.
User sessions created without selecting "Remember Me" are not affected.

=== Correct encoding for OpenID Connect client credentials when acting as a broker

In a scenario where {project_name} acts as a broker and connects via OpenID Connect to another identity provider, it now sends the client credentials via basic authentication in the correct encoding as specified in RFC 6749.

This prevents problems with client IDs or passwords that contain, for example, a colon or a percentage sign.

To revert to the old behavior, change the client authentication to *Client secret sent as HTTP Basic authentication without URL encoding (deprecated)* (`client_secret_basic_unencoded`).

=== Permissions of the database user for PostgreSQL

If you are running on PostgreSQL as a database for {project_name}, 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 {project_name} to determine an estimated number of rows in a table.
If {project_name} 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.

=== Not recommended to use org.keycloak.credential.UserCredentialManager directly in your extensions

If you have user storage extension and you reference the class `org.keycloak.credential.UserCredentialManager` from your providers, it is recommended to avoid using this class directly as it might be
moved to the private modules in the future releases. The class may be typically used in the method `credentialManager()` of the implementations of `UserModel` interface. In that case,
it is recommended to replace the code like this:
```
@Override
public SubjectCredentialManager credentialManager() {
    return new UserCredentialManager(keycloakSession, realmModel, this);
}
```
with the code similar to this:
```
@Override
public org.keycloak.models.UserCredentialManager credentialManager() {
    return keycloakSession.users().getUserCredentialManager(this);
}
```

=== Allowing realm administrators granted with the `realm-admin` role to assign admin roles

In previous versions, realm administrators granted with the `realm-admin` role were not able to grant admin roles for delegated realm administrators.
This was only possible by granting the `admin` role to a master realm user, making this user a server admin.

In this release, realm administrators with the `realm-admin` role can assign admin roles to users in their realm, allowing them to delegate administrative tasks without needing server admin privileges.

If you are using FGAP to delegate administration to users in a realm other than the master realm,
make sure the users granted with the `realm-admin` role are expected to have this role to avoid privilege scalation.

The documentation is also updated with additional information about the different types of realm administrators.
For more information, see link:{adminguide_link}#_fine_grained_permissions[Delegating realm administration using permissions].

=== OCSP request timeouts follow HTTP client configuration

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.

=== Added database indexes on `OFFLINE_CLIENT_SESSION` table

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

If those tables contain more than 300000 entries, {project_name} 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 {project_name}'s startup.
See the link:{upgradingguide_link}[{upgradingguide_name}] for details on how to configure a different limit.

=== Default authorization policies and resources are no longer auto-created

When enabling authorization on a new client (creating a Resource Server), Keycloak no longer automatically creates a "Default Resource", a "Default Policy," and a "Default Permission."

// ------------------------ Deprecated features ------------------------ //
== Deprecated features

The following sections provide details on deprecated features.

=== Sending OpenID Connect client secret via basic authentication without URL encoding

In a scenario where {project_name} acts as a broker and connects via OpenID Connect to another identity provider, you can choose to send the client secret as *Client secret sent as HTTP Basic authentication without URL encoding* (`client_secret_basic_unencoded`). While this violates RFC 6749, it can be used to keep the default behavior of earlier versions of {project_name}.

This behavior is deprecated and will be removed in a future version of Keycloak.

=== `AuthenticationManager.AuthResult` is now a record

The inner class `AuthenticationManager.AuthResult` in the `keycloak-services` module is now a record.
The getter methods like `getSession()` have been deprecated in favor of the `session()` accessors.

=== Accepting HTTP requests with non-normalized paths

The option `http-accept-non-normalized-paths` was introduced to restore the previous behavior where {project_name} accepted non-normalized URLs.

As this behavior can be problematic for URL filtering, it is deprecated and will be removed in a future release.

// ------------------------ Removed features ------------------------ //
== Removed features

The following features have been removed from this release.

=== <TODO>

