Craton HSM
Cloud Integrations
Cloud Integrations
The craton-hsm-cloud crate ships reference implementations for exposing
Craton HSM through cloud-native interfaces. It is reference
scaffolding: the in-tree implementations are in-memory mocks. Production
deployments re-implement the public traits against a real Craton HSM
backend and a real transport layer.
- Crate:
craton-hsm-cloud - License: BSL 1.1
- MSRV: Rust 1.75
- Safety:
#![deny(unsafe_code)],#![deny(missing_docs)]. - Status: reference / mock (not production-ready as shipped).
What It Provides
k8s_csi— Kubernetes CSI (Container Storage Interface) driver hooks. ExposesCsiIdentity,CsiController, andCsiNodetraits for injecting secrets into pods as ephemeral volumes.aws_shim— AWS CloudHSM-shaped API surface (AwsHsmBackendtrait).azure_shim— Azure Key Vault-shaped API surface (AzureKeyVaultBackendtrait).vault_plugin— HashiCorp Vault Transit-compatible backend (VaultBackendtrait): encrypt, decrypt, sign, verify, key management.
The crate itself has no cloud-SDK dependencies. Real integrations layer cloud SDKs on top in a consuming binary crate.
Production vs. Reference Status
| Integration | API version | Status |
|---|---|---|
| Kubernetes CSI | CSI v1.8+ | Supported |
| AWS KMS / CloudHSM shim | AWS SDK for Rust | Shim only; no production validation |
| Azure Key Vault shim | Azure SDK for Rust | Shim only; no production validation |
| HashiCorp Vault shim | KV v2, Transit | Shim only; no production validation |
The shipped crypto in mocks is not real crypto. The mock backends use HMAC-SHA256 over per-key random material plus an XOR stream "encrypt" that is unforgeable but is not confidentiality-preserving under any adversary with access to ciphertext pairs and is not authenticated encryption. They exist to exercise API shape and wire-format plumbing only.
Double Opt-In for Mocks
Two independent checks gate mock instantiation so a mock cannot ship by accident:
- Compile-time Cargo feature:
mock-insecure-do-not-ship. The alarming name appears incargo treeand audit tooling. - Runtime environment variable:
CRATON_HSM_ALLOW_MOCK=1. Every mock constructor callsmock_guard::check, which panics with a diagnostic if the variable is not set.
A production binary accidentally compiled with the feature still refuses to instantiate a mock at runtime.
// Tests / local development only.
// cargo ... --features mock-insecure-do-not-ship
// CRATON_HSM_ALLOW_MOCK=1
#[cfg(feature = "mock-insecure-do-not-ship")]
{
use craton_hsm_cloud::vault_plugin::MockVaultBackend;
std::env::set_var("CRATON_HSM_ALLOW_MOCK", "1");
let backend = MockVaultBackend::new();
// ... exercise Vault-transit API shape ...
}
Feature Flag
| Flag | Default | Effect |
|---|---|---|
mock-insecure-do-not-ship | off | Expose the insecure in-memory mock backends. Additionally requires CRATON_HSM_ALLOW_MOCK=1 at runtime. |
CSI Driver Helpers
The CSI module ships socket-hardening helpers so endpoints do not leak via world-writable sockets:
prepare_csi_socket_dir(endpoint)— parent directory mode0700, removes a stale socket.harden_bound_socket(path)— chmods the bound socket to0600.target_pathvalidation rejects traversal (..) and symlink escape.
Configuration Snippets
Kubernetes CSI driver
Deploy the driver as a DaemonSet. The driver socket must live on a
host-path volume; CSI sidecars (node-driver-registrar,
external-provisioner) talk to it over the UDS.
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: craton-hsm-csi
namespace: craton-hsm
spec:
selector:
matchLabels:
app: craton-hsm-csi
template:
metadata:
labels:
app: craton-hsm-csi
spec:
serviceAccountName: craton-hsm-csi
containers:
- name: craton-hsm-csi
image: ghcr.io/craton-inc/craton-hsm-csi:0.1.1
args:
- --endpoint=unix:///csi/csi.sock
- --node-id=$(NODE_NAME)
- --hsm-endpoint=https://cratond.craton-hsm.svc:443
env:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
volumeMounts:
- name: socket-dir
mountPath: /csi
- name: mountpoint-dir
mountPath: /var/lib/kubelet/pods
mountPropagation: Bidirectional
volumes:
- name: socket-dir
hostPath:
path: /var/lib/kubelet/plugins/hsm.craton.io
type: DirectoryOrCreate
- name: mountpoint-dir
hostPath:
path: /var/lib/kubelet/pods
type: DirectoryOrCreate
Reference the driver from a PVC via a StorageClass whose provisioner
is hsm.craton.io.
HashiCorp Vault Transit shim
Implement VaultBackend against a real Craton HSM client and register
it with a Vault HTTP framework. Sketch:
use craton_hsm_cloud::vault_plugin::VaultBackend;
use std::sync::Arc;
struct CratonVaultBackend { /* client, config */ }
impl VaultBackend for CratonVaultBackend {
fn encrypt(&self, key: &str, plaintext: &[u8]) -> Result<Vec<u8>, _> {
// dispatch to craton-hsm
todo!()
}
// ... decrypt, sign, verify, key management
}
fn serve(backend: Arc<dyn VaultBackend>) {
// wire into your HTTP framework
}
AWS KMS / CloudHSM shim
use craton_hsm_cloud::aws_shim::AwsHsmBackend;
struct CratonAwsBackend { /* ... */ }
impl AwsHsmBackend for CratonAwsBackend {
// implement the KMS / CloudHSM-shaped surface your clients use
}
Azure Key Vault shim
use craton_hsm_cloud::azure_shim::AzureKeyVaultBackend;
struct CratonAzureBackend { /* ... */ }
impl AzureKeyVaultBackend for CratonAzureBackend {
// REST-shaped encrypt/decrypt/sign/verify/key-management
}
Limitations
- The shipped crypto in mocks is not real crypto. See above.
- No network transport is included. AWS CloudHSM speaks a custom TLS protocol, Azure Key Vault speaks REST, Vault speaks HTTP, and K8s CSI speaks gRPC over UDS. Implementing those servers is the operator's responsibility.
- Real cloud integrations require operator work. This crate is a starting point, not a turnkey product.
Related Documents
- Authentication and RBAC — identity for gRPC / HTTP front ends.
- KMIP server — an alternative to cloud-shaped surfaces for clients that already speak KMIP.