Jesús Pérez 09a97ac8f5
chore: update platform submodule to monorepo crates structure
Platform restructured into crates/, added AI service and detector,
       migrated control-center-ui to Leptos 0.8
2026-01-08 21:32:59 +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                         │
└─────────────────────────────────────────────────────────┘
```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/)