Skip to main content
Configuring the CA takes four moves: initialize a CA with software keys, reissue the intermediate certificate against the CryptoHub-resident key, point ca.json at that key, and rewrite the file paths in ca.json so the container can resolve them.

Create the CA password file

step ca init encrypts the root CA private key and the provisioner key with one password. Later steps need that same password, so write it to a protected file first and reuse the file rather than retyping the value.
Shell
Put a single line holding your chosen password in the file, with no trailing blank line.
This one file is used four times: step ca init sets the password with it, step certificate create decrypts the root key with it, the container decrypts the CA material with it at startup, and step ca token unlocks the provisioner with it in Validate the integration. Move it out of /tmp to a location your host does not clear on reboot if you keep the CA running.

Initialize the certificate authority

step ca init creates a root CA, a software intermediate CA, a JWK provisioner, and a ca.json configuration file under ~/.step.
Shell
The step CLI reports the files it created under ~/.step, including certs/root_ca.crt, certs/intermediate_ca.crt, secrets/root_ca_key, secrets/intermediate_ca_key, and config/ca.json.
This guide uses the provisioner name admin@localhost and the DNS name localhost so the validation commands run on the CA host itself. For a CA that serves other machines, set --dns to the CA’s resolvable name and choose a provisioner name that identifies its owner. Whatever you choose, use the same provisioner name in Validate the integration.
At this point both CA keys are software key files. The next two sections replace the intermediate with a CryptoHub-resident key.

Issue an HSM-backed intermediate certificate

Create a new intermediate CA certificate whose public key is the CryptoHub-resident key, signed by the software root you created in the previous section. Replace <PIN> with your PKCS #11 PIN.
Shell
The step CLI writes /tmp/intermediate_ca.crt. Inspect it and confirm the subject is CryptoHub Smallstep Intermediate CA and the public key is RSA 3072, which is the key held on the appliance:
Shell
Replace the software intermediate certificate with the new one, keeping a backup:
Shell
The intermediate certificate on disk and the key in ca.json must be the same key pair. If you regenerate the CryptoHub key later, reissue this certificate as well. A mismatch causes step-ca to exit with x509: provided PrivateKey doesn't match parent's PublicKey at startup.

Secure the software keys

The software intermediate key is no longer used, and the root key is only needed to reissue the intermediate. Take both out of the running CA’s reach.
Shell
Move ~/.step/secrets/root_ca_key to offline storage, such as an encrypted removable volume or a vault, before you remove it from the host. Keeping the root key offline is the recommended architecture: the root signs rarely, and its protection comes from isolation, while the intermediate signs continuously and is protected by CryptoHub.

Point ca.json at the CryptoHub key

Open the CA configuration file:
Shell
Make two changes. Replace the key value, which currently points at the software intermediate key file, with the PKCS #11 URI for the CryptoHub-resident key:
ca.json
Add a top-level kms block, as a sibling of root, crt, and key, that tells step-ca which PKCS #11 module to load. Replace <PIN> with your PKCS #11 PIN:
ca.json
The pin-value parameter writes the PKCS #11 PIN into ca.json in cleartext. step-ca’s PKCS #11 key management system offers no validated PIN indirection for this module, so there is no supported way to move the PIN out of the file in this integration. Restrict the file to its owner and treat it as a secret:
Shell
Exclude ca.json from backups and configuration repositories that are not encrypted, and rotate the endpoint PIN in CryptoHub if the file is ever exposed.

Rewrite the file paths for the container

step ca init writes host-absolute paths into ca.json, based on the home directory of the user who ran it. The CA process runs in a container that mounts ~/.step at /home/step/.step, so those host paths do not exist inside it.
Rewrite root, crt, and db.dataSource to their /home/step/.step/... equivalents before you start the container. If you leave the host paths in place, the container cannot find the certificates or the database and exits immediately.
Rewrite all three at once, substituting your own home directory path:
Shell
Leave the kms block’s module-path unchanged. The FXPKCS11 directory is mounted at the same absolute path inside the container as on the host, so /usr/local/lib/fxpkcs11/libfxpkcs11.so resolves in both.
The relevant parts of ca.json now look like the following:
ca.json
The authority and tls blocks that step ca init generated remain unchanged.