HsmSecretStore
Manage a store of secrets with a hardware security module (HSM) device or a software emulation of an HSM device, such as SoftHSM.
The secrets provider queries the HsmSecretStore for a named secret,
identified by a secret ID and a stable ID, corresponding to the
secret-id
/aliases
mapping. The HsmSecretStore returns a list of matching
secrets.
The secrets provider builds the secret, checking that the secret’s constraints are met, and returns a unique secret. If the secret’s constraints are not met, the secrets provider cannot build the secret and the secret query fails.
For a description of how secrets are managed, see Secrets.
Usage
{
"name": string,
"type": "HsmSecretStore",
"config": {
"providerName": configuration expression<string>,
"storePassword": configuration expression<secret-id>,
"secretsProvider": SecretsProvider reference,
"mappings": [ object, ... ],
"leaseExpiry": configuration expression<duration>
}
}
Properties
"providerName"
: configuration expression<string>, required-
The 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>, required-
The secret ID of the password to access the HsmSecretStore.
For information about how IG manages secrets, see Secrets.
"secretsProvider"
: SecretsProvider reference, optional-
The SecretsProvider object to query for the
storePassword
.Default: The route’s default secret service. For more information, see Default secrets object.
"mappings"
: array of objects, required-
One or more mappings of one secret ID to one or more aliases.
The following example maps a secret ID to two aliases:
"mappings": [ { "secretId": "global.pcookie.crypt", "aliases": [ "rsapair72-1", "rsapair72-2" ] } ]
"leaseExpiry"
: configuration expression<duration>, optional-
The amount of time that secrets produced by this store can be cached before they must be refreshed.
If the duration is
zero
orunlimited
, IG issues a warning, and uses the default value.Default: 5 minutes
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": "${find(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://am.example.com:8088/openam",
"version": "7.2"
}
},
{
"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"
}
}
}