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

# Smallstep step-ca

> How Smallstep step-ca protects its online intermediate CA key with CryptoHub through the CryptoHub Client Library PKCS #11 module.

export const SmallstepCryptoHubFlow = () => <svg viewBox="0 0 720 390" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Smallstep certificate flow. A software root signs the intermediate certificate once. A certificate requester sends a request to the step-ca HSM container. The container sends a PKCS #11 signing operation through the CryptoHub Client Library to CryptoHub, which uses the intermediate key in the HSM and returns only the signature." style={{
  maxWidth: '100%',
  height: 'auto',
  fontFamily: 'Inter, system-ui, sans-serif',
  color: 'currentColor'
}}>
    <defs>
      <marker id="smallstep-arrow" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto" markerUnits="userSpaceOnUse">
        <polygon points="0 0, 10 3.5, 0 7" fill="currentColor" />
      </marker>
      <marker id="smallstep-success-arrow" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto" markerUnits="userSpaceOnUse">
        <polygon points="0 0, 10 3.5, 0 7" fill="var(--success, #055527)" />
      </marker>
    </defs>

    <text x="360" y="25" style={{
  textAnchor: "middle"
}} fontSize="13" fontWeight="700" fill="currentColor">One-time CA setup</text>
    <rect x="75" y="45" width="180" height="54" rx="6" fill="var(--diagram-node, rgba(0,0,0,0.05))" stroke="currentColor" strokeWidth="1.5" />
    <text x="165" y="68" style={{
  textAnchor: "middle"
}} fontSize="14" fontWeight="600" fill="currentColor">Software root key</text>
    <text x="165" y="87" style={{
  textAnchor: "middle"
}} fontSize="11.5" fill="currentColor">encrypted on the CA host</text>
    <rect x="465" y="45" width="180" height="54" rx="6" fill="var(--diagram-node, rgba(0,0,0,0.05))" stroke="var(--accent, #921111)" strokeWidth="1.8" />
    <text x="555" y="68" style={{
  textAnchor: "middle"
}} fontSize="14" fontWeight="600" fill="currentColor">Intermediate certificate</text>
    <text x="555" y="87" style={{
  textAnchor: "middle"
}} fontSize="11.5" fill="currentColor">public certificate on the CA host</text>
    <line x1="255" y1="72" x2="460" y2="72" stroke="currentColor" strokeWidth="1.5" strokeDasharray="6 4" markerEnd="url(#smallstep-arrow)" />
    <rect x="315" y="60" width="86" height="19" fill="var(--surface-1, #fbf9f7)" />
    <text x="358" y="74" style={{
  textAnchor: "middle"
}} fontSize="11.5" fill="currentColor">signs once</text>

    <line x1="30" y1="130" x2="690" y2="130" stroke="currentColor" strokeWidth="1" strokeOpacity="0.25" />
    <text x="360" y="157" style={{
  textAnchor: "middle"
}} fontSize="13" fontWeight="700" fill="currentColor">Certificate issuance</text>

    <rect x="30" y="190" width="150" height="62" rx="8" fill="var(--diagram-node, rgba(0,0,0,0.05))" stroke="currentColor" strokeWidth="1.5" />
    <text x="105" y="217" style={{
  textAnchor: "middle"
}} fontSize="14" fontWeight="600" fill="currentColor">Certificate requester</text>
    <text x="105" y="237" style={{
  textAnchor: "middle"
}} fontSize="11.5" fill="currentColor">service or workload</text>

    <rect x="260" y="190" width="180" height="62" rx="8" fill="var(--diagram-node, rgba(0,0,0,0.05))" stroke="var(--accent, #921111)" strokeWidth="1.8" />
    <text x="350" y="216" style={{
  textAnchor: "middle"
}} fontSize="14" fontWeight="600" fill="currentColor">step-ca HSM container</text>
    <text x="350" y="237" style={{
  textAnchor: "middle"
}} fontSize="11.5" fill="currentColor">direct PKCS #11 KMS</text>

    <rect x="540" y="190" width="150" height="62" rx="8" fill="var(--diagram-node, rgba(0,0,0,0.05))" stroke="var(--accent, #921111)" strokeWidth="1.8" />
    <text x="615" y="217" style={{
  textAnchor: "middle"
}} fontSize="14" fontWeight="600" fill="currentColor">CryptoHub</text>
    <text x="615" y="237" style={{
  textAnchor: "middle"
}} fontSize="11.5" fill="currentColor">client application service</text>

    <line x1="180" y1="211" x2="255" y2="211" stroke="currentColor" strokeWidth="1.5" markerEnd="url(#smallstep-arrow)" />
    <text x="218" y="201" style={{
  textAnchor: "middle"
}} fontSize="11" fill="currentColor">request</text>
    <line x1="440" y1="211" x2="535" y2="211" stroke="currentColor" strokeWidth="1.5" markerEnd="url(#smallstep-arrow)" />
    <text x="488" y="201" style={{
  textAnchor: "middle"
}} fontSize="11" fill="currentColor">sign over TLS</text>
    <line x1="535" y1="237" x2="445" y2="237" stroke="var(--success, #055527)" strokeWidth="1.7" strokeDasharray="6 4" markerEnd="url(#smallstep-success-arrow)" />
    <text x="490" y="267" style={{
  textAnchor: "middle"
}} fontSize="11" fill="var(--success, #055527)">signature only</text>
    <line x1="255" y1="237" x2="185" y2="237" stroke="var(--success, #055527)" strokeWidth="1.7" strokeDasharray="6 4" markerEnd="url(#smallstep-success-arrow)" />
    <text x="220" y="267" style={{
  textAnchor: "middle"
}} fontSize="11" fill="var(--success, #055527)">certificate</text>

    <rect x="510" y="305" width="210" height="58" rx="8" fill="var(--diagram-node, rgba(0,0,0,0.05))" stroke="currentColor" strokeWidth="1.5" />
    <text x="615" y="329" style={{
  textAnchor: "middle"
}} fontSize="14" fontWeight="600" fill="currentColor">Intermediate private key</text>
    <text x="615" y="349" style={{
  textAnchor: "middle"
}} fontSize="11.5" fill="currentColor">nonexportable in the HSM</text>
    <line x1="615" y1="252" x2="615" y2="300" stroke="currentColor" strokeWidth="1.5" markerEnd="url(#smallstep-arrow)" />
    <rect x="594" y="267" width="42" height="18" fill="var(--surface-1, #fbf9f7)" />
    <text x="615" y="280" style={{
  textAnchor: "middle"
}} fontSize="11" fill="currentColor">uses</text>
  </svg>;

Smallstep step-ca is an online certificate authority for internal PKI. This integration keeps the online intermediate CA key in CryptoHub while step-ca issues X.509 certificates to services and workloads.

## The CA key model

This guide uses two CA tiers:

* The root key remains encrypted on the step-ca host. Use it only to sign the intermediate certificate, then protect it as an offline root.
* The intermediate private key remains nonexportable in CryptoHub. The running CA uses this key for routine certificate issuance.

The split keeps the frequently used signing key in the HSM without requiring step-ca to access the root key during normal operation.

## How it works

The `smallstep/step-ca:0.30.2-hsm` container loads the endpoint-delivered `libcryptohub-pkcs11.so` module through Smallstep's native PKCS #11 KMS. The module authenticates from the protected UserPass credential in `cryptohub.json` and connects to CryptoHub over TLS on TCP 443.

When step-ca issues a certificate:

1. The requester sends a certificate request to step-ca.
2. step-ca builds the certificate data and asks its PKCS #11 signer to sign it.
3. The CryptoHub Client Library sends the signing operation to the Smallstep service in CryptoHub.
4. CryptoHub uses the intermediate key in the HSM and returns only the signature.
5. step-ca assembles and returns the issued certificate.

Neither CA private key travels to the requester or appears in the container filesystem.

<SmallstepCryptoHubFlow />

## Why this route uses the HSM image

Smallstep's standard `step-ca` release binary is compiled without CGO and rejects a PKCS #11 KMS. The `0.30.2-hsm` image includes the CGO-enabled CA and the step-kms-plugin needed to load a native PKCS #11 module.

An OpenSSL provider is not part of this integration. step-ca loads the CryptoHub module directly through its own KMS configuration.

## Validated scope

This guide covers:

* CryptoHub 7.3.0.x build 7.3.0.0b or later in that branch.
* Smallstep step-ca `0.30.2-hsm` on a Linux x86-64 Docker host.
* step CLI 0.30.6 and step-kms-plugin 0.17.0.
* One software root and one CryptoHub-backed RSA-3072 intermediate.
* UserPass endpoint authentication over the CryptoHub REST API.
* Leaf issuance, independent chain verification, and issuance after a container restart.

High availability, ACME, SSH CA operation, key rotation, Windows, and a native source-built step-ca daemon are outside this guide.
