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
zeroorunlimited, 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.extfile 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"
    }
  }
}