PingAM
This guide provides step-by-step instructions for integrating PingAM with a Thales Luna HSM to enhance security for token signing and encryption. PingAM ensures controlled access to network-based resources through robust authentication, authorization, and role-based policies.
By integrating with a PKCS11 keystore, PingAM leverages the Thales Luna HSM as a secure token to protect cryptographic keys and secrets. Available on-premises and in the cloud, Luna HSM strengthens data protection, ensures compliance with security regulations, and enhances overall system integrity.
Following this guide, security teams can establish a resilient access management framework that reinforces both security and compliance. Key benefits include:
-
Secure generation, storage, and protection of the identity signing private keys using either FIPS 140-2 or FIPS 140-3 Level 3 validated hardware.
-
Full life cycle management of the keys to ensure their integrity and reliability throughout their usage.
-
Maintenance of a comprehensive HSM audit trail for transparency and accountability in key operations.
-
Significant performance enhancements by offloading cryptographic operations from application servers.
Supported Platforms
This integration has been tested on the following platforms:
HSM Type | Tested Platforms | JDK Version | OpenAM Version |
---|---|---|---|
Luna HSM | Red Hat Enterprise Linux 8.8 | OpenJDK 11 | OpenAM 7.3.2 |
Prerequisites
Before proceeding with the integration, ensure the following tasks are completed:
Configure Luna HSM
The initial step in this integration process involves configuring the on-premises Luna HSM. Refer to the instructions below to successfully set up your on-premises Luna HSM.
1Ensure that the HSM is set up, initialized, provisioned, and ready for deployment. For more information, refer to Luna HSM documentation.
2Create a partition that will be later on used by PingAM.
3Create and exchange certificate between the Luna Network HSM and client system. Register client and assign partition to create an NTLS connection.
4Initialize Crypto Officer and Crypto User roles for the registered partition.
5Run the following command to verify that the partition has been successfully registered and configured:
/usr/safenet/lunaclient/bin/lunacm
Upon successful execution, you should observe an output similar to the example provided below:
lunacm (64-bit) v10.7.2-16. Copyright (c) 2024 Thales Group. All rights reserved. Available HSMs: Slot Id -> 0 Label -> TPA01 Serial Number -> 1312109862218 Model -> LunaSA 7.7.1 Firmware Version -> 7.7.1 Bootloader Version -> 1.1.2 Configuration -> Luna User Partition With SO (PW) Key Export With Cloning Mode Slot Description -> Net Token Slot FM HW Status -> Non-FM Current Slot Id -> 0
Note
Refer to Luna HSM documentation for detailed steps on creating NTLS connection, initializing the partitions, and assigning various user roles.
Note
For proper configuration of a PED-based Luna HSM, it is recommended to activate partition policies 22 and 23, allowing for both activation and auto-activation.
Note
This integration is fully tested with both HA and FIPS modes.
Set up Luna HSM HA group
Refer to Luna HSM documentation for HA steps and details regarding configuring and setting up two or more HSM boxes on host systems. You must enable the HAOnly
setting in HA for failover to work so that if the primary goes down due to any reason, all calls get automatically routed to the secondary until the primary recovers and starts up.
Managing User Access to Your HSM
Initially, only the root user can access the Hardware Security Module (HSM). However, you can grant access to specific non-root users by including them in the hsmusers
group. This group is automatically created when you install the client software. Even if you later uninstall the client software, the hsmusers
group remains intact, ensuring you can upgrade your software without losing your user access settings.
To add users to the hsmusers group
If you wish to permit non-root users or applications to interact with the HSM device, you must assign these users to the hsmusers group. Make sure that the users you intend to add to the hsmusers group are already established on the client workstation. Only users added to the hsmusers group will be granted access to the HSM device. Follow these steps to add a user to the hsmusers group:
1Ensure that you possess sudo privileges on the client workstation.
2Add a user to the hsmusers group using the command:
sudo gpasswd --add <username> hsmusers
Replace username
with the actual username you want to include in the hsmusers group.
To remove users from the hsmusers group
If you need to withdraw a user's authorization to access the HSM device, you can remove them from the hsmusers group. Carry out the following steps to remove a user from the hsmusers group:
1Confirm that you hold sudo privileges on the client workstation.
2Eliminate a user from the hsmusers group using the command:
sudo gpasswd --delete <username> hsmusers
Replace username
with the specific username you want to exclude from the hsmusers group. To observe the changes, you will need to log in again.
Note
Any user you remove will retain access to the HSM device until the client workstation is rebooted.
Set up PingAM
Before integrating PingAM with Thales HSM, ensure that PingAM is installed and properly configured.
1Understand the OpenAM Platform: Refer to the PingAM documentation for installation, pre-installation requirements, and deployment options.
2Install PingAM: Set up PingAM on the target machine following the recommended guidelines.
3Verify the Installation: Ensure that PingAM is running and accessible before proceeding with integration.
Environment setup
This guide demonstrates the integration of PingAM for OAuth 2.0 token signing using a three-server setup, as outlined in the PingAM OAuth 2.0 documentation:
-
Authorization Server:
https://authz.example.com:8443/openam
– Acts as the OAuth 2.0 authorization server. -
Client Server:
https://client.example.com:8443/openam
– Functions as the OAuth 2.0 client and policy handler. -
Resource Server:
https://www.example.com:8443/
– A web agent-protected server where secured resources are hosted in Apache Tomcat.
In this setup:
-
The two AM servers communicate using OAuth 2.0.
-
The web agent on the resource server interacts with AM through standard AM-specific requests.
-
The resource server itself does not require OAuth 2.0 support.
The following figure, sourced from the PingAM documentation, illustrates the three-server setup used to demonstrate the integration for OAuth 2.0 token signing:
Configure PingAM with Thales HSM
PingAM runs as a web application within a web container, such as Apache Tomcat, and becomes available when the web container starts. To enable TLS using Luna HSM for the web container, refer to the Apache Tomcat Integration Guide. This guide assumes that PingAM is installed and running on the web server and that you have access to the Admin Console.
Follow these steps to configure secure token signing and encryption using Thales HSM:
1Set environment variables to ensure the web server runs with the correct configuration:
export CATALINA_BASE=/opt/apache-tomcat # If using Apache Tomcat export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-11.0.25.0.9-2.el8.x86_64 export PATH=$JAVA_HOME/bin:$PATH
Note
These variables must be set on all PingAM instances.
2Create your own key aliases in the PKCS11 keystore and update the default key aliases in the Admin UI and Secret ID mappings to match your setup. AM generates demo keys in a JCEKS keystore located at /path/to/openam/security/keystores
.
Note
This demonstration uses the same key aliases as those stored in the JCEKS keystore. If using different key aliases, refer to the PingAM documentation for modifying default key aliases and mapping and rotating secrets.
3List default key aliases in the JCEKS keystore to identify the keys stored by PingAM. Navigate to the keystore directory and run the following command:
cd /root/openam/security/keystores/ keytool -list -keystore keystore.jceks -storetype jceks -storepass:file ../secrets/default/.storepass -keypass:file ../secrets/default/.keypass
This command lists key aliases along with their key types:
es256test (ECDSA key) es384test (ECDSA key) es512test (ECDSA key) hmacsigningtest (Symmetric HMAC key) directenctest (Symmetric Direct AES encryption key) rsajwtsigningkey (Asymmetric RSA key) selfserviceenctest (Asymmetric RSA key) selfservicesigntest (Symmetric secret signing key) test (Asymmetric RSA key) *configstorepwd (password string) *dsameuserpwd (password string)
Note
The configstorepwd
and dsameuserpwd
aliases are created during AM restart. These store configuration passwords used during startup.
Note
This guide demonstrates using the same key aliases for keys generated on Luna HSM as those in the JCEKS keystore. If different aliases are used, follow the PingAM documentation on modifying default key aliases and mapping and rotating secrets.
4Create a PKCS11 configuration file (luna.cfg
) in a writable directory, such as /opt
, to define how the Luna HSM is accessed.
vi /opt/luna.cfg
Add the following content:
# SafeNet Luna HSM Configuration name = Luna library = /usr/safenet/lunaclient/lib/libCryptoki2_64.so description = Luna config slot = 0 attributes(*,*,*) = { CKA_TOKEN = true } attributes(*,CKO_SECRET_KEY,*) = { CKA_CLASS = 4 CKA_LABEL = true CKA_PRIVATE = true CKA_SENSITIVE = true CKA_SIGN = true CKA_VERIFY = true CKA_ENCRYPT = true CKA_DECRYPT = true CKA_WRAP = true CKA_UNWRAP = true } attributes(*,CKO_PRIVATE_KEY,*) = { CKA_CLASS = 3 CKA_LABEL = true CKA_PRIVATE = true CKA_SENSITIVE = true CKA_DECRYPT = true CKA_SIGN = true CKA_UNWRAP = true } attributes(*,CKO_PUBLIC_KEY,*) = { CKA_CLASS = 2 CKA_TOKEN = false CKA_LABEL = true CKA_ENCRYPT = true CKA_VERIFY = true CKA_WRAP = true } attributes(*,CKO_PRIVATE_KEY,CKK_EC) = { CKA_DERIVE = true }
Note
This configuration must be created on all PingAM instances.
5Run the following keytool command with the PKCS11 provider to generate an elliptic curve (EC) key pair on the Luna HSM, stored with the alias es256test
:
keytool -genkeypair -alias es256test -keyalg EC -groupname secp256r1 -sigalg SHA256withECDSA -keystore NONE -storetype PKCS11 -storepass userpin1 -providerClass sun.security.pkcs11.SunPKCS11 -providerArg /opt/luna.cfg -providerName SunPKCS11-Luna
- Perform key generation only on one AM instance if all instances share the same Luna HSM partition.
- Replace
userpin1
with the CO Password for Luna HSM. - The command generates a certificate and private key but does not assign a label to the private key.
6List the key handles to identify the newly generated private key.
/usr/safenet/lunaclient/bin/cmu list -password userpin1
Example output:
handle=1421 label=es256test handle=1429 label=
7Assign the missing key label.
/usr/safenet/lunaclient/bin/cmu setattribute -password userpin1 -handle=1429 -label=es256test
8Verify that the private key and certificate labels match.
/usr/safenet/lunaclient/bin/cmu list -password userpin1
Expected output:
handle=1421 label=es256test handle=1429 label=es256test
9Repeat this process for all asymmetric key aliases using the appropriate key generation commands:
keytool -genkeypair -alias es384test -keyalg EC -groupname secp384r1 -sigalg SHA384withECDSA -keystore NONE -storetype PKCS11 -storepass userpin1 -providerClass sun.security.pkcs11.SunPKCS11 -providerArg /opt/luna.cfg -providerName SunPKCS11-Luna keytool -genkeypair -alias es512test -keyalg EC -groupname secp521r1 -sigalg SHA512withECDSA -keystore NONE -storetype PKCS11 -storepass userpin1 -providerClass sun.security.pkcs11.SunPKCS11 -providerArg /opt/luna.cfg -providerName SunPKCS11-Luna keytool -genseckey -alias hmacsigningtest -keyalg HmacSHA256 -keysize 256 -keystore NONE -storetype PKCS11 -storepass userpin1 -providerClass sun.security.pkcs11.SunPKCS11 -providerArg /opt/luna.cfg -providerName SunPKCS11-Luna keytool -genseckey -alias directenctest -keyalg AES -keysize 256 -keystore NONE -storetype PKCS11 -storepass userpin1 -providerClass sun.security.pkcs11.SunPKCS11 -providerArg /opt/luna.cfg -providerName SunPKCS11-Luna keytool -genkeypair -alias rsajwtsigningkey -keyalg RSA -keysize 2048 -sigalg SHA256withRSA -keystore NONE -storetype PKCS11 -storepass userpin1 -providerClass sun.security.pkcs11.SunPKCS11 -providerArg /opt/luna.cfg -providerName SunPKCS11-Luna keytool -genkeypair -alias selfserviceenctest -keyalg RSA -keysize 2048 -sigalg SHA256withRSA -keystore NONE -storetype PKCS11 -storepass userpin1 -providerClass sun.security.pkcs11.SunPKCS11 -providerArg /opt/luna.cfg -providerName SunPKCS11-Luna keytool -genseckey -alias selfservicesigntest -keyalg HmacSHA256 -keysize 256 -keystore NONE -storetype PKCS11 -storepass userpin1 -providerClass sun.security.pkcs11.SunPKCS11 -providerArg /opt/luna.cfg -providerName SunPKCS11-Luna keytool -genkeypair -alias test -keyalg RSA -keysize 2048 -sigalg SHA256withRSA -keystore NONE -storetype PKCS11 -storepass userpin1 -providerClass sun.security.pkcs11.SunPKCS11 -providerArg /opt/luna.cfg -providerName SunPKCS11-Luna
Note
When generating asymmetric keys with the keytool
command, a self-signed certificate is created by default. If a CA-signed certificate is required, generate a certificate signing request, submit it to a CA for signing, and then import the CA-signed certificate into the PKCS11 keystore. If using a self-signed certificate, skip steps 10-11, as they are only required for CA-signed certificates.
10Generate a certificate request for an asymmetric key in the keystore.
keytool -certreq -alias test -sigalg SHA256withRSA -file certreq_file -keystore NONE -storetype PKCS11 -storepass userpin1 -providerClass sun.security.pkcs11.SunPKCS11 -providerArg /opt/luna.cfg
Submit the certificate signing request (CSR) to a CA. Once signed, the CA will return a certificate or a certificate chain.
11Import the signed certificate reply into the PKCS11 keystore.
keytool -importcert -trustcacerts -alias test -file certchain.p7b -keystore NONE -storetype PKCS11 -storepass userpin1 -providerClass sun.security.pkcs11.SunPKCS11 -providerArg /root/openam/security/keystores/luna.cfg
12Update java.security
to configure SunPKCS11 as a provider.
Open java.security
and modify the provider list:
security.provider.1=SUN security.provider.2=SunEC security.provider.3=SunJSSE security.provider.4=SunJCE security.provider.5=SunPKCS11 /opt/luna.cfg security.provider.6=SunJGSS security.provider.7=SunSASL security.provider.8=XMLDSig security.provider.9=SunPCSC security.provider.10=JdkLDAP security.provider.11=JdkSASL security.provider.12=com.safenetinc.luna.provider.LunaProvider security.provider.13=SunRsaSign
Note
This step must be performed on all AM instances.
13Verify the generated key materials on the Luna HSM using PKCS11 provider.
keytool -list -keystore NONE -storetype PKCS11 -storepass userpin1 -providerClass sun.security.pkcs11.SunPKCS11 -providerArg /opt/luna.cfg -providerName SunPKCS11-Luna
This command lists all keys and certificates stored in the Luna HSM partition.
14Ensure AM is running and that the AM admin UI is accessible with administrative credentials.
15Navigate to a writable directory that is shared across all AM instances and create an empty PKCS11 keystore file.
cd /root/openam/security/keystores/ touch PKCS11
16Store the PKCS11 keystore password in cleartext in a writable secrets directory.
cd /root/openam/security/secrets/default/ echo -n co_password > .hsmpass
Note
Replace co_password
with the actual password.
17Set read-only permissions for the password file to restrict access.
chmod 400 .hsmpass
18Navigate to the encrypted secrets directory shared across all AM instances.
cd /root/openam/security/secrets/encrypted
19Open the AM encoding page in a web browser:
https://authz.example.com:8443/openam/encode.jsp
20Enter the Crypto Officer (CO) password and copy the encoded password.
21Store the encoded password in a file named hsmpass
and set the correct permissions.
echo -n "encoded_password" > hsmpass chmod 400 hsmpass
Note
Replace "encoded_password"
with the actual encoded value.
22Log in to the AM admin UI, go to Configure > Server Defaults > Security > Key Store, and enter the keystore file name and path in the Keystore File field.
%BASE_DIR%/security/keystores/PKCS11
Note
%BASE_DIR%
represents the AM installation base directory. Ensure the keystore path is correct for your setup.
23Set Keystore Type to PKCS11
.
24Enter the keystore password file path in the Keystore Password File field.
%BASE_DIR%/security/secrets/default/.hsmpass
25Enter the private key password file path in the Private Key Password File field.
%BASE_DIR%/security/secrets/default/.hsmpass
26In the Certificate Alias field, enter the key alias generated on Luna HSM. The alias must match the one configured in Realms > [Realm Name] > Authentication > Settings > Security as the Persistent Cookie Encryption Certificate Alias.
Example:
test
27Click Save Changes.
Note
AM still retains the previous keystore configuration in memory and cannot yet use key aliases from the new keystore. Ensure the keystore files are available in the same location across all AM instances. This may involve mounting a shared filesystem or copying files manually.
28Restart all AM instances to apply the new keystore settings. The updated keystore and its keys are now in effect.
29Log in to the AM admin UI as an administrative user and create a secret store.
-
To create a global secret store, navigate to Configure > Secret Stores.
-
To create a realm-specific secret store, go to Realms > [Realm Name] > Secret Stores.
30Click Add Secret Store.
31Enter a unique Secret Store ID (e.g., pkcs11-keystore
).
32From the Store Type drop-down list, select Keystore.
33Enter the keystore file name in the File field.
/root/openam/security/keystores/PKCS11
Note
Ensure this file is accessible to all AM instances by storing it on a shared filesystem or manually copying and maintaining it across instances.
34Click Create.
35Set Keystore Type to PKCS11
.
36Enter SunPKCS11-Luna
in the Provider Name field.
37Enter hsmpass
in the Store Password Secret ID field.
38Enter hsmpass
in the Entry Password Secret ID field.
39Set the Key Lease Expiry Time (in minutes) as required.
40Click Save Changes.
41Navigate to Configure > Secret Stores > default-keystore > Mappings tab.
42Copy all Secret IDs and Aliases and save them in a text file for reference.
43Delete all keys and secret mappings from the Mappings tab of default-keystore
.
44Add the same Secret IDs and Aliases that were deleted from default-keystore
to the Mappings tab of pkcs11-keystore
. Use the text file saved earlier as a reference.
45In the AM admin UI, navigate to the realm, select Secret Stores, and add a new keystore named pkcs11-keystore
.
46Provide the same details as configured for the global pkcs11-keystore
. Click Save Changes.
47Add the realm-level Secret IDs and Aliases to the Mappings tab of pkcs11-keystore
. Use the text file saved earlier as a reference.
48Repeat these steps for all realms in the environment to create pkcs11-keystore
and configure the necessary mappings.
49Navigate to the keystore directory, create a backup of the existing JCEKS keystore, and then delete all key aliases that were migrated to the PKCS11 keystore.
# cd /root/openam/security/keystores/ # cp keystore.jceks keystore.jceks.b4.hsm
Delete the migrated key aliases one by one:
# keytool -delete -alias test -keystore keystore.jceks -storetype jceks -storepass:file ../secrets/default/.storepass -keypass:file ../secrets/default/.keypass
50Repeat the keytool -delete
command for all aliases:
-
es256test
(ECDSA key) -
es384test
(ECDSA key) -
es512test
(ECDSA key) -
hmacsigningtest
(Symmetric HMAC key) -
directenctest
(Symmetric Direct AES encryption key) -
rsajwtsigningkey
(Asymmetric RSA key) -
selfserviceenctest
(Asymmetric RSA key) -
selfservicesigntest
(Symmetric secret signing key) -
test
(Asymmetric RSA key)
Note
Ensure all aliases listed above are deleted from the JCEKS keystore.
This completes the integration of PingAM with Luna HSM. The keystore and secret store are now configured to use Luna HSM for cryptographic key operations. All secured keys are available for signing and encryption as per the configured Secret Store mappings.
Validate the Integration Using OAuth 2.0 Token Signing and Encryption
1Follow the steps provided in the AM OAuth 2.0 documentation for protecting a website with OAuth 2.0. This includes setting up the Authorization Server, Client, and Resource Server and installing the Java Agent.
2Replace the AM server and Resource Server URLs in the configuration with the URLs specific to your environment.
3Map the key aliases generated on Luna HSM in the Secret Store mappings, as previously done for the default key aliases.
4Configure AM Secret IDs for the OAuth 2.0 provider to use the correct key aliases:
-
Sign JWTs using the secret mapped to
am.global.services.oauth2.oidc.agent.idtoken.signing
. This secret ID must map to thersajwtsigningkey
key alias in the PKCS11 keystore. -
Sign claims using the secret mapped to
am.services.oauth2.jwt.authenticity.signing
. This secret ID must map to thehmacsigningtest
key alias in the PKCS11 keystore.
5Enable client-side token signing and encryption by configuring the OAuth 2.0 Provider and client. Ensure that a supported algorithm is configured. Refer to the AM documentation: Configure AM for client-side OAuth 2.0 tokens.
6Review the AM documentation for details on how AM features utilize keys from the Key Store and Secret Store.
7If the setup is correct, log out of any active session by opening the following URL in a web browser:
https://client.example.com:8443/openam/XUI/?realm=/#logout
Note
After logging out, access a resource protected by the AM Java Agent to verify that authentication is enforced. You should be prompted to authenticate before gaining access.
8Access the resource protected by the Java Agent by browsing the following URL. The AM Client and Authorization Server will use OAuth 2.0 tokens signed by keys stored in Luna HSM:
https://www.example.com:8443/examples/
9Authenticate and approve the authorization decision by clicking Allow.
The authorization service creates an SSO session by exchanging the signed token and redirects the client back to the protected resource.
10Retrieve the signed token by executing the following cURL command:
curl --request POST --user "myClientID:password" \ --data "grant_type=password&username=demo&password=Ch4ng31t&scope=cn" \ https://authz.example.com:8443/openam/oauth2/access_token
The response will contain an access token in JSON format:
"access_token":"eyJ0eXAiOiJKV1QiLCJraWQiOiI1bFJGeEY2OWt4VmxWblJlQi9zVGVuaW82dW89IiwiYWxnIjoiUlMyNTYifQ..."
11Retrieve and verify the token details using the access token obtained in the previous step. This can be done by executing the following cURL command or by accessing the URL in a web browser:
curl https://authz.example.com:8443/openam/oauth2/realms/root/tokeninfo?access_token=eyJ0eXAiO......e1ItSxlbw
A successful response confirms that the OAuth 2.0 configuration is correctly set up and that the token is valid.
This completes the OAuth 2.0 Token Signing demonstration using the AM Secret Store, configured to use the PKCS11 provider and leveraging keys generated on Luna HSM.