> ## 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 the CA, issue an HSM-backed intermediate certificate, and point ca.json at the CryptoHub-resident key through PKCS #11.

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 expandable lines wrap title="Shell" theme={null}
touch /tmp/ca-password.txt
chmod 600 /tmp/ca-password.txt
nano /tmp/ca-password.txt
```

Put a single line holding your chosen password in the file, with no trailing blank line.

<Note>
  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](/Integrations/CryptoHub/Certificate_Authority/Smallstep_step-ca/Validate_the_integration). Move it out of `/tmp` to a location your host does not clear on reboot if you keep the CA running.
</Note>

## 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 expandable lines wrap title="Shell" theme={null}
step ca init --name "CryptoHub Smallstep CA" --dns localhost --address ":9000" --provisioner admin@localhost --password-file /tmp/ca-password.txt
```

<Check>
  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`.
</Check>

<Note>
  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](/Integrations/CryptoHub/Certificate_Authority/Smallstep_step-ca/Validate_the_integration).
</Note>

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 expandable lines wrap title="Shell" theme={null}
step certificate create --profile intermediate-ca --ca ~/.step/certs/root_ca.crt --ca-key ~/.step/secrets/root_ca_key --ca-password-file /tmp/ca-password.txt --kms 'pkcs11:module-path=/usr/local/lib/fxpkcs11/libfxpkcs11.so;token=Futurex?pin-value=<PIN>' --key 'pkcs11:id=7101;object=smallstep-ca-key' "CryptoHub Smallstep Intermediate CA" /tmp/intermediate_ca.crt
```

<Check>
  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 expandable lines wrap title="Shell" theme={null}
  step certificate inspect /tmp/intermediate_ca.crt --short
  ```
</Check>

Replace the software intermediate certificate with the new one, keeping a backup:

```shell expandable lines wrap title="Shell" theme={null}
cp ~/.step/certs/intermediate_ca.crt ~/.step/certs/intermediate_ca.crt.bak
cp /tmp/intermediate_ca.crt ~/.step/certs/intermediate_ca.crt
```

<Warning>
  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.
</Warning>

## 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 expandable lines wrap title="Shell" theme={null}
shred -u ~/.step/secrets/intermediate_ca_key
```

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 expandable lines wrap title="Shell" theme={null}
nano ~/.step/config/ca.json
```

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:

```json expandable lines wrap title="ca.json" theme={null}
"key": "pkcs11:id=7101;object=smallstep-ca-key",
```

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:

```json expandable lines wrap title="ca.json" theme={null}
"kms": {
  "type": "pkcs11",
  "uri": "pkcs11:module-path=/usr/local/lib/fxpkcs11/libfxpkcs11.so;token=Futurex?pin-value=<PIN>"
}
```

<Warning>
  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 expandable lines wrap title="Shell" theme={null}
  chmod 600 ~/.step/config/ca.json
  ```

  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.
</Warning>

## 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.

<Warning>
  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.
</Warning>

Rewrite all three at once, substituting your own home directory path:

```shell expandable lines wrap title="Shell" theme={null}
sed -i "s|$HOME/.step|/home/step/.step|g" ~/.step/config/ca.json
```

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.

<Check>
  The relevant parts of `ca.json` now look like the following:

  ```json expandable lines wrap title="ca.json" theme={null}
  {
    "root": "/home/step/.step/certs/root_ca.crt",
    "crt": "/home/step/.step/certs/intermediate_ca.crt",
    "key": "pkcs11:id=7101;object=smallstep-ca-key",
    "address": ":9000",
    "dnsNames": [
      "localhost"
    ],
    "db": {
      "type": "badgerv2",
      "dataSource": "/home/step/.step/db"
    },
    "kms": {
      "type": "pkcs11",
      "uri": "pkcs11:module-path=/usr/local/lib/fxpkcs11/libfxpkcs11.so;token=Futurex?pin-value=<PIN>"
    }
  }
  ```

  The `authority` and `tls` blocks that `step ca init` generated remain unchanged.
</Check>
