Platform restructured into crates/, added AI service and detector,
migrated control-center-ui to Leptos 0.8
462 lines
12 KiB
Markdown
462 lines
12 KiB
Markdown
# 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/)
|