Securosys Primus HSM
This guide describes how to configure OpenBao auto-unsealing with a Securosys Primus HSM by using the PKCS#11 interface.
Install the PKCS#11 library
This section describes how to install the PKCS#11 library.
Install on VMs or bare metal
For traditional installations, follow the Securosys PKCS#11 provider installation guide.
Kubernetes
The upstream OpenBao container images don't include the Securosys PKCS#11 library. To make the library available to the OpenBao pod on Kubernetes, use one of the following methods.
Option 1: Create a custom OpenBao container image
Build a custom container image based on the openbao-hsm-ubi image. The
upstream openbao image can't be used, because the Primus PKCS#11 library
requires glibc.
-
Download the PKCS#11 API Provider.
-
Unpack the provider for your architecture:
# Set the version of the downloaded provider.export VERSION=x.x.xunzip PrimusAPI_PKCS11-v${VERSION}.zip# Set your target architecture. 'aarch64' is also available.export ARCH=x86_64tar xvf PrimusAPI_PKCS11-X-${VERSION}-rhel8-${ARCH}.tar.gz -
Create a
Dockerfile:ARG BAO_VERSIONFROM ghcr.io/openbao/openbao-hsm-ubi:$BAO_VERSIONCOPY primus /usr/local/primus -
Build and push the container image:
# Replace x.x.x with the correct versions.podman build --build-arg BAO_VERSION="x.x.x" \-t openbao-hsm-ubi-primus:x.x.x .podman push openbao-hsm-ubi-primus:x.x.x \docker://registry.example.com/openbao-hsm-ubi-primus:x.x.x -
Deploy the HSM configuration and secrets to the cluster. For more information, see the Securosys documentation about the
primus.cfgfile and the.secrets.cfgfile.# Replace 4321 with your actual user PIN.kubectl create secret generic hsm-secrets \--from-literal=secrets.cfg="$(cat .secrets.cfg)" \--from-literal=pin="4321"kubectl create configmap hsm-config --from-file=primus.cfg=primus.cfg -
Extend the Helm values with the following configuration:
server:image:registry: "registry.example.com"repository: "openbao-hsm-ubi-primus"tag: "x.x.x"ha:raft:config: |# Your existing Raft storage configuration goes here.seal "pkcs11" {lib = "/usr/local/primus/lib/libprimusP11.so"slot = "0"key_label = "bao-root-key-aes"mechanism = "CKM_AES_GCM"}extraSecretEnvironmentVars:- envName: BAO_HSM_PINsecretName: hsm-secretssecretKey: pinvolumes:- name: hsm-configconfigMap:name: hsm-config- name: hsm-secretssecret:secretName: hsm-secretsvolumeMounts:- name: hsm-configmountPath: "/etc/primus/primus.cfg"subPath: primus.cfg- name: hsm-secretsmountPath: "/etc/primus/.secrets.cfg"subPath: secrets.cfg -
Initialize OpenBao:
bao operator init
Option 2: Inject the library with an init container
This method uses the upstream openbao-hsm-ubi container image without
modification. You build a custom init container image that copies the library
into an emptyDir volume during pod initialization.
This example stores the library as a tarball inside the init container image. For production environments, consider fetching the library from a secure artifact registry, such as JFrog Artifactory.
-
Download the PKCS#11 API Provider.
-
Unpack the provider for your architecture:
# Set the version of the downloaded provider.export VERSION=x.x.xunzip PrimusAPI_PKCS11-v${VERSION}.zip -
Create a
Dockerfile:FROM alpine:latestARG ARCHARG VERSIONCOPY PrimusAPI_PKCS11-X-${VERSION}-rhel8-${ARCH}.tar.gz /primus.tar.gzCMD tar -x -C /usr/local -f /primus.tar.gz -
Build and push the container image:
# Replace x.x.x with the correct version.podman build --build-arg VERSION="x.x.x" --build-arg ARCH="x86_64" \-t primus-library:1.0.0 .podman push primus-library:1.0.0 \docker://registry.example.com/primus-library:1.0.0 -
Deploy the HSM configuration and secrets to the cluster. For more information, see the Securosys documentation about the
primus.cfgfile and the.secrets.cfgfile.# Replace 4321 with your actual user PIN.kubectl create secret generic hsm-secrets \--from-literal=secrets.cfg="$(cat .secrets.cfg)" \--from-literal=pin="4321"kubectl create configmap hsm-config --from-file=primus.cfg=primus.cfg -
Extend the Helm values with the following configuration:
server:image:repository: "openbao/openbao-hsm-ubi"ha:raft:config: |# Your existing Raft storage configuration goes here.seal "pkcs11" {lib = "/usr/local/primus/lib/libprimusP11.so"slot = "0"key_label = "bao-root-key-aes"mechanism = "CKM_AES_GCM"}extraSecretEnvironmentVars:- envName: BAO_HSM_PINsecretName: hsm-secretssecretKey: pinvolumes:- name: hsm-configconfigMap:name: hsm-config- name: hsm-secretssecret:secretName: hsm-secrets- name: primus-libraryemptyDir: {}volumeMounts:- name: hsm-configmountPath: "/etc/primus/primus.cfg"subPath: primus.cfg- name: hsm-secretsmountPath: "/etc/primus/.secrets.cfg"subPath: secrets.cfg- name: primus-librarymountPath: "/usr/local/primus"readOnly: trueextraInitContainers:- name: init-primus-libraryimage: "registry.example.com/primus-library:1.0.0"volumeMounts:- name: primus-librarymountPath: /usr/local/primus -
Initialize OpenBao:
bao operator init
Create a key in the HSM
OpenBao does not automatically generate the key in the HSM. To create the key,
use a utility such as pkcs11-tool.
$ pkcs11-tool --module "/usr/local/primus/lib/libprimusP11.so" \
--slot 0 \
--pin 4321 \ # Replace with your actual user PIN.
--keygen \
--key-type aes:32 \
--label "bao-root-key-aes" \
--sensitive
In this command:
--module: Specifies the path to the PKCS#11 library.--slot 0: Specifies HSM slot 0. This value depends on your configuration.--pin 4321: Specifies the user PIN for authentication.--keygen: Generates a new key.--key-type aes:32: Specifies an AES-256 key suitable forCKM_AES_GCM. To use RSA withCKM_RSA_OAEP, specifyrsa:4096and swap--keygenfor--keypairgen.--label "bao-root-key-aes": Sets the label of the key in the HSM.--sensitive: Sets theCKA_SENSITIVEattribute, which prevents the key from being revealed in plaintext.
Configure the pkcs11 seal
Configure the PKCS#11 seal in the OpenBao configuration:
seal "pkcs11" {
lib = "/usr/local/primus/lib/libprimusP11.so"
slot = "0"
key_label = "bao-root-key-aes"
mechanism = "CKM_AES_GCM"
# pin = "1234"
}
If you used the Kubernetes-based setup above, you may have already configured this.
To avoid hard-coding the User PIN (also called the "PKCS#11 Password" by Securosys)
in the configuration file, you can set it via the BAO_HSM_PIN environment variable.
For more details, see the pkcs11 seal documentation.
Initialize OpenBao
Finally, initialize OpenBao:
bao operator init