# 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 ```plaintext ┌─────────────────────────────────────────────────────────┐ │ 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 │ └─────────────────────────────────────────────────────────┘ ```plaintext ## 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 ```bash cd provisioning/platform/kms-service cargo build --release # Binary will be at: target/release/kms-service ```plaintext ## Configuration ### Configuration File Create `provisioning/config/kms.toml`: ```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 ```plaintext ### Environment Variables ```bash # 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" ```plaintext ## Quick Start ### Development Setup (Age) ```bash # 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 ```plaintext ### Production Setup (Cosmian) ```bash # 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 ```plaintext ## Usage ### REST API Examples #### Encrypt Data ```bash curl -X POST http://localhost:8082/api/v1/kms/encrypt \ -H "Content-Type: application/json" \ -d '{ "plaintext": "SGVsbG8sIFdvcmxkIQ==", "context": "env=prod,service=api" }' ```plaintext #### Decrypt Data ```bash curl -X POST http://localhost:8082/api/v1/kms/decrypt \ -H "Content-Type: application/json" \ -d '{ "ciphertext": "...", "context": "env=prod,service=api" }' ```plaintext #### Generate Data Key (Cosmian only) ```bash curl -X POST http://localhost:8082/api/v1/kms/generate-key \ -H "Content-Type: application/json" \ -d '{ "key_spec": "AES_256" }' ```plaintext #### Health Check ```bash curl http://localhost:8082/api/v1/kms/health ```plaintext ### Nushell CLI Integration ```bash # 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" ```plaintext ## 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) ```nushell # 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 ```plaintext ### 2. Dynamic Secrets (Provider API Keys) ```rust // Rust orchestrator can call KMS API let encrypted_key = kms_client.encrypt(api_key.as_bytes(), &context).await?; ```plaintext ### 3. SSH Key Management ```nushell # Generate and encrypt temporal SSH keys ssh-keygen -t ed25519 -f temp_key -N "" kms encrypt-file temp_key --context "infra=prod,purpose=deployment" ```plaintext ### 4. Orchestrator (Workflow Data) ```rust // Encrypt sensitive workflow parameters let encrypted_params = kms_service .encrypt(params_json.as_bytes(), &workflow_context) .await?; ```plaintext ### 5. Control Center (Audit Logs) - All KMS operations are logged - Audit trail for compliance - Integration with control center UI ## Testing ### Unit Tests ```bash cargo test ```plaintext ### Integration Tests ```bash # 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 ```plaintext ## Deployment ### Docker ```dockerfile 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"] ```plaintext ### Kubernetes (Production with Cosmian) ```yaml 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 ```plaintext ### systemd Service ```ini [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 ```plaintext ## 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](../../docs/migration/KMS_SIMPLIFICATION.md) for migration guide. ## Monitoring ### Metrics Endpoints ```bash # Service status (includes operation count) curl http://localhost:8082/api/v1/kms/status # Health check curl http://localhost:8082/api/v1/kms/health ```plaintext ### Logs ```bash # Set log level export RUST_LOG="kms_service=debug,tower_http=debug" # View logs journalctl -u kms-service -f ```plaintext ## Troubleshooting ### Age Backend Issues ```bash # 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 ```plaintext ### Cosmian KMS Issues ```bash # 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="}' ```plaintext ## License Copyright © 2024 Provisioning Team ## References - [Age Encryption](https://github.com/FiloSottile/age) - [Cosmian KMS](https://cosmian.com/kms/) - [Axum Web Framework](https://docs.rs/axum/) - [Confidential Computing](https://confidentialcomputing.io/)