2026-01-14 05:24:19 +00:00

12 KiB

KMS Service - Key Management Service

A unified Key Management Service for the Provisioning platform with support for multiple backends: Age (development), Cosmian KMS (privacy-preserving), RustyVault (self-hosted), AWS KMS (cloud-native), and HashiCorp Vault (enterprise).

Features

Age Backend (Development)

  • Fast, offline encryption/decryption
  • No server required - local key files
  • Simple setup with age-keygen
  • Perfect for development and testing
  • Zero network dependency

RustyVault Backend (Self-hosted) NEW

  • Vault-compatible API (drop-in replacement)
  • Pure Rust implementation
  • Self-hosted secrets management
  • Apache 2.0 license (OSI-approved)
  • Transit secrets engine support
  • Embeddable or standalone
  • No vendor lock-in

Cosmian KMS Backend (Production)

  • Enterprise-grade key management
  • Confidential computing support (SGX/SEV)
  • Zero-knowledge architecture
  • Server-side key rotation
  • Audit logging and compliance
  • Multi-tenant support

Security Features

  • TLS for all communications (Cosmian)
  • Context-based encryption (AAD)
  • Automatic key rotation (Cosmian)
  • Data key generation (Cosmian)
  • Health monitoring
  • Operation metrics

Architecture

┌─────────────────────────────────────────────────
────────┐
│                    KMS Service                          │
├─────────────────────────────────────────────────
────────┤
│  REST API (Axum)                                        │
│  ├─ /api/v1/kms/encrypt       POST                      │
│  ├─ /api/v1/kms/decrypt       POST                      │
│  ├─ /api/v1/kms/generate-key  POST (Cosmian only)       │
│  ├─ /api/v1/kms/status        GET                       │
│  └─ /api/v1/kms/health        GET                       │
├─────────────────────────────────────────────────
────────┤
│  Unified KMS Service Interface                          │
│  ├─ encrypt(plaintext, context) -> ciphertext           │
│  ├─ decrypt(ciphertext, context) -> plaintext           │
│  ├─ generate_data_key(spec) -> DataKey                  │
│  └─ health_check() -> bool                              │
├─────────────────────────────────────────────────
────────┤
│  Backend Implementations                                │
│  ├─ Age Client                                          │
│  │   ├─ X25519 encryption                              │
│  │   ├─ Local key files                                │
│  │   └─ Offline operation                              │
│  └─ Cosmian KMS Client                                  │
│      ├─ REST API integration                           │
│      ├─ Zero-knowledge encryption                      │
│      └─ Confidential computing                         │
└─────────────────────────────────────────────────
────────┘

Installation

Prerequisites

  • Rust 1.70+ (for building)
  • Age 1.2+ (for development backend)
  • Cosmian KMS server (for production backend)
  • Nushell 0.107+ (for CLI integration)

Build from Source

cd provisioning/platform/kms-service
cargo build --release

# Binary will be at: target/release/kms-service

Configuration

Configuration File

Create provisioning/config/kms.toml:

[kms]
dev_backend = "age"
prod_backend = "cosmian"
environment = "${PROVISIONING_ENV:-dev}"

[kms.age]
public_key_path = "~/.config/provisioning/age/public_key.txt"
private_key_path = "~/.config/provisioning/age/private_key.txt"

[kms.cosmian]
server_url = "${COSMIAN_KMS_URL:-https://kms.example.com}"
api_key = "${COSMIAN_API_KEY}"
default_key_id = "provisioning-master-key"
tls_verify = true

Environment Variables

# Development with Age
export PROVISIONING_ENV=dev
# Age keys will be read from paths in config

# Production with Cosmian
export PROVISIONING_ENV=prod
export COSMIAN_KMS_URL="https://kms.example.com"
export COSMIAN_API_KEY="your-api-key"

Quick Start

Development Setup (Age)

# 1. Generate Age keys
mkdir -p ~/.config/provisioning/age
age-keygen -o ~/.config/provisioning/age/private_key.txt
age-keygen -y ~/.config/provisioning/age/private_key.txt > ~/.config/provisioning/age/public_key.txt

# 2. Set environment
export PROVISIONING_ENV=dev

# 3. Start KMS service
cargo run --bin kms-service

Production Setup (Cosmian)

# 1. Set up Cosmian KMS server (or use hosted service)

# 2. Create master key in Cosmian KMS
# (Use Cosmian KMS CLI or web interface)

# 3. Set environment variables
export PROVISIONING_ENV=prod
export COSMIAN_KMS_URL=https://your-kms.example.com
export COSMIAN_API_KEY=your-api-key-here

# 4. Start KMS service
cargo run --bin kms-service

Usage

REST API Examples

Encrypt Data

curl -X POST http://localhost:8082/api/v1/kms/encrypt 
  -H "Content-Type: application/json" 
  -d '{
    "plaintext": "SGVsbG8sIFdvcmxkIQ==",
    "context": "env=prod,service=api"
  }'

Decrypt Data

curl -X POST http://localhost:8082/api/v1/kms/decrypt 
  -H "Content-Type: application/json" 
  -d '{
    "ciphertext": "...",
    "context": "env=prod,service=api"
  }'

Generate Data Key (Cosmian only)

curl -X POST http://localhost:8082/api/v1/kms/generate-key 
  -H "Content-Type: application/json" 
  -d '{
    "key_spec": "AES_256"
  }'

Health Check

curl http://localhost:8082/api/v1/kms/health

Nushell CLI Integration

# Load the KMS module
use provisioning/core/nulib/kms

# Set service URL
export KMS_SERVICE_URL="http://localhost:8082"

# Encrypt data
"secret-data" | kms encrypt
"api-key" | kms encrypt --context "env=prod,service=api"

# Decrypt data
$ciphertext | kms decrypt
$ciphertext | kms decrypt --context "env=prod,service=api"

# Generate data key (Cosmian only)
kms generate-key
kms generate-key --key-spec AES_128

# Check service status
kms status
kms health

# Encrypt/decrypt files
kms encrypt-file config.yaml
kms encrypt-file secrets.json --output secrets.enc --context "env=prod"

kms decrypt-file config.yaml.enc
kms decrypt-file secrets.enc --output secrets.json --context "env=prod"

Backend Comparison

Feature Age RustyVault Cosmian KMS AWS KMS Vault
Setup Simple Self-hosted Server setup AWS account Enterprise
Speed Very fast Fast Fast Fast Fast
Network No Yes Yes Yes Yes
Key Rotation Manual Automatic Automatic Automatic Automatic
Data Keys No Yes Yes Yes Yes
Audit Logging No Yes Full Full Full
Confidential No No Yes (SGX/SEV) No No
Multi-tenant No Yes Yes Yes Yes
License MIT Apache 2.0 Proprietary Proprietary BSL/Enterprise
Cost Free Free Paid Paid Paid
Use Case Dev/Test Self-hosted Privacy AWS Cloud Enterprise

Integration Points

1. Config Encryption (SOPS Integration)

# Encrypt configuration files
kms encrypt-file workspace/config/secrets.yaml

# SOPS can use KMS for key encryption
# Configure in .sops.yaml to use KMS endpoint

2. Dynamic Secrets (Provider API Keys)

// Rust orchestrator can call KMS API
let encrypted_key = kms_client.encrypt(api_key.as_bytes(), &context).await?;

3. SSH Key Management

# Generate and encrypt temporal SSH keys
ssh-keygen -t ed25519 -f temp_key -N ""
kms encrypt-file temp_key --context "infra=prod,purpose=deployment"

4. Orchestrator (Workflow Data)

// Encrypt sensitive workflow parameters
let encrypted_params = kms_service
    .encrypt(params_json.as_bytes(), &workflow_context)
    .await?;

5. Control Center (Audit Logs)

  • All KMS operations are logged
  • Audit trail for compliance
  • Integration with control center UI

Testing

Unit Tests

cargo test

Integration Tests

# Age backend tests (no external dependencies)
cargo test age

# Cosmian backend tests (requires Cosmian KMS server)
export COSMIAN_KMS_URL=http://localhost:9999
export COSMIAN_API_KEY=test-key
cargo test cosmian -- --ignored

Deployment

Docker

FROM rust:1.70 as builder
WORKDIR /app
COPY . .
RUN cargo build --release

FROM debian:bookworm-slim
RUN apt-get update && 
    apt-get install -y ca-certificates && 
    rm -rf /var/lib/apt/lists/*
COPY --from=builder /app/target/release/kms-service /usr/local/bin/
ENTRYPOINT ["kms-service"]

Kubernetes (Production with Cosmian)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: kms-service
spec:
  replicas: 2
  template:
    spec:
      containers:
      - name: kms-service
        image: provisioning/kms-service:latest
        env:
        - name: PROVISIONING_ENV
          value: "prod"
        - name: COSMIAN_KMS_URL
          value: "https://kms.example.com"
        - name: COSMIAN_API_KEY
          valueFrom:
            secretKeyRef:
              name: cosmian-api-key
              key: api-key
        ports:
        - containerPort: 8082

systemd Service

[Unit]
Description=KMS Service
After=network.target

[Service]
Type=simple
User=kms-service
Environment="PROVISIONING_ENV=prod"
Environment="COSMIAN_KMS_URL=https://kms.example.com"
Environment="COSMIAN_API_KEY=your-api-key"
ExecStart=/usr/local/bin/kms-service
Restart=always

[Install]
WantedBy=multi-user.target

Security Best Practices

  1. Development: Use Age for dev/test only, never for production secrets
  2. Production: Always use Cosmian KMS with TLS verification enabled
  3. API Keys: Never hardcode Cosmian API keys, use environment variables
  4. Key Rotation: Enable automatic rotation in Cosmian (90 days recommended)
  5. Context Encryption: Always use encryption context (AAD) for additional security
  6. Network Access: Restrict KMS service access with firewall rules
  7. Monitoring: Enable health checks and monitor operation metrics

Migration from Vault/AWS KMS

See KMS_SIMPLIFICATION.md for migration guide.

Monitoring

Metrics Endpoints

# Service status (includes operation count)
curl http://localhost:8082/api/v1/kms/status

# Health check
curl http://localhost:8082/api/v1/kms/health

Logs

# Set log level
export RUST_LOG="kms_service=debug,tower_http=debug"

# View logs
journalctl -u kms-service -f

Troubleshooting

Age Backend Issues

# Check keys exist
ls -la ~/.config/provisioning/age/

# Verify key format
cat ~/.config/provisioning/age/public_key.txt
# Should start with: age1...

# Test encryption manually
echo "test" | age -r $(cat ~/.config/provisioning/age/public_key.txt) > test.enc
age -d -i ~/.config/provisioning/age/private_key.txt test.enc

Cosmian KMS Issues

# Check connectivity
curl https://kms.example.com/api/v1/health 
  -H "X-API-Key: $COSMIAN_API_KEY"

# Verify API key
curl https://kms.example.com/api/v1/version 
  -H "X-API-Key: $COSMIAN_API_KEY"

# Test encryption
curl -X POST https://kms.example.com/api/v1/encrypt 
  -H "X-API-Key: $COSMIAN_API_KEY" 
  -H "Content-Type: application/json" 
  -d '{"keyId":"master-key","data":"SGVsbG8="}'

License

Copyright © 2024 Provisioning Team

References