Vault
Configure transit secrets engine to use PKCS 11 HSM using managed keys
Enterprise
Appropriate Vault Enterprise license required
Transit secrets engine can be pluged into Vault's centralised abstraction layer called managed keys to delegate crypto-operations operations to a trusted external KMS or HSM. This allows users to leverage key management systems external to Vault for handling, storing, and interacting with private key material.
Requirements
To setup transit secrets engine backed by PKCS 11 based HSM, you need:
- A Vault Enterprise server running.
- A PKCS 11 based HSM.
Vault setup
Configure managed key.
A PKCS#11 HSM requires a shared library to configure Vault to communication with the HSM. To declare this library, edit the Vault server configuration to add a
kms_librarystanzaconfig-vault.hcl
kms_library "pkcs11" { name = "myhsm" library = "/usr/vault/lib/libCryptoki2_64.so" }Use PKCS 11 with IBM EP11 tokens.
kms_library "pkcs11" { name = "myhsm" library = "/usr/local/lib/opencryptoki/libopencryptoki.so" }Restart or reload Vault's configuration with
SIGHUP.$ kill -HUP $(pidof vault)Each managed key requires type-specific configuration. You must identify the location of a key and PIN to access the HSM. This is very similar to Vault's PKCS#11 auto-unseal mechanism. Configure the managed key.
$ vault write sys/managed-keys/pkcs11/transit-rsa-key \ library=myhsm \ slot=4 \ pin=12345678 \ key_label="vault-rsa-key" \ allow_generate_key=true \ mechanism=0x0001 \ allow_store_key=true \ key_bits=2048 \ any_mount=falseThe PKCS#11 specific parameters are
library, referring to the previously configuredkms_librarystanza,slot,pin,key_label, andmechanism, which identifies the object in the HSM which will hold the key. Its mechanism isCKM_RSA_PKCS(RSA with PKCS#11 v1.5 signatures), and that will require a 2048 bit key. Theallow_generate_keyflag indicates that Vault is allowed to request that the HSM generate a key. Theallow_store_keyparameter indicates that a new key may be stored in the backend. Without this flag, you may configure the key yourself in the HSM and just point Vault at the result. Theany_mountmeans any mount in the namespace may access the managed key. For this example, it is set to false so that you can demonstrate how to lock managed key access down to a specific mount.Example output:
Success! Data written to: sys/managed-keys/pkcs11/transit-rsa-keyRead the key back to verify if named managed key was created successfully.
$ vault read sys/managed-keys/pkcs11/transit-rsa-key Key Value --- ----- UUID fe8f3c8c-8f11-571d-b4ce-411314fcaf98 allow_generate_key true allow_replace_key false allow_store_key true any_mount false key_bits 2048 key_label vault-rsa-key library myhsm mechanism 1 name transit-rsa-key pin redacted slot 4 type pkcs11 usages [3 4]
Configure transit secrets engine
Enable the
transitsecrets engine at thetransitpath.$ vault secrets enable transit Success! Enabled the transit secrets engine at: transit/Tune the secrets engine to use managed keys.
$ vault secrets tune --allowed-managed-keys=transit-rsa-key transit Success! Tuned the secrets engine at: transit/You configured the managed key with
any_mount=falsein the previous step. This command grants access to thetransit-rsa-keyto the Transit secrets engine's mount.Create a transit key.
$ vault write transit/keys/hsm-transit-key \ type=managed_key \ managed_key_name=transit-rsa-key \ allow_plaintext_backup=false \ exportable=falseExample output:
Key Value --- ----- allow_plaintext_backup false auto_rotate_period 0s deletion_allowed false derived false exportable false imported_key false latest_version 1 min_available_version 0 min_decryption_version 1 min_encryption_version 0 name hsm-transit-key supports_decryption true supports_derivation false supports_encryption true supports_signing true type managed_keyAt this step while creating transit key, RSA 2048 public private key pair also gets created in the HSM. The key label is
vault-rsa-key.
Perform crypto-operation
Perform the sign data operation.
$ vault write transit/sign/hsm-transit-key \ input=$(echo -n "data to sign" | base64) \ hash_algorithm=sha2-256Example output:
Key Value --- ----- key_version 1 signature vault:v1:bqLeknlTuvrPt99ubS0CZyDs5iG8q9n+7kLG+2qHmg1xcHxUdKYCvtIUO5ZpCjJ6SUA/cTJgeFqdhK5rOcSfTzhU5B+HABEYeVb+H7yQ4+sLWrJQ5fNAQZCly+AiXM4q2lAvMW651oq0D4R86f0tOUHVjsaQyqhrrtaA1GQoIcNikx4llTXiGRmc3A1dZmpFCpG7ejQuUF8mGj1tFmY/dyrV0V9o58rmqGe/ddfg+bAfpewNcqWPoWtB+o9QuFhw3L8eqxVCbF8lGfZlqJmudep13So4bC03bWdlZBET8nYpX51Bi5yz0C9wth666IiqE61JnPBlmcJFEyd3FCJ4yQ==Verify signed data.
$ vault write transit/verify/hsm-transit-key \ input=$(echo -n "data to sign" | base64) \ hash_algorithm=sha2-256 \ signature="vault:v1:..."The signature is the output of the sign command.
Example output:
Key Value --- ----- valid true