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. Exposes CsiIdentity, CsiController, and CsiNode traits for injecting secrets into pods as ephemeral volumes.
  • aws_shim — AWS CloudHSM-shaped API surface (AwsHsmBackend trait).
  • azure_shim — Azure Key Vault-shaped API surface (AzureKeyVaultBackend trait).
  • vault_plugin — HashiCorp Vault Transit-compatible backend (VaultBackend trait): 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

IntegrationAPI versionStatus
Kubernetes CSICSI v1.8+Supported
AWS KMS / CloudHSM shimAWS SDK for RustShim only; no production validation
Azure Key Vault shimAzure SDK for RustShim only; no production validation
HashiCorp Vault shimKV v2, TransitShim 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:

  1. Compile-time Cargo feature: mock-insecure-do-not-ship. The alarming name appears in cargo tree and audit tooling.
  2. Runtime environment variable: CRATON_HSM_ALLOW_MOCK=1. Every mock constructor calls mock_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

FlagDefaultEffect
mock-insecure-do-not-shipoffExpose 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 mode 0700, removes a stale socket.
  • harden_bound_socket(path) — chmods the bound socket to 0600.
  • target_path validation 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.