HSM & key management¶
Where private keys live, and the proof they never leave.
Every signing key in secsy-pki is created inside, and used through, a key provider — a PKCS#11 HSM, a cloud KMS, Vault Transit, or the software backend for development. Private key material is never exported. These guides cover choosing and configuring a backend, running the key ceremony, and proving the non-extractability guarantee to someone who does not trust you.
| Guide | Covers |
|---|---|
| HSM / PKCS#11 configuration | The key-provider abstraction, configuring a PKCS#11 HSM or the software backend, and SoftHSM for dev/CI |
| HSM high availability (multi-token failover) | Spanning several PKCS#11 tokens/slots behind health-tracked failover: pkcs11.tokens + selection_policy (primary-backup / round-robin), the failure-threshold & background recovery prober, replicated-key ceremony and the cross-token unique-label invariant, per-token health/failover metrics, and the SoftHSM mid-load failover test |
| Cloud KMS backend (AWS / Azure / Google) | Hosting CA/TSA/OCSP signing keys in AWS KMS, Azure Key Vault or Google Cloud KMS: key_provider.type: kms + backend selection, per-role backend routing (roles.ca/roles.tsa), credentials via the cloud SDK default chain, IAM/RBAC requirements, the non-extractability guarantee, and the in-memory fake backend for credential-free tests |
| HashiCorp Vault Transit backend | Hosting CA/TSA/OCSP signing keys and KEKs in a Vault Transit engine (kms.backend: vault): trust/non-extractability model, token & AppRole auth with transparent re-login, least-privilege Vault policy, per-role selection, wrap/unwrap (KEK) support, the openssl-verify interop path, and the hermetic httptest fake-Vault test |
| Key ceremony, backup & DR | M-of-N key ceremony (secsy-ca ceremony), key inventory, CA-metadata backup/restore, HSM token backup, and the disaster-recovery runbook & drill |
| Production HSM migration | Moving from SoftHSM to a real HSM (YubiHSM / network HSM) for production |
| Remotely verifiable HSM audit log | Proving to a third party that the HSM signed nothing beyond what was published, and that the proof is current: the device log's own format (the 62-entry ring, the 32-byte record field by field, the truncated-SHA-256 chain digest with a reproducible worked example, and the all-0xff factory-reset sentinel), irreversible force-audit provisioning (incl. undocumented firmware commands), a pinned factory-reset chain anchor — with the measured reason it cannot verify itself and must be recorded out of band — a fail-closed persist-before-acknowledge device-log collector, the hash-chained signature ledger written at the key-provider chokepoint, device-vs-ledger-vs-published reconciliation, periodic RFC 3161 freshness attestations over the audit head, per-key device attestations that bind each signing key to the public key it holds (so the verdict is about a key, not a count of device operations) plus its handle's create/delete/export history, device-signed serial bindings that put the audit head inside a label the factory attestation key certifies — timestamped, and welded into the log by the force-audited operations they leave behind — so an exported log is tied to Yubico-rooted hardware rather than to the CA's word, secsy-ca hsm-audit provision/collect/timestamp/commit/export/verify -key (the verifier needs no config, database or HSM), GET /api/hsm/audit-bundle, and the secsy_hsm_audit_* metrics |
| Native YubiHSM 2 driver | Talking to the device over its own protocol instead of the yubihsm-shell binary: a GlobalPlatform SCP03 secure channel over direct USB (Linux usbfs, no libusb/cgo) or a yubihsm-connector, typed DeviceErrors in place of regex-scraped output (the shell exits 0 on refused commands), wire-format parsing of audit entries and option maps, no temporary files or passwords on a child process, context deadlines that reach the device, connector-URL and multi-device selection, udev/permission requirements, and the fake-device conformance harness that pins the protocol in CI |
| YubiHSM key attestation | Proving what a CA key is, as a claim a relying party can check: the device-signed attestation certificate and its Yubico extensions (origin, capabilities, domains, on-device handle), the verifier that reports whether the key is non-exportable (exportable-under-wrap) and was generated on-device rather than imported, binding the attestation to a CA certificate so it describes the key that CA actually signs with, required chain anchoring to Yubico's published YubiHSM 2 attestation PKI (root and sub-CA both embedded), secsy-ca hsm-attest key/ca/audit/verify (the verifier needs no config, database or HSM), GET /api/hsm/keys/{label}/attestation, GET /api/ca/{id}/key-attestation, POST /api/hsm/attestation:verify, the hsm.key_attestation audit event, and the secsy_hsm_key_attestation* metrics |
| YubiHSM device attestation | Proving that the hardware itself is a genuine YubiHSM with the serial number it claims, against Yubico's published attestation CA rather than the operator's word: the factory attestation certificate in opaque object 0 and the Yubico-signed serial extension it carries, why verifying that chain authenticates a certificate and not a device, the challenge-response that closes the gap (a verifier-chosen nonce carried into an attestation signature through the label of a throwaway capability-less key in reserved slot 0xfa00, generated/attested/deleted in one session), cross-checking the certified serial against the certificate subject and against what the device reports over SCP03, secsy-ca hsm-attest device printing the verified serial with exit 0/1 — plus -no-challenge for a read-only check, -expect-serial, and offline third-party verification via hsm-attest verify -expect-challenge |
| YubiHSM hardware test suite | Validating the product against a real device rather than SoftHSM: an environment-variable-gated (SECSY_YUBIHSM_TESTS=1) six-tier suite covering the SCP03 wire, the on-device key lifecycle across the full algorithm matrix, attestation and its negative cases, the append-only audit log (drain seams, and a full log failing closed), the PKCS#11 layer the product signs through, and a CA/CRL/SSH-CA end-to-end on the hardware — plus what it does to a device, and the findings SoftHSM could not have produced |
↩ Back to the documentation map · project README