Skip to main content

Installation PKCS#11 with Docker

This guide explains how to install the Primus PKCS#11 Provider for applications that are deployed in container environments such as Docker Compose or Kubernetes.

Prerequisites

This guide assumes that you are already familiar with the traditional, native Linux installation of the Primus PKCS#11 Provider. It also assumes that you know either Docker Compose and/or know how to operate a Kubernetes cluster with Helm.

Overview

The native Linux installation method is interactive. Administrators manually unpack the archive, edit the config files, and interactively use the ppin tool to exchange the Setup Password for the Permanent Secret.

This is not suitable for container environments. Instead, the installation must be translated to container concepts.

Recall that a complete Primus PKCS#11 Provider installation consists of the following files in the locations /usr/local/primus and /etc/primus/.

$ tree -a /usr/local/primus/

/usr/local/primus/
├── bin
│   └── ppin
├── etc
│   ├── .secrets.cfg
│   └── primus.cfg
├── include
│   ├── oasis-pkcs11-v3.2
│   │   ├── pkcs11.h
│   │   ├── pkcs11f.h
│   │   └── pkcs11t.h
│   ├── pkcs11-2.4.0.h
│   ├── pkcs11-2.5.2.h
│   └── pkcs11.h
└── lib
├── libprimusP11.so -> libprimusP11.so.2
├── libprimusP11.so.2 -> libprimusP11.so.2.7.0
└── libprimusP11.so.2.7.0

6 directories, 12 files
$ tree -a /etc/primus/

/etc/primus/
├── .secrets.cfg
└── primus.cfg

1 directory, 2 files

In order to have a working Primus PKCS#11 Provider usable by applications, you need to get at a minimum the following files into the container:

  • /usr/local/primus/libprimusP11.so (The final .so, either directly or through symlinks.)
  • /etc/primus/.secrets.cfg
  • /etc/primus/primus.cfg

The libprimusP11.so can be copied as-is from the release artifacts. It can either be mounted as a volume or baked into the container image.

The .secrets.cfg and primus.cfg must be manually prepared. They are configuration files and should be mounted as a volume.

Steps

Step 1: Prepare Files

Follow the native Linux installation guide and install the Primus PKCS#11 Provider on a temporary host. This can even be a Docker container that you delete afterwards. Use the ppin tool to create the .secrets.cfg file.

This step results in a working setup with complete .secrets.cfg and primus.cfg files.

Step 2: Deploy PKCS#11 Configuration to Kubernetes

Deploy the .secrets.cfg, the primus.cfg, and your PKCS#11 Password to your Kubernetes cluster. Replace PRIMUSDEV with your real PKCS#11 Password/PIN.

kubectl create secret generic hsm-secrets \
--from-literal=secrets.cfg="$(cat .secrets.cfg)" \
--from-literal=pkcs11pin="PRIMUSDEV"

kubectl create configmap hsm-config --from-file=primus.cfg=primus.cfg

Skip this step if you use Docker Compose.

Step 3: Build Init Container Image

Build a small container image containing the contents of /usr/local/primus/. This will serve as an init container that copies the files into an shared volume during pod/service initialization.

  1. Download the PKCS#11 API Provider.

  2. Unpack the ZIP:

    export VERSION=x.x.x
    unzip PrimusAPI_PKCS11-v${VERSION}.zip
  3. Create a Dockerfile:

    FROM alpine:3

    ARG ARCH=x86_64
    ARG VERSION=2.7.0

    COPY PrimusAPI_PKCS11-X-${VERSION}-rhel8-${ARCH}.tar.gz /primus.tar.gz

    # This must run at container start time, so that it writes to the volume mount!
    CMD tar -x -C /usr/local -f /primus.tar.gz
  4. Build and push the container image:

    export VERSION=x.x.x

    docker build --build-arg VERSION="${VERSION}" --build-arg ARCH="x86_64" -t primus-pkcs11:${VERSION} .

    docker push primus-pkcs11:${VERSION} docker://registry.example.com/primus-pkcs11:${VERSION}

Step 4: Deploy with Docker Compose or Helm

Modify your deployment configuration (docker-compose.yml or Helm chart) to look something like the below. This example uses OpenBao, but it should work similar for other applications.

services:
openbao:
image: docker.io/openbao/openbao-hsm-ubi:2.6.1
volumes:
- primus-library:/usr/local/primus
- ./primus.cfg:/etc/primus/primus.cfg:ro
- ./.secrets.cfg:/etc/primus/.secrets.cfg:ro
pre_start:
- image: registry.example.com/primus-pkcs11:2.7.0

volumes:
primus-library:

The configurations work as follows:

  • The init container (pre_start/extraInitContainers) executes once at service/pod startup.
  • The volume persists and shares the files in /usr/local/primus/. Kubernetes uses an emptyDir volume.
  • The CMD in the init container image fills the /usr/local/primus/. (It only makes meaningful changes if the volume is empty or if you update the init container image with a new PKCS#11 provider version.)
  • The primus.cfg and .secrets.cfg are mounted from the manually created files. They can be read-only, because the application doesn't need to modify them.

Step 5: Configure Application

You can now configure your application to access the Primus PKCS#11 Provider.

Troubleshooting

The most common problem are Unix permission issues. Make sure that your containerized application has read access to all of:

  • /usr/local/primus/ (recursively)
  • /etc/primus/.secrets.cfg and /etc/primus/primus.cfg

You may need to manually use chown/chmod to adjust the permissions of the contents of the volume mounts.

Logging

The Primus PKCS#11 Provider writes to a log file, whose location is configured in primus.cfg. It is recommended to also capture these logs for auditability and debugging. Change the log location:

primus:
{
// ... Slot definitions ...

log:
{
file = "/var/log/primus/primus.log";
// ...
}; /* end log */
}; /* end primus */

Then mount /var/log/primus/ as a volume to persist the logs.

Conclusion

Your application running in Docker/Kubernetes is now be able to access and use the Primus PKCS#11 Provider.

Get started withCloudHSM for free.
Other questions?Ask Sales.
Feedback
Need help?