ForgeRock Identity Gateway

Incompatible changes

Incompatible changes refer to changes that impact existing functionality and might have an effect on your migration from a previous release. Before you upgrade, make appropriate changes to your scripts and plugins.

Version Description


IG .war file

The IG .war file is no longer created. It was deprecated in IG 6 and stopped being delivered in IG 2023.2. For information about migration, refer to Migrate from web container mode to standalone mode.

secretsProvider property changes from optional to required

Groovy scripts used in the IG configuration must now use the UTF-8 character set. In previous releases, Groovy files referenced from the IG configuration could rely on default encoding or system properties.

IG Java 17

IG no longer supports Java 11. You must upgrade to Java 17.


Upgrade to Vert.x 4.5 renames and removes Vert.x options used by WebSocket connections to AM and accessed through the vertx attribute of AmService.

Learn more about Vert.x changes in 4.5.0 Deprecations and breaking changes.

Use the Vert.x options described in VertxOptions.

Handling of failed HTTP responses

IG now fails an HTTP response promise when:

  • Streaming is disabled by the streamingEnabled property of admin.json. This is the default setting.

  • The response provides response headers but not the entire response body.

In previous releases, IG completed the response promise but the response was unreadable.

JWT must be signed or encrypted

The following filters must now be configured with a SecretsProvider and signature or encryption:

Improved security for CrossDomainSingleSignOnFilter

When verificationSecretId in CrossDomainSingleSignOnFilter is configured, IG uses it to verify the signature of AM session tokens. When verificationSecretId isn’t configured, IG discovers and uses the AM JWK set to verify the signature of AM session tokens.

From this release, if verificationSecretId isn’t configured and IG can’t use the AM JWK set, the CrossDomainSingleSignOnFilter fails to start.

In previous releases, the CrossDomainSingleSignOnFilter accepted unsigned tokens.

IG .zip file

To prevent confusion during upgrade, now unpacks to a directory containing the IG version number. For example, this release unpacks to /path/to/identity-gateway-2024.3.0.

In previous releases, unpacked to /path/to/identity-gateway.

Treatment of HTTP 500 errors

HTTP 500 errors are no longer computed in Handlers or Filters. Instead, they fail the response promise with the Runtime exception that caused the failure.

Inline objects can’t be referenced from the configuration

In previous releases, other objects in a configuration could refer to an inline object through its name property. Inline objects can no longer be referenced by other objects; only named heap objects can be referenced by other objects.


Safeguard against accidental exposure of private keys with JwkSetHandler

The new property exposePrivateSecrets is available in JwkSetHandler to safeguard against the accidental exposure of private keys in a JWK set.

The property is false by default to prevent exposure of private keys. To expose private keys, you must now explicitly set the property to true.




Improved security for scripts

To improve security, IG now runs scripts only from an absolute path, or from a path relative to the base script directory. Routes that refer to scripts otherwise, such as through a URL, fail to deploy.

For more information, refer to the file property of Scripts.




The IG .war file is no longer delivered. For information about migration, refer to Migrate from web container mode to standalone mode.


ScriptableResourceUriProvider accepts returned values only as a String

ScriptableResourceUriProvider accepts returned values only as a String. In previous releases, it accepted returned values as a String or Promise<String>. For more information, see ScriptableResourceUriProvider in PolicyEnforcementFilter.

AM 5.x.x EOL

AM 5.x.x has reached Product End of Life and is no longer supported. The default value of the AmService property version has changed to 6. For more information, refer to ForgeRock Product Support Lifecycle Policy | IG and Agents.

keyType for CapturedUserPasswordFilter is required

For better security, the keyType for CapturedUserPasswordFilter is now required, and the use of DES is deprecated.

JWT classes relocated to new packages

Classes related to JWT stateless sessions have moved from the package org.forgerock.openig.jwt to org.forgerock.openig.session.jwt.

Classes and functions used to validate a JWT, used with a JwtValidatorCustomizer in a JwtValidationFilter, have moved from the package to

The IG scripting engine has been updated to incorporate the changes automatically.

CDSSO requires session cookies with SameSite=None, Secure=True

To improve privacy, browsers have recently changed third-party cookie policies to require the following settings for session cookies: SameSite=None, Secure=True.

Depending on your deployment and route configuration, configure session cookies as follows:


Logback upgrade

IG has upgraded the version of Logback from 1.2.7 to 1.2.9. For more information, refer to the Logback News for Logback 1.2.8 and Logback 1.2.9.


Proxying WebSocket traffic in standalone mode

When IG is in standalone mode, proxying Websocket traffic can produce errors where requested subprotocols not supported. To prevent these error, you must now list the subprotocols that are proxied by IG in the vertx property of admin.json.


Name of TimerDecorator in Prometheus output

In the Prometheus output, information for the default TimerDecorator is always included as name="gateway.timer".

In previous releases, information is included in the Prometheus output as follows:

  • When a default TimerDecorator is not declared in config.json, information is included as name="timer".

  • When a default TimerDecorator is declared in config.json, information is included as name="gateway.timer".

For more information, see TimerDecorator.

Runtime expressions that consume streamed content written with a #

To prevent IG from blocking executing threads, write runtime expressions that consume streamed content with # instead of $. This ensures that IG does a deferred evaluation.

For IG in standalone mode, when the new streamingEnabled property in admin.json is true, expressions that consume streamed content must be written with # instead of $.

For more information, see runtime expression.

New methods for asynchronous execution of scripts
This change is required if the new streaming property in admin.json is true. Otherwise, the change is recommended but not required.

APIs that read the entity content have been updated to execute scripts asynchronously.

Username of an AM identity is now subname

Before AM 7.1, the sub claim of OAuth 2.0 access_tokens and id_tokens contained only the username. From AM 7.1, the username is contained in the subname claim. The sub claim includes additional information.

Update scripts and expressions in IG that use the sub claim.

Secrets from secret stores expire by default

Secrets from FileSystemSecretStore, HsmSecretStore, KeyStoreSecretStore, and SystemAndEnvSecretStore, now expire after a default of five minutes, or after the time specified in the property leaseExpiry. In the previous release, secrets from these secret stores never expired or had other expiry times.

Entity.toString() function does not return content

The Entity.toString() function no longer returns the entity content as a string. Instead, it returns only metadata. This change prevents buffering of the entity content during logging, which, when the entity is big, can impede asynchronous operation.

To return the entity content as a string, replace request.entity.toString() and response.entity.toString() functions with request.entity.string and response.entity.string.

Capture and logging of entity

To faciltate asynchronous processing in this release, when the CaptureDecorator property captureEntity is false, the decorator does not capture the message entity, and writes nothing to the logs.

In previous releases, when captureEntity was false, the decorator wrote [entity] in the log to show that there was an entity but that capture was not configured.

RSA keys must be at least 2048 bits

For security, RFC 7518 - Digital Signature with RSASSA-PKCS1-v1_5 requires that RSA keys must be 2048 bits or larger. Smaller keys are now rejected.

Validation of goto parameter in OAuth2ClientFilter

To prevent redirects to malicious web sites, IG now validates the goto query parameter in requests to OAuth2ClientFilter /login and /logout endpoints.

The goto URL must use the same scheme, host, and port as the original URI, or be a relative URI (just the path). Otherwise, the request fails with an error.

To redirect a request to a site that does not meet the goto URL criteria, change the original URI by using a ForwardedRequestFilter.

For more information, see OAuth2ClientFilter and ForwardedRequestFilter.


Content-Type is a required header when entity used in StaticResponseHandler

When entity is used in the StaticResponseHandler, Content-Type is a required header. In previous releases, Content-Type was optional.

Java 11 required

IG 7.0 requires Java 11. Java 8 is not supported.

Connections to DS secure by default

ForgeRock Directory Services (DS) is now secure by default. Connections between IG and DS must therefore be configured for TLS.

Groovy 3.0

IG now supports Groovy 3.0. Some Groovy feature may have been deprecated/removed. Refer to the Release notes for Groovy 3.0.

JwtSessionFactory not an alternative type for JwtSession

JwtSessionFactory is no longer an alternative type for JwtSession

Default value of skew allowance in JwtSession

The default skew allowance in JwtSession has been reduced from 2 minutes to zero. A property to configure the skew allowance has been added in JwtSession.

KeyStore and KeyStoreSecretStore default type based on keystore extension

Oracle recommends the use of PKCS12 keystores. From Java 9, Oracle has provided more support for PKCS12. From Java 11, Oracle has changed the default keystore to PKCS12.

Following this lead, the default type for KeyStore and KeyStoreSecretStore is now based on the keystore extension. If the keystore extension is not recognized, the default type is PKCS12. In previous releases, the default type was the one used by the platform.

To ensure backward-compatibility, where keys are generated using a non-PKCS12 type (for example, JKS), specify type in KeyStore or storeType in KeyStoreSecretStore.

OAuth2ResourceServerFilter doesn’t check access_token expiry

In previous releases, after an access_token resolver validated an access_token, the OAuth2ResourceServerFilter checked that the access_token was not expired. From this release, the OAuth2ResourceServerFilter considers any token returned by an AccessTokenResolver as valid, and checks only that the required scopes are present.

gracefulStop In ScheduledExecutorService

When the ScheduledExecutorService property gracefulStop is true, the service now removes submitted jobs and attempts to end running jobs after respecting the gracePeriod. In previous releases, it did not remove or end jobs.

Allow listing of audit event fields in logs

To prevent logging of sensitive data for an event, the Common Audit Framework now uses an allow-list to specify which event fields appear in logs. Compared to previous releases, different event fields are included by default in the logs.

The AuditService includeIf property has been implemented to include deny-listed event fields in the logs.

Identification of OAuth2ClientFilter registrations

In OAuth2ClientFilter, registrations are now identified by the ClientRegistration property clientId instead of name. In this release, IG automatically rewrites OAuth2Session tokens that use name to use clientId. Registration by name is deprecated.

When a user initiates a login with the OAuth2ClientFilter, the login endpoint uses the ClientRegistration property clientId:


In previous releases, the login endpoint used the ClientRegistration property name:


Similarly, the login endpoint in Nascar pages uses client_id instead of name.


Validation of goto parameter in OAuth2ClientFilter (present in 7.0.2, but not 7.0.1 or 7)

To prevent redirects to malicious websites, IG now validates the goto query parameter in requests to OAuth2ClientFilter /login and /logout endpoints.

The goto URL must use the same scheme, host, and port as the original URI, or be a relative URI (just the path). Otherwise, the request fails with an error.


SAML 2.0 deployments require additional configuration

When IG uses AM federation libraries generated from AM 6.5.2 or earlier, add the following lines to the file:

# Specifies implementation for
# org.forgerock.openam.federation.plugin.rooturl.RootUrlProvider interface.
# This property defines the default base url provider.


Improved security for authentication cookies in CrossDomainSingleSignOnFilter and JwtSession

By default, the JwtCookieSession cookie and CrossDomainSingleSignOnFilter authentication cookie and are now flagged as HttpOnly.

CrossDomainSingleSignOnFilter has additional properties to set or unset cookie flags for HttpOnly and secure.

Agent credentials mandatory in AmService

The agent property of AmService is now mandatory. The agent defines the credentials of an AM Java agent that acts on behalf of IG to authenticate with AM, request policy decisions from AM, and communicate WebSocket notifications from AM to IG.

This is a breaking change for all filters that use AmService, and for the following filters where agent replaces properties that are removed in this release:

  • SingleSignOnFilter, where agent replaces previously deprecated properties.

  • PolicyEnforcementFilter, where agent replaces previously deprecated properties and the following properties: pepUsername and pepPassword.

  • TokenTransformationFilter, where agent replaces previously deprecated properties and the following properties: username and password.

Agent session logged out when AmService stopped

When a route containing an AmService is reloaded, or when an AmService is stopped, the agent session is logged out.

Disconnection strategy for session cache and PolicyEnforcementFilter cache

When the WebSocket notification service is disconnected, by default the session cache and policy enforcement cache is cleared. In previous releases, the caches were not cleared.

DS API change for secure LDAP connection

DS 6.5 has updated its client API for establishing SSL connections. The SslContextBuilder class has been removed and related usages have been integrated into SslOptions.

This has an impact on existing scripts that are using IG’s LdapClient for connecting to a secure LDAP server.

Previously working script:

SslContextBuilder builder = new SslContextBuilder();
SslOptions sslOptions = SslOptions.newSslOptions(

New API:

SslOptions sslOptions = SslOptions.newSslOptions(null, TrustManagers.trustAll())


New Features in Freeform Studio

New features have been added to the technology preview of Freeform Studio. Routes created in Freeform Studio in IG 6.0 are automatically transitioned into JSON editor routes.


Production mode by default

By default, after installation IG is now in production (immutable) mode instead of development (mutable) mode. To use Studio and manage routes through Common REST, you must switch to development mode.

Introduction of ReverseProxyHandler

The chain in routes created in Studio now ends with a ReverseProxyHandler instead of a ClientHandler.

PolicyEnforcementFilter credentials must be registered as Java Agent

It is now mandatory to register an AM Java agent in order to use the PolicyEnforcementFilter.

The tokens issued by AM for an agent have an unlimited lifetime (unless configured otherwise), and all appropriate permissions, making them a perfect fit for an application needing to ask for policy decisions.

ClientHandler verifies the hostname for outgoing SSL connections

By default, the ClientHandler now verifies the hostname for outgoing SSL connections. By default, in previous releases the hostname was not verified.

For more information, refer to the hostnameVerifier property in ClientHandler.

Route filename, name, and ID

The filename of a route cannot be default.json, and the route’s name property and route ID cannot be default.

Servlet 2.x support removed

This release supports servlet 3.x. Servlet 2.x is no longer supported.

Captured entity size is limited

By default, when the CaptureDecorator property captureEntity is true, up to 512 KB of an entity can be captured. Before this release, IG tried to capture the entire entity.

The CaptureDecorator property maxEntityLength has been added to limit the maximum size of captured entities, and so prevent excessive memory use or OutOfMemoryError.

ApiProtectionFilter protects /openig/api

The default ApiProtectionFilter now protects the /openig/api endpoint. Before this release, it protected the /openig endpoint.

Plus (+) not allowed in names

The plus character (+) is now a reserved character in names. It is no longer allowed in object namrs and route names.

Timestamp in route log files complies with ISO 8601

The timestamp in route logs now includes the date, and is compliant with ISO 8601. The following examples show the impact of this change on log parsing:

  • An entry in the route log was previously in this format:

    10:57:12:158 | INFO | . . .

  • The entry now appears in this format:

    2018-01-16T10:57:12,242Z | INFO | . . .


Support for Java 7

Support for Java 7 has been removed. Before you update to IG 5.5, install the latest version of Java 8.

If you are using IG on Tomcat with SSL enabled, use OpenJDK 1.8.0_121 or later versions to prevent mismatch between client side ciphers and server side ciphers.

Default cookie name is IG_SESSIONID

Most web containers use JSESSIONID as the default cookie name. To prevent invalid session IDs when a protected application uses the same cookie name as the IG web container, IG now uses IG_SESSIONID as its default cookie name.

Configuration of Jetty for HTTPS

The way to configure HTTPS for Jetty has changed in Jetty 9.4. For general information about Jetty and HTTPS, see the Jetty documentation.

Support for "scope" in dynamic client registration

As required by RFC 7591, OAuth 2.0 Dynamic Client Registration Protocol, the metadata property of OAuth2ClientFilter supports scope.

Dynamic client registration with versions of AM earlier than 5.5 must use the scopes property. Dynamic client registration with AM 5.5 can use the scopes or scope property.

For the option to dynamically register with a wider range of identity providers, you can use both scope and scopes at the same time.

Copyright © 2010-2024 ForgeRock, all rights reserved.