> ## Documentation Index
> Fetch the complete documentation index at: https://docs.futurex.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Configure step-ca to use CryptoHub

> Initialize a software root, issue an intermediate certificate for the CryptoHub key, and configure the step-ca PKCS #11 KMS.

Create a software root, replace the initial software intermediate with the CryptoHub-backed key, and update `ca.json` for the HSM container.

## Create the CA password file

Create one protected password file for the software root and JWK provisioner:

```shell title="Shell" theme={null}
export STEPPATH=/var/lib/smallstep/.step
export CA_PASSWORD_FILE=/var/lib/smallstep/ca-password.txt

install -m 0600 /dev/null "$CA_PASSWORD_FILE"
read -r -s -p 'CA and provisioner password: ' CA_PASSWORD
printf '\n'
printf '%s\n' "$CA_PASSWORD" > "$CA_PASSWORD_FILE"
unset CA_PASSWORD
```

The file contains one password line and is readable only by its owner.

<Warning>
  Protect this password with the same controls as the software root key. Losing both the password and a recoverable backup of the root prevents future intermediate renewal.
</Warning>

## Initialize the software CA

Replace `<CA-NAME>` with a descriptive CA name and `<CA-DNS-NAME>` with the DNS name clients use for step-ca.

```shell title="Shell" theme={null}
step ca init \
  --deployment-type standalone \
  --name '<CA-NAME>' \
  --dns '<CA-DNS-NAME>' \
  --address ':9000' \
  --provisioner admin \
  --password-file "$CA_PASSWORD_FILE" \
  --provisioner-password-file "$CA_PASSWORD_FILE"
```

The command reports paths for the root certificate, root private key, intermediate certificate, database, and `ca.json`.

At this stage, both CA keys are software keys. The next section replaces the online intermediate.

## Issue the CryptoHub-backed intermediate certificate

Load the CryptoHub variables:

```shell title="Shell" theme={null}
source /etc/step-ca/cryptohub.env
export CHLIBS_CONFIG
```

Issue an intermediate certificate whose public key comes from CryptoHub:

```shell title="Shell" theme={null}
step certificate create \
  --profile intermediate-ca \
  --kms "$STEP_KMS_URI" \
  --key "$STEP_INTERMEDIATE_KEY" \
  --ca "$STEPPATH/certs/root_ca.crt" \
  --ca-key "$STEPPATH/secrets/root_ca_key" \
  --ca-password-file "$CA_PASSWORD_FILE" \
  --not-after 43800h \
  --force \
  'CryptoHub Smallstep Intermediate CA' \
  "$STEPPATH/certs/intermediate_ca_cryptohub.crt"
```

The command reports that it saved `intermediate_ca_cryptohub.crt`.

## Confirm the key binding

Compare the public key in CryptoHub with the public key in the new certificate:

```shell title="Shell" theme={null}
step kms key \
  --kms "$STEP_KMS_URI" \
  "$STEP_INTERMEDIATE_KEY" \
  > /tmp/smallstep-hsm-public.pem

openssl x509 \
  -in "$STEPPATH/certs/intermediate_ca_cryptohub.crt" \
  -pubkey -noout \
  > /tmp/smallstep-cert-public.pem

openssl pkey -pubin \
  -in /tmp/smallstep-hsm-public.pem \
  -outform DER \
  > /tmp/smallstep-hsm-public.der

openssl pkey -pubin \
  -in /tmp/smallstep-cert-public.pem \
  -outform DER \
  > /tmp/smallstep-cert-public.der

cmp /tmp/smallstep-hsm-public.der /tmp/smallstep-cert-public.der
openssl verify \
  -CAfile "$STEPPATH/certs/root_ca.crt" \
  "$STEPPATH/certs/intermediate_ca_cryptohub.crt"
```

`cmp` produces no output. OpenSSL prints the intermediate certificate path followed by `OK`.

Only after both checks pass, install the new certificate and remove the superseded software intermediate key:

```shell title="Shell" theme={null}
install -m 0644 \
  "$STEPPATH/certs/intermediate_ca_cryptohub.crt" \
  "$STEPPATH/certs/intermediate_ca.crt"
rm -f "$STEPPATH/secrets/intermediate_ca_key"
```

The encrypted root key remains on disk. The online intermediate private key exists only in CryptoHub.

## Configure the PKCS #11 KMS

Rewrite the host paths for the container and add the KMS configuration:

```shell title="Shell" theme={null}
CA_CONFIG="$STEPPATH/config/ca.json"
CA_CONFIG_TMP=$(mktemp "$STEPPATH/config/ca.json.XXXXXX")

jq \
  --arg key "$STEP_INTERMEDIATE_KEY" \
  --arg kms "$STEP_KMS_URI" '
    .root = "/home/step/.step/certs/root_ca.crt" |
    .crt = "/home/step/.step/certs/intermediate_ca.crt" |
    .key = $key |
    .kms = {"type": "pkcs11", "uri": $kms} |
    .address = ":9000" |
    .db.dataSource = "/home/step/.step/db"
  ' "$CA_CONFIG" > "$CA_CONFIG_TMP"

chmod 0600 "$CA_CONFIG_TMP"
mv "$CA_CONFIG_TMP" "$CA_CONFIG"
```

## Validate the CA configuration

Verify the non-secret path and KMS fields:

```shell title="Shell" theme={null}
jq '{root, crt, key, kms, address, db: .db.dataSource}' \
  "$STEPPATH/config/ca.json"
```

The output shows `kms.type` set to `pkcs11`, the CryptoHub key URI, and `/home/step/.step/` paths that exist inside the container.
