Upgrading OpenAM Servers

This chapter covers upgrade from OpenAM core server 11.0.0 or later to the current version. For other OpenAM components, see "Upgrading OpenAM Components".

OpenAM server upgrade relies on the Upgrade Wizard to make the necessary changes to the configuration store. You must then restart OpenAM or the container in which it runs. Even a version number change requires that you run the Upgrade Wizard, so needing to run the Upgrade Wizard says nothing about the significance of the changes that have been made to OpenAM. You must run the Upgrade Wizard even for maintenance releases.

Make sure you try upgrading OpenAM in a test environment before applying the upgrade in your production environment.

Starting with this release, a failed write of an account-lockout counter or counter reset switches the affected identity to counters held in memory on that OpenAM server. Previously, a rejected counter write could prevent subsequent authentication failures from being counted at all. Other identities continue using the configured data store, and a read failure alone does not activate this fallback.

The switch remains in effect until that server restarts, even if the write failure was transient and the store later recovers. Counters are independent on each server and are lost on restart. A successful login resets the in-memory counter but does not restore persistence. Positive lockout durations are preserved; a configured duration of zero changes from physical account deactivation to a temporary lock of 30 minutes. Once that lock expires, another sequence of failed attempts can lock the account again.

Setting inetuserstatus to Active or clearing sunAMAuthInvalidAttemptsData in the directory does not clear an existing fallback lock. Allow the temporary lock to expire; restarting the affected server also discards its fallback counters. An existing physical account restriction in physical-locking mode remains effective and must still be cleared separately.

Special identities, including amadmin, follow the same policy without name-based exemptions. Their rejected counter writes previously prevented lockout. With the current default account-lockout settings, five failed passwords can now lock amadmin on the affected server for 30 minutes. Review administrator access and recovery procedures before upgrading.

Two related corrections also apply to writable stores and explicitly configured in-memory counters: a failure threshold of one now starts a timed lock on the first failure, and a duration multiplier of zero preserves the lock duration for later cycles instead of reducing it to zero.

Disabling account lockout, or setting its failure count or failure interval to zero, stops enforcing existing temporary locks consistently across authentication index types. This does not clear the counters or restore persistence: re-enabling lockout before a temporary lock expires enforces that lock again. Physical account restrictions remain subject to the existing account and profile checks.

Explicitly configured in-memory counters now invoke the account-lockout callback plugins for the login realm when the failure threshold is reached, without resolving the user from the identity store. Previously, this path sent the lockout notification but skipped the plugin callback because no identity had been resolved.

If you are upgrading from an unsupported version of OpenAM to a later version, you must first upgrade to a supported version. In some cases, you may need to upgrade again depending on the upgrade path.

Starting with this release the legacy Liberty ID-WSF SOAP endpoints (/Liberty/ and /WSPRedirectHandler/) are disabled by default as part of the GHSA-p462-xxwx-pqf4 hardening. Existing deployments that rely on Liberty ID-WSF, IDPP, Discovery, AuthnSvc, or Interaction services must explicitly opt in by setting the advanced server property com.sun.identity.liberty.enabled=true.

Two related advanced server properties were also introduced and now default to a fail-close behaviour:

  • com.sun.identity.liberty.soap.sensitiveHandlers (default idpp,disco,authnsvc,interaction) — list of SOAP RequestHandler keys that reject the unauthenticated null:null mechanism and the ANONYMOUS security profile.

  • com.sun.identity.liberty.allowAnonymousWSC (default false) — restores the legacy minting of an anonymous Web Service Client session for null-family mechanisms without a client credential.

If your deployment depends on the previous (insecure) behaviour, review and adjust these properties before promoting the upgrade. See "Advanced" in the Reference.

Starting with this release the SAML 2.0 and ID-FF IDP discovery reader and writer endpoints (/saml2reader, /saml2writer, /idffreader, /idffwriter) validate the RelayState redirect URL as part of the GHSA-2pf8-52jh-5x3m hardening. Relative and same-origin redirect URLs continue to work unchanged. Absolute URLs that point to a different host are now rejected with HTTP 400 unless they match the new advanced server property org.openidentityplatform.openam.idpdiscovery.relaystate.whitelist (a semicolon-separated list of URL patterns, empty by default).

If your common-domain discovery deployment hosts service providers on a different host than OpenAM, add their return URLs to this property before promoting the upgrade. See "Advanced" in the Reference.

Starting with this release the legacy Liberty ID-FF (Liberty Alliance 1.x) SOAP endpoint (/SOAPReceiver/, served by FSSOAPReceiver) is *disabled by default as part of the GHSA-qcqm-7432-wg7r hardening. Existing deployments that actively use Liberty ID-FF federation must explicitly opt in by setting the advanced server property com.sun.identity.federation.services.soap.enabled=true. The kill-switch disables the whole endpoint, including ID-FF browser-artifact single sign-on and LECP, not only the state-changing operations. In a multi-server site set this property on every server: cross-node single logout forwards the logout SOAP message to a peer server’s own /SOAPReceiver, so a node where the endpoint is still disabled would reject the forwarded request with HTTP 404 and single logout would fail.

Also starting with this release, inbound ID-FF state-changing and disclosure operations (federation termination, name registration, single logout, and name-identifier mapping) require a verified XML signature by default (com.sun.identity.federation.services.requireSignature, default true), even when message signing is otherwise optional. This applies to the SOAP binding and to the HTTP-Redirect binding endpoints /ProcessTermination/, /ProcessLogout/, and /ProcessRegistration/*, which are reachable without authentication and act on the user named by an opaque handle in the request. Unlike the SOAP endpoint, the redirect binding is not disabled by default, so this change affects any deployment that uses ID-FF over the redirect binding.

Enable message signing along with it. OpenAM signs its own outbound ID-FF messages only when XMLSigningOn is enabled, and that setting is false on a stock installation. If you leave com.sun.identity.federation.services.requireSignature at its default without enabling signing, OpenAM’s own single logout, federation termination, and name registration messages are sent unsigned and rejected by the receiving provider. Before promoting the upgrade, either:

  • set XMLSigningOn to true under the sunFAMIDFFConfiguration service (advanced server property com.sun.identity.federation.services.signingOn) and configure a signing certificate alias on every participating hosted provider, with the matching certificate published in the metadata each partner consumes. This setting is now read for each operation, so changing it takes effect without restarting the server; in earlier releases it was cached at startup and a restart was required; or

  • set com.sun.identity.federation.services.requireSignature=false to restore the previous, insecure behaviour if your federation partners do not sign ID-FF messages.

See "Advanced" in the Reference.

Starting with this release the OAuth 2.0 authorization endpoint applies the OAuth2 Provider property Code Verifier Parameter Required to every request whose response_type includes code, as part of the GHSA-5p2f-7vcr-6vfh hardening. Previously the OpenID Connect hybrid flows (code token, code id_token, and code id_token token) escaped the check and were issued authorization codes with no code_challenge bound to them. That property is enabled by default, so hybrid-flow clients that send no code_challenge now fail at /oauth2/authorize.

The token endpoint fails closed to match: while the property is enabled, an authorization code that carries no code_challenge is rejected at /oauth2/access_token. Authorization codes issued before the upgrade, or before the property was turned on, therefore stop being redeemable. The exposure lasts at most one authorization code lifetime (the OAuth2 Provider property Authorization Code Lifetime (seconds), 120 by default), so if in-flight codes matter, leave client traffic redirected elsewhere for that long before promoting the upgrade.

Update hybrid-flow clients to send a code_challenge at the authorization endpoint and the matching code_verifier at the token endpoint, or disable Code Verifier Parameter Required for the realm. Disabling it never relaxes verification for codes that were issued with a challenge. See "OAuth2 Provider" in the Reference.

Starting with this release debugconfig.properties is validated more strictly. A file with org.forgerock.openam.debug.rotation=-1, or with a trailing space after a rotation value next to a suffix that is empty, too coarse or cannot be parsed, is now rejected as a whole: OpenAM prints "'/debugconfig.properties' isn’t valid, the default configuration will be used instead" to the standard error output and uses no prefix and no rotation. Leave a rotation value empty to turn that rotation off. Trailing spaces are also removed from the prefix and the suffix, so they no longer appear in debug log file names. See "Rotating Debug Logs" in the Administration Guide.

Starting with this release the OAuth 2.0 device flow verifies PKCE, as part of the GHSA-h93p-35jm-rj83 hardening. Previously a code_challenge sent to /oauth2/device/code was stored with the device code but never checked, so the device code could be redeemed without the code_verifier. Now every poll of /oauth2/access_token for such a device code must supply the matching code_verifier, and /oauth2/device/code rejects a code_challenge sent with a code_challenge_method other than S256 or plain.

Device-flow clients that send no code_challenge are not affected: the Code Verifier Parameter Required property does not apply to the device flow. Clients that do send a code_challenge but never sent the code_verifier must be updated to send it.

Starting with this release the signature on a SAML v1.x assertion or response is verified against the signing certificate configured for its issuer, as part of the GHSA-j56q-q3r3-hg7f hardening. Previously a certificate carried in the KeyInfo element was accepted as long as it was present anywhere in OpenAM’s keystore, so one trusted asserting party could sign messages on behalf of another.

A trusted asserting party therefore now needs its signing certificate alias configured. Signed assertions and responses from a partner whose alias is blank are rejected, and a certificate in the KeyInfo element must be the one of that alias. There is no property to restore the previous behaviour. Before promoting the upgrade, import each asserting party’s signing certificate into OpenAM’s keystore and enter its alias in the trusted partner configuration. See "To Configure a Trusted Asserting Party" in the Administration Guide.

Starting with this release a host name that is a DNS alias of a realm is accepted as a valid host name, as if it had its own com.sun.identity.server.fqdnMap[<alias>]=<alias> entry, unless the FQDN map maps it to another host name. The DNS aliases of the top-level realm hold the RDN value of the root suffix (for example openam) and the host name of every server and site that was created, so these host names are accepted as well.

OpenAM now removes the host name of a server or site from the DNS aliases of the top-level realm when the server or site is deleted, or when the primary URL of the site changes, unless the URL of another server or site has the same host name. If the host name cannot be removed at that moment, for example because the DNS aliases or the URLs of the other servers and sites cannot be read or updated, the server or site is still deleted or its URL still changed, OpenAM logs an error in the amSetupServlet debug log, and the host name stays. Servers and sites deleted before the upgrade, and site URLs changed before it, have left their host names behind. Before promoting the upgrade, review the DNS aliases of every realm and remove the host names that are no longer in use or no longer under your control. If you added a server or site host name to the DNS aliases of the top-level realm yourself, for example the host name of a load balancer, add it again after you delete the last server or site that has it.

Starting with this release OpenAM no longer ships the Restlet Servlet extension (org.restlet.ext.servlet). The web.xml file of earlier releases names org.restlet.ext.servlet.ServerServlet for the WebFinger servlet, which this release no longer has. If your customized .war file keeps its own copy of web.xml, change it as the WebFinger note below describes.

Custom code that calls org.restlet.ext.servlet.ServletUtils must call org.forgerock.openam.rest.jakarta.servlet.ServletUtils instead, which has the same getRequest and getResponse methods. Custom code that embeds Restlet in its own servlet through org.restlet.ext.servlet.ServletAdapter has no drop-in replacement, because OpenAM ships no counterpart of that class.

Starting with this release WebFinger (/.well-known/webfinger) answers OpenID Connect issuer discovery requests again; earlier 16.x releases answered every request with HTTP status 500. It no longer looks up the account named in the resource parameter: for any acct: or http(s) resource it returns the issuer of the deployment, the same for every account. Releases 15.x and earlier answered HTTP status 404 for an account that did not exist, which told an anonymous caller whether the account existed.

Starting with this release OpenAM serves the XACML policy endpoint (/xacml/) through the OpenAM servlet instead of the ForgeRockRest servlet. If your customized .war file keeps its own copy of web.xml, move the <servlet-mapping> whose <url-pattern> is /xacml/ from the ForgeRockRest servlet to the OpenAM servlet before you deploy. Otherwise every request to /xacml/* answers HTTP status 404.

The endpoint otherwise behaves as before, with these changes:

  • /xacml/realms/root/policies and /xacml/realms/root/realms/<realm>/policies address the top-level realm and its subrealms, as the same spellings do under /json. Earlier releases answered 404. /xacml/<realm>/policies and the realm query parameter work as before.

  • The Content-API-Version response header is protocol=1.0,resource=1.0. Earlier releases sent [Content-API-Version: protocol=1.0,resource=1.0].

  • An import request with an empty body answers 400. Earlier releases answered 500.

  • An import request body compressed with Content-Encoding: gzip is decoded as before. Content-Encoding: deflate is read as a raw DEFLATE stream, the form that earlier releases accepted as deflate-no-wrap, instead of the zlib format, so a body in the zlib format answers 400. deflate-no-wrap, zip and identity, which earlier releases also accepted, answer 400. Compress import requests with gzip.

  • A realm query parameter that names no realm answers 400 with a JSON body. Earlier releases answered 404.

  • A HEAD request to /xacml/policies is answered like a GET request, without a body. Earlier releases answered HTTP status 500.

  • Every 405 response carries an Allow header that lists the supported methods. The same applies to the other endpoints that OpenAM builds from annotated classes: /json/api now answers HEAD like GET and sends Allow: GET with its 405 responses, and /json/authenticate, which supports only POST, sends Allow: POST with its 405 responses.

  • Errors raised before a request reaches the XACML service, such as an unknown realm in the path, an unsupported method or an invalid Accept-API-Version value, no longer carry the XML error document. Their status codes are unchanged, except that an invalid Accept-API-Version value answers 400 instead of 500.

  • The <message> text of an XML error document can differ from earlier releases. For example, an import of a document that holds no policies answers No policies found in XACML document, where earlier releases answered No policies found in XACML document (400). The message of a failed import is looked up in the locale of the request’s Accept-Language header instead of the server locale. Rely on the <code> element rather than on the message text.

Custom code that refers to org.forgerock.openam.rest.service.XACMLServiceEndpointApplication, org.forgerock.openam.rest.service.XMLRestStatusService, org.forgerock.openam.rest.service.ResourceApiVersionRestlet or org.forgerock.openam.entitlement.rest.XacmlRouterProvider must be changed, because these classes no longer exist. org.forgerock.openam.xacml.v3.rest.XacmlService is no longer a Restlet resource. Custom code that injects the Restlet Router bound as @Named("XacmlRouter"), for example to add routes under /xacml, must be changed as well, because that binding no longer exists.

Starting with this release OpenAM serves WebFinger (/.well-known/) through the OpenAM servlet instead of a servlet of its own. If your customized .war file keeps its own copy of web.xml, delete the WebFinger servlet and its <servlet-mapping>, and map the <url-pattern> /.well-known/ to the OpenAM servlet before you deploy. Otherwise the container cannot load the WebFinger servlet, because its classes no longer exist.

The endpoint otherwise behaves as before, with these changes:

  • /.well-known/realms/root/webfinger, /.well-known/realms/root/realms/<realm>/webfinger and /.well-known/realms/<realm>/webfinger address the top-level realm and its subrealms, as the same spellings do under /json. Releases 15.x and earlier answered 404, unless a top-level realm is named realms: a path that starts with /.well-known/realms/ addressed that realm before and now always means one of these spellings, so address that realm as /.well-known/realms/root/realms/realms/webfinger or with the realm query parameter. /.well-known/<realm>/webfinger and the realm query parameter work as before.

  • An unknown realm in one of the realms/ spellings answers 404 with a code, reason and message JSON body. An unknown realm in the realm query parameter or in a /.well-known/<realm>/webfinger path answers 404 with an error and error_description body, as before.

  • The access audit events of WebFinger requests no longer carry the user ID and the session tracking ID of a session cookie that the request sends.

  • WebFinger requests no longer set the realm and realmObject servlet request attributes, so a custom Base URL Source extension or servlet filter that reads them finds no value there.

Custom code that refers to org.forgerock.openidconnect.restlet.WebFinger, org.forgerock.openidconnect.restlet.OpenIDConnectDiscovery or org.forgerock.oauth2.restlet.OAuth2StatusService must be changed, because these classes no longer exist.

To Upgrade From a Supported OpenAM Version

Follow these steps to upgrade a site of OpenAM servers.

During the upgrade process, you must take the OpenAM servers in the site out of production, instead redirecting client application traffic elsewhere. This is required because upgrade involves making changes to OpenAM’s configuration model. If the upgrade fails, you must be able to roll back before the configuration changes impact other sites.

Do not perform an upgrade by deploying the new version and then importing an existing configuration by running the ssoadm import-svc-config command. Importing an outdated configuration can result in a corrupted installation.

  1. Prepare your customized OpenAM server .war file.

  2. Back up your deployment.

  3. Route client application traffic to another site during the upgrade.

  4. For servers in the site, stop OpenAM, or if necessary stop the container where OpenAM runs.

  5. For servers in the site, deploy your customized server .war file.

    When you deploy the new .war file, you might have to delete working files left by the old installation. For example, if you deploy on Apache Tomcat, replacing /path/to/tomcat/webapps/openam.war, then also recursively delete the /path/to/tomcat/webapps/openam/ and /path/to/tomcat/work/Catalina/localhost/openam/ directories before restarting the server.

  6. For servers in the site, restart OpenAM or the container where it runs.

  7. To upgrade the data in the configuration store, perform one of the following actions in one of the servers in the site:

    • Navigate to the OpenAM URL, for example https://openam.example.com:443/openam, and follow the instructions in the Upgrade Wizard for an interactive upgrade.

    • Use the openam-upgrade-tool-16.1.4.jar tool for an unattended upgrade:

      1. Install the openam-upgrade-tool-16.1.4.jar tool as described in "To Set Up Configuration Tools" in the Installation Guide. A sampleupgrade file will be expanded in the directory where you install the tool.

      2. Create a configuration file for the openam-upgrade-tool-16.1.4.jar. You can use the sampleupgrade file as a template to create a configuration file, for example upgrade.properties.

        An upgrade configuration file may resemble the following:

        $ grep -v "^#" upgrade.properties
            SERVER_URL=http://openam.example.com:8080
             DEPLOYMENT_URI=/openam
             ACCEPT_LICENSES=true
      3. Upgrade OpenAM by using the tool with the properties file following this example:

        $ java -jar openam-upgrade-tool-16.1.4.jar --file upgrade.properties
        
        Writing Backup; Done.
        Upgrading Services
        New service iPlanetAMAuthPersistentCookieService; Done.
        New service iPlanetAMAuthOpenIdConnectService; Done.
        New service OAuth2Provider; Done.
        New service iPlanetAMAuthDevicePrintModuleService; Done.
        New service crestPolicyService; Done.
        New service RestSecurity; Done.
        New service MailServer; Done.
        New service dashboardService; Done.
        New service iPlanetAMAuthOATHService; Done.
        Add Organization schema to sunFAMSAML2Configuration; Done.
        Upgrade sunAMAuthHOTPService; Done.
        Upgrade sunAMAuthADService; Done.
        Upgrade sunAMAuthOAuthService; Done.
        Upgrade iPlanetAMAuthCertService; Done.
        Upgrade sunIdentityRepositoryService; Done.
        Upgrade iPlanetAMPasswordResetService; Done.
        Upgrade iPlanetAMSessionService; Done.
        Upgrade iPlanetAMAuthService; Done.
        Upgrade iPlanetAMAuthLDAPService; Done.
        Upgrade sunAMAuthDataStoreService; Done.
        Upgrade AgentService; Done.
        New sub schema sunIdentityRepositoryService; Done.
        New sub schema AgentService; Done.
        Delete service sunFAMLibertyInteractionService; Done.
        Delete service sunFAMLibertySecurityService; Done.
        Creating entitlement application type crestPolicyService; Done.
        Creating entitlement application crestPolicyService; Done.
        Re-enabling Generic LDAPv3 Data Store; Done.
        Upgrading data store embedded; Done.
        Updating Platform Properties; Done.
        Writing Upgrade Log; Done.
        
        Upgrade Complete.

        For additional information about the command-line tool, see the reference documentation for upgrade.jar(1) in the Reference.

      4. Restart OpenAM or the container where it runs.

  8. (Optional) If you installed OpenAM using an external directory server as the configuration store, add an access control instruction (ACI) to the external directory to give the OpenAM administrative user server-side sorting privileges.

    The ACI should be similar to the following:

    aci: (targetcontrol="1.2.840.113556.1.4.473")(version 3.0;acl "Allow
     server-side sorting"; allow (read)(userdn = "ldap:///
     uid=openam,ou=admins,dc=example,dc=com");)

    See "Preparing an External Configuration Data Store" in the Installation Guide for more information about using an external directory server as the OpenAM configuration store.

  9. (Optional) If you want to configure the upgraded system for the Core Token Service (CTS), read "Configuring the Core Token Service" in the Installation Guide.

  10. Referral policies are not supported in OpenAM 16.1.4. If your OpenAM deployment has referral policies, the following warning message will appear when you upgrade your OpenAM server to OpenAM 16.1.4:

    Referrals found that require removing

    OpenAM will take the following actions during the upgrade:

    • Removing all referral policies from your OpenAM configuration.

    • Copying resource types and policy sets associated with removed referral policies to the realms targeted by the referral policies.

    For example, suppose you had an OpenAM 12 deployment with a referral policy in realm A, and that referral policy referred to policies in realm B. During an upgrade, OpenAM would delete the referral policy in realm A and copy all the resource types and policy sets associated with the deleted referral policy from realm A to realm B.

    After upgrading to OpenAM 16.1.4, you are responsible for reconfiguring OpenAM so that policy evaluation that previously depended upon referrals continues to function correctly. You might need to take one or both of the following actions:

    • Reconfiguring your policy agent with the realm and policy set [1] that contain policies to be evaluated when that agent requests a policy decision from OpenAM. Previously, you might have configured the agent to use a realm that contained a referral policy. Because referral policies are not supported in OpenAM 16.1.4, this is no longer possible.

    For more information about configuring an agent with a realm and policy set, see "Working With Realms and Policy Agents" in the Administration Guide.

    • Copying or moving a policy or a group of policies. OpenAM 16.1.4 has new REST API endpoints that let you copy and move policies. This functionality might be helpful when migrating away from policy deployments that use referral policies. For more information about the REST endpoints that let you copy and move policies, see "Copying and Moving Policies" in the Developer’s Guide.

  11. Validate that the service is performing as expected.

  12. Allow client application traffic to flow to the upgraded site.

To Complete Upgrade from OpenAM 11.0.x

After upgrade from OpenAM 11.0.x, all OAuth 2.0 client configurations inherit the default response types:

  • code

  • token

  • id_token

  • code token

  • token id_token

  • code id_token

  • code token id_token

  1. For each OAuth 2.0 client configuration, edit the list of response types to remove any that are not supported or not required.

  2. For each OAuth 2.0 client configuration, update the client password.

    As part of a fix for OpenID Connect ID Token signing, the password storage format for OAuth 2.0 clients has changed. OpenAM now stores client passwords using reversible encryption. OpenAM 11.0 stores client passwords using a one-way hash algorithm, and therefore the passwords cannot be recovered.

    You can update the client password by using either OpenAM console or the ssoadm update-agent command with the --attributevalues option to update the value of the userpassword attribute.

To Complete Upgrade from OpenAM 13.0.x

If you configured one or more JDBC audit event handlers in OpenAM 13.0.x, make the following changes to the audit tables' schema:

  1. Run the following command on Oracle databases that support OpenAM audit event handlers:

    ALTER TABLE am_auditaccess ADD (response_detail CLOB NULL);

    This command adds the response_detail column to the am_auditaccess table.

  2. Run the following commands on MySQL databases that support OpenAM audit event handlers:

    ALTER TABLE audit.am_auditconfig CHANGE COLUMN configobjectid objectid VARCHAR(255);
    ALTER TABLE audit.am_auditaccess ADD COLUMN response_detail TEXT NULL;

    The commands change the name of the configobjectid column in the am_auditconfig table to objectid and add the response_detail column to the am_auditaccess table.

  3. If you use databases other than Oracle or MySQL to support OpenAM audit event handlers, review their schema.

    If the am_auditconfig table has a column named configobjectid, change that column’s name to objectid.

    If the am_auditaccess table does not have a column named response_detail, add that column to the table’s schema.


1. The agent configuration UI refers to a policy set as an application.