Stronghold supports root key encryption using Hardware Security Modules (HSM) such as TPM2, JaCarta, and other devices that support the PKCS #11 standard.
For testing and development, you can also use the SoftHSM2 program emulator.
Currently, HSM is only supported in standalone Stronghold installations. In the examples below, it’s assumed that you use a local configuration file and a seal "pkcs11" section in the standalone server configuration.
To use automatic unsealing via PKCS #11, start by creating keys in the HSM and configuring Stronghold to use them.
SoftHSM2
To test Stronghold integration with the HSM, you can use SoftHSM2 emulator. Do the following to create a token, generate a key pair and configure Stronghold to use the key.
Install the required packages:
apt install libsofthsm2 openscCreate a directory for keeping the SoftHSM2 data and the configuration file:
mkdir /home/stronghold/softhsm cd softhsm echo "directories.tokendir = /home/stronghold/softhsm/" > /home/stronghold/softhsm2.confSet a path to the SoftHSM2 configuration and the PKCS #11 library:
export SOFTHSM2_CONF=/home/stronghold/softhsm2.conf HSMLIB="/usr/lib/x86_64-linux-gnu/softhsm/libsofthsm2.so"Initialize a token and set the PIN codes:
pkcs11-tool --module $HSMLIB --init-token --so-pin 1234 --init-pin --pin 4321 --label my_token --loginExample output:
Using slot 0 with a present token (0x0) Token successfully initialized User PIN successfully initializedEnsure the token has been created and initialized:
pkcs11-tool --module $HSMLIB -LExample output:
Available slots: Slot 0 (0xe6829d3): SoftHSM slot ID 0xe6829d3 token label : my_token token manufacturer : SoftHSM project token model : SoftHSM v2 token flags : login required, rng, token initialized, PIN initialized, other flags=0x20 hardware version : 2.6 firmware version : 2.6 serial num : 6a5468368e6829d3 pin min/max : 4/255 Slot 1 (0x1): SoftHSM slot ID 0x1 token state: uninitializedCreate an RSA key pair in the token:
pkcs11-tool --module $HSMLIB --login --pin 4321 --keypairgen --key-type rsa:4096 --label "vault-rsa-key"Example output:
Using slot 0 with a present token (0xe6829d3) Key pair generated: Private Key Object; RSA label: vault-rsa-key Usage: decrypt, sign, signRecover, unwrap Access: sensitive, always sensitive, never extractable, local Public Key Object; RSA 4096 bits label: vault-rsa-key Usage: encrypt, verify, verifyRecover, wrap Access: localCreate a Stronghold configuration file (
config.hcl) and add the PKCS #11 parameters into it:api_addr="https://0.0.0.0:8200" log_level = "warn" ui = true listener "tcp" { address = "0.0.0.0:8200" tls_cert_file = "/home/stronghold/cert.pem" tls_key_file = "/home/stronghold/key.pem" #tls_require_and_verify_client_cert = true #tls_client_ca_file = "ca.crt" tls_disable = "false" } storage "raft" { path = "/home/stronghold/data" } seal "pkcs11" { lib = "/usr/lib/x86_64-linux-gnu/softhsm/libsofthsm2.so" token_label = "my_token" pin = "4321" key_label = "vault-rsa-key" rsa_oaep_hash = "sha1" }Start Stronghold while specifying the SoftHSM2 configuration:
- Stronghold in DKP
- Stronghold in Linux
export SOFTHSM2_CONF=/home/stronghold/softhsm2.conf d8 stronghold server -config config.hclexport SOFTHSM2_CONF=/home/stronghold/softhsm2.conf stronghold server -config config.hcl
Migration from Shamir keys to HSM
Modify the Stronghold configuration by adding the
seal "pkcs11"section:seal "pkcs11" { lib = "/usr/lib/librtpkcs11ecp.so" token_label = "my_token" pin = "12345678" key_label = "vault-rsa-key" }Restart Stronghold. The logs should show a message:
2025-04-03T17:08:13.431+0300 [WARN] core: entering seal migration mode; Stronghold will not automatically unseal even if using an autoseal: from_barrier_type=shamir to_barrier_type=pkcs11Perform the migration by entering the unseal keys:
- Stronghold in DKP
- Stronghold in Linux
d8 stronghold operator unseal -migratestronghold operator unseal -migrate
After the migration is complete, Stronghold will automatically unseal using PKCS #11 on restart.
Migration from HSM to Shamir keys
Modify the configuration by adding the parameter
disabled = "true"to theseal "pkcs11"section:seal "pkcs11" { lib = "/usr/lib/librtpkcs11ecp.so" token_label = "my_token" pin = "12345678" key_label = "vault-rsa-key" disabled = "true" }Restart Stronghold.
Perform the migration by entering the recovery keys:
- Stronghold in DKP
- Stronghold in Linux
d8 stronghold operator unseal -migratestronghold operator unseal -migrate
After the migration is complete, Stronghold will require manual entry of unseal keys on each restart.