Configuration Encryption Guide
Version: 1.0.0 Last Updated: 2025-10-08 Status: Production Ready
Overview
The Provisioning Platform includes a comprehensive configuration encryption system that provides:
- Transparent Encryption/Decryption: Configs are automatically decrypted on load
- Multiple KMS Backends: Age, AWS KMS, HashiCorp Vault, Cosmian KMS
- Memory-Only Decryption: Secrets never written to disk in plaintext
- SOPS Integration: Industry-standard encryption with SOPS
- Sensitive Data Detection: Automatic scanning for unencrypted sensitive data
Table of Contents
- Prerequisites
- Quick Start
- Configuration Encryption
- KMS Backends
- CLI Commands
- Integration with Config Loader
- Best Practices
- Troubleshooting
Prerequisites
Required Tools
-
SOPS (v3.10.2+)
# macOS brew install sops # Linux wget https://github.com/mozilla/sops/releases/download/v3.10.2/sops-v3.10.2.linux.amd64 sudo mv sops-v3.10.2.linux.amd64 /usr/local/bin/sops sudo chmod +x /usr/local/bin/sops -
Age (for Age backend - recommended)
# macOS brew install age # Linux apt install age -
AWS CLI (for AWS KMS backend - optional)
brew install awscli
Verify Installation
# Check SOPS
sops --version
# Check Age
age --version
# Check AWS CLI (optional)
aws --version
Quick Start
1. Initialize Encryption
Generate Age keys and create SOPS configuration:
provisioning config init-encryption --kms age
This will:
- Generate Age key pair in
~/.config/sops/age/keys.txt - Display your public key (recipient)
- Create
.sops.yamlin your project
2. Set Environment Variables
Add to your shell profile (~/.zshrc or ~/.bashrc):
# Age encryption
export SOPS_AGE_RECIPIENTS="age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p"
export PROVISIONING_KAGE="$HOME/.config/sops/age/keys.txt"
Replace the recipient with your actual public key.
3. Validate Setup
provisioning config validate-encryption
Expected output:
✅ Encryption configuration is valid
SOPS installed: true
Age backend: true
KMS enabled: false
Errors: 0
Warnings: 0
4. Encrypt Your First Config
# Create a config with sensitive data
cat > workspace/config/secure.yaml <<EOF
database:
host: localhost
password: supersecret123
api_key: key_abc123
EOF
# Encrypt it
provisioning config encrypt workspace/config/secure.yaml --in-place
# Verify it's encrypted
provisioning config is-encrypted workspace/config/secure.yaml
Configuration Encryption
File Naming Conventions
Encrypted files should follow these patterns:
*.enc.yaml- Encrypted YAML files*.enc.yml- Encrypted YAML files (alternative)*.enc.toml- Encrypted TOML filessecure.yaml- Files in workspace/config/
The .sops.yaml configuration automatically applies encryption rules based on file paths.
Encrypt a Configuration File
Basic Encryption
# Encrypt and create new file
provisioning config encrypt secrets.yaml
# Output: secrets.yaml.enc
In-Place Encryption
# Encrypt and replace original
provisioning config encrypt secrets.yaml --in-place
Specify Output Path
# Encrypt to specific location
provisioning config encrypt secrets.yaml --output workspace/config/secure.enc.yaml
Choose KMS Backend
# Use Age (default)
provisioning config encrypt secrets.yaml --kms age
# Use AWS KMS
provisioning config encrypt secrets.yaml --kms aws-kms
# Use Vault
provisioning config encrypt secrets.yaml --kms vault
Decrypt a Configuration File
# Decrypt to new file
provisioning config decrypt secrets.enc.yaml
# Decrypt in-place
provisioning config decrypt secrets.enc.yaml --in-place
# Decrypt to specific location
provisioning config decrypt secrets.enc.yaml --output plaintext.yaml
Edit Encrypted Files
The system provides a secure editing workflow:
# Edit encrypted file (auto decrypt -> edit -> re-encrypt)
provisioning config edit-secure workspace/config/secure.enc.yaml
This will:
- Decrypt the file temporarily
- Open in your
$EDITOR(vim/nano/etc) - Re-encrypt when you save and close
- Remove temporary decrypted file
Check Encryption Status
# Check if file is encrypted
provisioning config is-encrypted workspace/config/secure.yaml
# Get detailed encryption info
provisioning config encryption-info workspace/config/secure.yaml
KMS Backends
Age (Recommended for Development)
Pros:
- Simple file-based keys
- No external dependencies
- Fast and secure
- Works offline
Setup:
# Initialize
provisioning config init-encryption --kms age
# Set environment variables
export SOPS_AGE_RECIPIENTS="age1..." # Your public key
export PROVISIONING_KAGE="$HOME/.config/sops/age/keys.txt"
Encrypt/Decrypt:
provisioning config encrypt secrets.yaml --kms age
provisioning config decrypt secrets.enc.yaml
AWS KMS (Production)
Pros:
- Centralized key management
- Audit logging
- IAM integration
- Key rotation
Setup:
- Create KMS key in AWS Console
- Configure AWS credentials:
aws configure - Update
.sops.yaml:creation_rules: - path_regex: .*\.enc\.yaml$ kms: "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012"
Encrypt/Decrypt:
provisioning config encrypt secrets.yaml --kms aws-kms
provisioning config decrypt secrets.enc.yaml
HashiCorp Vault (Enterprise)
Pros:
- Dynamic secrets
- Centralized secret management
- Audit logging
- Policy-based access
Setup:
-
Configure Vault address and token:
export VAULT_ADDR="https://vault.example.com:8200" export VAULT_TOKEN="s.xxxxxxxxxxxxxx" -
Update configuration:
# workspace/config/provisioning.yaml kms: enabled: true mode: "remote" vault: address: "https://vault.example.com:8200" transit_key: "provisioning"
Encrypt/Decrypt:
provisioning config encrypt secrets.yaml --kms vault
provisioning config decrypt secrets.enc.yaml
Cosmian KMS (Confidential Computing)
Pros:
- Confidential computing support
- Zero-knowledge architecture
- Post-quantum ready
- Cloud-agnostic
Setup:
- Deploy Cosmian KMS server
- Update configuration:
kms: enabled: true mode: "remote" remote: endpoint: "https://kms.example.com:9998" auth_method: "certificate" client_cert: "/path/to/client.crt" client_key: "/path/to/client.key"
Encrypt/Decrypt:
provisioning config encrypt secrets.yaml --kms cosmian
provisioning config decrypt secrets.enc.yaml
CLI Commands
Configuration Encryption Commands
| Command | Description |
|---|---|
config encrypt <file> | Encrypt configuration file |
config decrypt <file> | Decrypt configuration file |
config edit-secure <file> | Edit encrypted file securely |
config rotate-keys <file> <key> | Rotate encryption keys |
config is-encrypted <file> | Check if file is encrypted |
config encryption-info <file> | Show encryption details |
config validate-encryption | Validate encryption setup |
config scan-sensitive <dir> | Find unencrypted sensitive configs |
config encrypt-all <dir> | Encrypt all sensitive configs |
config init-encryption | Initialize encryption (generate keys) |
Examples
# Encrypt workspace config
provisioning config encrypt workspace/config/secure.yaml --in-place
# Edit encrypted file
provisioning config edit-secure workspace/config/secure.yaml
# Scan for unencrypted sensitive configs
provisioning config scan-sensitive workspace/config --recursive
# Encrypt all sensitive configs in workspace
provisioning config encrypt-all workspace/config --kms age --recursive
# Check encryption status
provisioning config is-encrypted workspace/config/secure.yaml
# Get detailed info
provisioning config encryption-info workspace/config/secure.yaml
# Validate setup
provisioning config validate-encryption
Integration with Config Loader
Automatic Decryption
The config loader automatically detects and decrypts encrypted files:
# Load encrypted config (automatically decrypted in memory)
use lib_provisioning/config/loader.nu
let config = (load-provisioning-config --debug)
Key Features:
- Transparent: No code changes needed
- Memory-Only: Decrypted content never written to disk
- Fallback: If decryption fails, attempts to load as plain file
- Debug Support: Shows decryption status with
--debugflag
Manual Loading
use lib_provisioning/config/encryption.nu
# Load encrypted config
let secure_config = (load-encrypted-config "workspace/config/secure.enc.yaml")
# Memory-only decryption (no file created)
let decrypted_content = (decrypt-config-memory "workspace/config/secure.enc.yaml")
Configuration Hierarchy with Encryption
The system supports encrypted files at any level:
1. workspace/{name}/config/provisioning.yaml ← Can be encrypted
2. workspace/{name}/config/providers/*.toml ← Can be encrypted
3. workspace/{name}/config/platform/*.toml ← Can be encrypted
4. ~/.../provisioning/ws_{name}.yaml ← Can be encrypted
5. Environment variables (PROVISIONING_*) ← Plain text
Best Practices
1. Encrypt All Sensitive Data
Always encrypt configs containing:
- Passwords
- API keys
- Secret keys
- Private keys
- Tokens
- Credentials
Scan for unencrypted sensitive data:
provisioning config scan-sensitive workspace --recursive
2. Use Appropriate KMS Backend
| Environment | Recommended Backend |
|---|---|
| Development | Age (file-based) |
| Staging | AWS KMS or Vault |
| Production | AWS KMS or Vault |
| CI/CD | AWS KMS with IAM roles |
3. Key Management
Age Keys:
- Store private keys securely:
~/.config/sops/age/keys.txt - Set file permissions:
chmod 600 ~/.config/sops/age/keys.txt - Backup keys securely (encrypted backup)
- Never commit private keys to git
AWS KMS:
- Use separate keys per environment
- Enable key rotation
- Use IAM policies for access control
- Monitor usage with CloudTrail
Vault:
- Use transit engine for encryption
- Enable audit logging
- Implement least-privilege policies
- Regular policy reviews
4. File Organization
workspace/
└── config/
├── provisioning.yaml # Plain (no secrets)
├── secure.yaml # Encrypted (SOPS auto-detects)
├── providers/
│ ├── aws.toml # Plain (no secrets)
│ └── aws-credentials.enc.toml # Encrypted
└── platform/
└── database.enc.yaml # Encrypted
5. Git Integration
Add to .gitignore:
# Unencrypted sensitive files
**/secrets.yaml
**/credentials.yaml
**/*.dec.yaml
**/*.dec.toml
# Temporary decrypted files
*.tmp.yaml
*.tmp.toml
Commit encrypted files:
# Encrypted files are safe to commit
git add workspace/config/secure.enc.yaml
git commit -m "Add encrypted configuration"
6. Rotation Strategy
Regular Key Rotation:
# Generate new Age key
age-keygen -o ~/.config/sops/age/keys-new.txt
# Update .sops.yaml with new recipient
# Rotate keys for file
provisioning config rotate-keys workspace/config/secure.yaml <new-key-id>
Frequency:
- Development: Annually
- Production: Quarterly
- After team member departure: Immediately
7. Audit and Monitoring
Track encryption status:
# Regular scans
provisioning config scan-sensitive workspace --recursive
# Validate encryption setup
provisioning config validate-encryption
Monitor access (with Vault/AWS KMS):
- Enable audit logging
- Review access patterns
- Alert on anomalies
Troubleshooting
SOPS Not Found
Error:
SOPS binary not found
Solution:
# Install SOPS
brew install sops
# Verify
sops --version
Age Key Not Found
Error:
Age key file not found: ~/.config/sops/age/keys.txt
Solution:
# Generate new key
mkdir -p ~/.config/sops/age
age-keygen -o ~/.config/sops/age/keys.txt
# Set environment variable
export PROVISIONING_KAGE="$HOME/.config/sops/age/keys.txt"
SOPS_AGE_RECIPIENTS Not Set
Error:
no AGE_RECIPIENTS for file.yaml
Solution:
# Extract public key from private key
grep "public key:" ~/.config/sops/age/keys.txt
# Set environment variable
export SOPS_AGE_RECIPIENTS="age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p"
Decryption Failed
Error:
Failed to decrypt configuration file
Solutions:
-
Wrong key:
# Verify you have the correct private key provisioning config validate-encryption -
File corrupted:
# Check file integrity sops --decrypt workspace/config/secure.yaml -
Wrong backend:
# Check SOPS metadata in file head -20 workspace/config/secure.yaml
AWS KMS Access Denied
Error:
AccessDeniedException: User is not authorized to perform: kms:Decrypt
Solution:
# Check AWS credentials
aws sts get-caller-identity
# Verify KMS key policy allows your IAM user/role
aws kms describe-key --key-id <key-arn>
Vault Connection Failed
Error:
Vault encryption failed: connection refused
Solution:
# Verify Vault address
echo $VAULT_ADDR
# Check connectivity
curl -k $VAULT_ADDR/v1/sys/health
# Verify token
vault token lookup
Security Considerations
Threat Model
Protected Against:
- ✅ Plaintext secrets in git
- ✅ Accidental secret exposure
- ✅ Unauthorized file access
- ✅ Key compromise (with rotation)
Not Protected Against:
- ❌ Memory dumps during decryption
- ❌ Root/admin access to running process
- ❌ Compromised Age/KMS keys
- ❌ Social engineering
Security Best Practices
- Principle of Least Privilege: Only grant decryption access to those who need it
- Key Separation: Use different keys for different environments
- Regular Audits: Review who has access to keys
- Secure Key Storage: Never store private keys in git
- Rotation: Regularly rotate encryption keys
- Monitoring: Monitor decryption operations (with AWS KMS/Vault)
Additional Resources
- SOPS Documentation: https://github.com/mozilla/sops
- Age Encryption: https://age-encryption.org/
- AWS KMS: https://aws.amazon.com/kms/
- HashiCorp Vault: https://www.vaultproject.io/
- Cosmian KMS: https://www.cosmian.com/
Support
For issues or questions:
- Check troubleshooting section above
- Run:
provisioning config validate-encryption - Review logs with
--debugflag
Last Updated: 2025-10-08 Version: 1.0.0