HsmSecretStore
Manage a store of secrets with a hardware security module (HSM) device or a software emulation of an HSM device, such as SoftHSM.
Secrets from HsmSecretStore have a non-configurable lease duration of five minutes. The secret can be used for five minutes before it is refreshed or discarded.
For a description of how secrets are managed, see About Secrets.
Usage
{ "name": string, "type": "HsmSecretStore", "config": { "providerName": configuration expression<string>, "storePassword": configuration expression<secret-id>, "secretsProvider": SecretsProvider reference, "mappings": [ configuration object, ... ] } }
Properties
"providerName"
: configuration expression<enumeration>, requiredThe name of the pre-installed Java Security Provider supporting an HSM. Use a physical HSM device, or a software emulation of an HSM device, such as SoftHSM.
For the SunPKCS11 provider, concatenate
"providerName"
with the prefixSunPKCS11-
. For example, declare the following for the nameFooAccelerator
:"providerName": "SunPKCS11-FooAccelerator"
"storePassword"
: configuration expression<secret-id>, requiredThe secret ID of the password to access the HsmSecretStore.
For information about supported formats for
secret-id
, see secret-id.For information about how IG manages secrets, see "Secrets".
"secretsProvider"
: SecretsProvider reference, optionalThe SecretsProvider object to query for the
storePassword
. For more information, see "SecretsProvider".Default: The route's default secret service. For more information, see "Default Secrets Object".
"mappings"
: array of objects, requiredOne or more mappings of one secret ID to one or more aliases. The secret store uses the mappings as follows:
When the secret is used to create signatures or encrypt values, the secret store uses the active secret, the first alias in the list.
When the secret is used to verify signatures or decrypt data, the secret store tries all of the mapped aliases in the list, starting with the first, and stopping when it finds a secret that can successfully verify signature or decrypt the data.
The following example maps a secret ID to two aliases:
"mappings": [ { "secretId": "global.pcookie.crypt", "aliases": [ "rsapair72-1", "rsapair72-2" ] } ]
secretId
: configuration expression<secret-id>, requiredThe ID of the secret used in your configuration.
For information about supported formats for
secret-id
, see secret-id.aliases
: array of configuration expression<string>, requiredOne or more aliases for the secret ID.
Log Level
To facilitate debugging secrets for the HsmSecretStore, in logback.xml
add a logger defined by the fully qualified package name of the HsmSecretStore. The following line in logback.xml
sets the log level to ALL
:
<logger name="org.forgerock.secrets.keystore" level="ALL">
Example
To set up this example:
Set up and test the example in "JwtBuilderFilter", and then replace the KeyStoreSecretStore in that example with an HsmSecretStore.
Set an environment variable for the HsmSecretStore password,
storePassword
, and then restart IG.For example, if the HsmSecretStore password is
password
, set the following environment variable:export HSM_PIN='cGFzc3dvcmQ='
The password is retrieved by the SystemAndEnvSecretStore, and must be base64-encoded.
Create a provider config file, as specified in the PKCS#11 Reference Guide.
Depending on your version of Java, create a
java.security.ext
file for the IG instance, with the following content:security.provider.<number>=<provider-name> <path-to-provider-cfg-file>
or
security.provider.<number>=<class-name> <path-to-provider-cfg-file>
Start the IG JVM with the following system property that points to the provider config file:
-Djava.security.properties=file://path-to-security-extension-file
The following example route is based on the examples in "JwtBuilderFilter", replacing the KeyStoreSecretStore with an HsmSecretStore:
{ "name": "hsm-jwt-signature", "condition": "${matches(request.uri.path, '/hsm-jwt-signature$')}", "baseURI": "http://app.example.com:8081", "heap": [ { "name": "SystemAndEnvSecretStore-1", "type": "SystemAndEnvSecretStore" }, { "name": "AmService-1", "type": "AmService", "config": { "agent": { "username": "ig_agent", "passwordSecretId": "agent.secret.id" }, "secretsProvider": "SystemAndEnvSecretStore-1", "url": "http://openam.example.com:8088/openam", "version": "7" } }, { "name": "HsmSecretStore-1", "type": "HsmSecretStore", "config": { "providerName": "SunPKCS11-SoftHSM", "storePassword": "hsm.pin", "secretsProvider": "SystemAndEnvSecretStore-1", "mappings": [{ "secretId": "id.key.for.signing.jwt", "aliases": [ "signature-key" ] }] } } ], "handler": { "type": "Chain", "config": { "filters": [{ "name": "SingleSignOnFilter-1", "type": "SingleSignOnFilter", "config": { "amService": "AmService-1" } }, { "name": "UserProfileFilter-1", "type": "UserProfileFilter", "config": { "username": "${contexts.ssoToken.info.uid}", "userProfileService": { "type": "UserProfileService", "config": { "amService": "AmService-1" } } } }, { "name": "JwtBuilderFilter-1", "type": "JwtBuilderFilter", "config": { "template": { "name": "${contexts.userProfile.commonName}", "email": "${contexts.userProfile.rawInfo.mail[0]}" }, "secretsProvider": "HsmSecretStore-1", "signature": { "secretId": "id.key.for.signing.jwt" } } }, { "name": "HeaderFilter-1", "type": "HeaderFilter", "config": { "messageType": "REQUEST", "add": { "x-openig-user": ["${contexts.jwtBuilder.value}"] } } }], "handler": "ReverseProxyHandler" } } }