Craton HSM

Deployment Hardening

Deployment Hardening

The Craton HSM codebase implements the in-boundary defences described in model. The operator is responsible for the out-of-boundary controls: file permissions, process isolation, kernel security modules, network exposure, TLS identity, and host entropy. This page lists the controls we expect an operator to put in place for a production deployment, and the commands and configuration fragments needed to apply them.

File System Permissions

PathOwnerModeNotes
/opt/craton-hsm/lib/libcraton_hsm.soroot:craton0555Library is read-execute only; no write bit for the service account
/opt/craton-hsm/lib/libcraton_hsm.hmacroot:craton0444Integrity sidecar must match the library exactly
/etc/craton-hsm/craton_hsm.tomlroot:craton0640Config readable by the service account only
/var/lib/craton-hsm/craton:craton0700Persistent state directory
/var/lib/craton-hsm/state.redbcraton:craton0600Encrypted object store; only the service account reads or writes
/var/log/craton-hsm/audit.logcraton:craton0640Append-only; log rotation runs as the same account
/etc/craton-hsm/tls/root:craton0750TLS key and certificate material

The service account (craton in the examples) must not have shell access and should own nothing outside these paths. Mount /var/lib/craton-hsm on an encrypted volume (LUKS on Linux, BitLocker on Windows) and with nosuid,nodev options.

systemd Sandboxing (Linux)

The gRPC daemon should run under a unit file with the following sandboxing directives:

[Unit]
Description=Craton HSM daemon
After=network-online.target
Wants=network-online.target

[Service]
ExecStart=/opt/craton-hsm/bin/craton-hsm-daemon --config /etc/craton-hsm/craton_hsm.toml
User=craton
Group=craton
Type=notify
Restart=on-failure

# Filesystem isolation
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/craton-hsm /var/log/craton-hsm
PrivateTmp=true
PrivateDevices=true

# Namespace / kernel surface
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectKernelLogs=true
ProtectControlGroups=true
ProtectClock=true
ProtectHostname=true
ProtectProc=invisible

# Memory and capabilities
MemoryDenyWriteExecute=true
NoNewPrivileges=true
CapabilityBoundingSet=CAP_IPC_LOCK
AmbientCapabilities=CAP_IPC_LOCK
LockPersonality=true
RestrictNamespaces=true
RestrictRealtime=true
RestrictSUIDSGID=true

# Networking
IPAddressAllow=10.0.0.0/8
IPAddressDeny=any
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX

# No core dumps
LimitCORE=0

[Install]
WantedBy=multi-user.target

CAP_IPC_LOCK is required for mlock on large key material. Without it the module logs a warning and continues without memory locking, which is acceptable for development but not for production.

seccomp

Craton HSM does not ship a hand-tuned seccomp profile because the surface depends on the chosen backend and the Rust allocator's syscalls. Use systemd's SystemCallFilter= with the @system-service set minus @privileged and @resources:

SystemCallFilter=@system-service
SystemCallFilter=~@privileged @resources
SystemCallArchitectures=native

For a stricter deployment, produce an allow-list by running the daemon under systemd-run --property=SystemCallLog= in staging and promoting the observed set.

AppArmor / SELinux

On distributions with AppArmor, create a profile that restricts the daemon to the paths listed above and forbids execution of arbitrary binaries. A starter profile:

#include <tunables/global>

/opt/craton-hsm/bin/craton-hsm-daemon {
  #include <abstractions/base>
  #include <abstractions/nameservice>
  #include <abstractions/openssl>

  capability ipc_lock,

  /opt/craton-hsm/bin/craton-hsm-daemon mr,
  /opt/craton-hsm/lib/libcraton_hsm.so mr,
  /opt/craton-hsm/lib/libcraton_hsm.hmac r,
  /etc/craton-hsm/** r,
  /var/lib/craton-hsm/** rwk,
  /var/log/craton-hsm/** rw,

  deny /proc/sys/** w,
  deny /sys/** w,
  deny /boot/** r,
  deny /root/** r,
  deny /home/** r,

  network tcp,
}

On SELinux systems, confine the daemon with a dedicated type (for example craton_hsm_t) and label the data directories accordingly. Do not run the daemon under unconfined_t.

Network Exposure

The PKCS#11 C ABI has no network surface; only the gRPC daemon does.

  • Bind the daemon to an internal address. Do not publish it on the public internet. Example: listen_addr = "10.0.1.10:8443".
  • Require mutual TLS. Reject connections without a client certificate.
  • Maintain a short allow-list of client certificate fingerprints, or require the client certificate to chain to a private CA dedicated to HSM clients.
  • Firewall the listen port to the application tier. Use IPAddressAllow= in the systemd unit and an iptables/nftables rule as defence in depth.
  • If the cluster feature is enabled, keep the cluster port on a separate VLAN with its own mTLS identity.
PortProtocolSourcePurpose
8443TCPApplication tier onlyPKCS#11 API over gRPC
9443TCPCluster peers onlyRaft consensus (enterprise)
5696TCPKMIP clients onlyKMIP protocol (enterprise)

TLS Configuration

  • TLS 1.2 as a minimum; TLS 1.3 preferred.
  • Disable every cipher suite outside the TLS 1.3 defaults and the TLS 1.2 AEAD suites (ECDHE-ECDSA-AES-GCM, ECDHE-RSA-AES-GCM, ECDHE-ECDSA-CHACHA20-POLY1305).
  • Require ALPN set to h2 for the gRPC listener.
  • Pin the CA trust store for client certificates. Do not trust the system roots on the HSM host.
  • Verify client certificate revocation with CRLs refreshed at least daily; fail closed when no fresh CRL covers the issuer.

Certificate Rotation

Server and client certificates should rotate on a published schedule. Recommended:

  1. Issue new certificates at least 30 days before the current ones expire.
  2. Deploy the new server certificate alongside the old one (dual-bind) and keep both valid for the overlap.
  3. Reload the daemon (systemctl reload craton-hsm) — the daemon picks up the new material without dropping existing connections.
  4. After the overlap, remove the old material and revoke the old certificate.
  5. Verify revocation propagation by attempting a connection with the old certificate; it must be rejected.

Automate issuance with the internal CA of your choice; rotate the TLS private key on every issuance (never reuse key material across certificate generations).

Host Entropy

Craton HSM seeds its HMAC_DRBG from the OS CSPRNG. The operator is responsible for ensuring the OS entropy source is healthy before the daemon starts:

  • Linuxgetrandom(2) blocks until the entropy pool is initialised. On bare metal this is instant; on VMs that boot without a virtio-rng device, this can take minutes. Always attach virtio-rng to VMs that run the daemon.
  • WindowsBCryptGenRandom uses the system CNG provider. Ensure the system has been initialised before starting the service; on Windows Server 2022 this is handled by the platform.
  • Containers — mount /dev/urandom / /dev/random from the host; do not run with --cap-drop=ALL without restoring CAP_IPC_LOCK and read access to the entropy device.

The module's continuous RNG health test catches stuck outputs but not bias. If C_GenerateRandom fails with CKR_FUNCTION_FAILED, audit the entropy source before restarting.

Process Hardening

  • Disable core dumps: LimitCORE=0 in the unit file, ulimit -c 0 for interactive shells. A core dump of the daemon leaks live key material.
  • Disable ptrace attach for the service account via yama.ptrace_scope (set to 3 for a fully locked-down host).
  • Mount /tmp and /var/tmp with noexec,nosuid.
  • Set vm.swappiness=1 or disable swap entirely. Key material is mlocked, but unrelated allocations may still end up swapped.
  • Keep the host kernel patched, especially for speculative-execution vulnerabilities; the module relies on the kernel's mitigations.

Monitoring and Alerting

Forward the audit log to a SIEM. Alert on:

  • Any POST failure or integrity mismatch.
  • Repeated PIN failures approaching the lockout threshold.
  • AES-GCM nonce counter warnings at 90% and above.
  • Any fips_approved: false entry in a deployment that is supposed to be FIPS-only.
  • Cluster leadership churn (enterprise).
  • TLS handshake failures at the daemon.

Deployment Checklist

  • Dedicated service account, no shell, owns only the HSM paths.
  • Config, state, and log directories with the permissions above.
  • systemd unit with the sandboxing directives from this page.
  • AppArmor or SELinux profile in enforcing mode.
  • TLS 1.2+, mutual authentication, CRL refreshed daily, alerting on handshake failures.
  • Firewall rules matching the recommended ports.
  • virtio-rng attached on VMs; entropy source verified before start.
  • Audit log forwarded to SIEM; chain verification scheduled daily.
  • Integrity sidecar regenerated on every binary update and integrity-verified before deploy.
  • Disaster recovery runbook tested: restore from encrypted backup into a fresh host.

Further Reading