IG 2023.4

HsmSecretStore

Manage a store of secrets with a hardware security module (HSM) device or a software emulation of an HSM device, such as SoftHSM.

This Secret store can only manage secrets of the CryptoKey type.

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, refer to Secrets.

Usage

{
  "name": string,
  "type": "HsmSecretStore",
  "config": {
    "providerName": configuration expression<string>,
    "storePasswordSecretId": configuration expression<secret-id>,
    "secretsProvider": SecretsProvider reference,
    "mappings": [ object, ... ],
    "leaseExpiry": configuration expression<duration>,
    "storePassword": configuration expression<secret-id> //deprecated
   }
}

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 prefix SunPKCS11-. For example, declare the following for the name FooAccelerator:

"providerName": "SunPKCS11-FooAccelerator"
"storePasswordSecretId": configuration expression<secret-id>, required

The secret ID of the password to access the HsmSecretStore.

This secret ID must point to a GenericSecret.

For information about how IG manages secrets, refer to Secrets.

"secretsProvider": SecretsProvider reference, optional

The SecretsProvider object to query for the storePassword.

Default: The route’s default secret service. For more information, refer to 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" ]
  }
]
secretId: configuration expression<secret-id>, required

The ID of the secret used in your configuration.

aliases: array of configuration expression<strings>, required

One or more aliases for the secret ID.

"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 or unlimited, IG issues a warning, and uses the default value.

Default: 5 minutes

"storePassword": configuration expression<secret-id>, required if storePasswordSecretId not set
The use of this property is deprecated; use storePasswordSecretId instead. For more information, refer to the Deprecated section of the Release Notes.

The secret ID of the password to access the HsmSecretStore.

+ For information about how IG manages secrets, refer to Secrets.

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:

  1. Set up and test the example in JwtBuilderFilter, and then replace the KeyStoreSecretStore in that example with an HsmSecretStore.

  2. 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.

  3. Create a provider config file, as specified in the PKCS#11 Reference guide.

  4. 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>
  5. 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"
      }
    },
    {
      "name": "HsmSecretStore-1",
      "type": "HsmSecretStore",
      "config": {
        "providerName": "SunPKCS11-SoftHSM",
        "storePasswordSecretId": "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"
    }
  }
}
Copyright © 2010-2023 ForgeRock, all rights reserved.