2025-07-11 20:53:20 +01:00
# Configuration Encryption System
This document describes the configuration encryption system that allows you to securely store sensitive configuration values using AES-256-GCM encryption.
## Overview
The configuration encryption system provides:
- **AES-256-GCM encryption** for sensitive configuration values
- **Automatic key generation** and management via `.k` file
- **Simple syntax** - encrypted values start with `@`
- **Automatic decryption** during configuration loading
- **CLI tools** for managing encrypted values
- **Environment variable support** alongside encryption
## How It Works
1. **Key Storage** : A 256-bit encryption key is stored in a `.k` file in your project root
2. **Value Encryption** : Sensitive values are encrypted and prefixed with `@`
3. **Automatic Decryption** : During config loading, `@` prefixed values are automatically decrypted
4. **Fallback Support** : You can still use environment variables alongside encrypted values
## Quick Start
### 1. Generate Encryption Key
```bash
# Generate a new encryption key
cargo run --bin config_crypto_tool generate-key
# Or use the interactive mode
cargo run --bin config_crypto_tool interactive
```
This creates a `.k` file in your project root containing a base64-encoded 256-bit encryption key.
### 2. Encrypt Sensitive Values
```bash
# Encrypt a database password
cargo run --bin config_crypto_tool encrypt "my_secret_password"
# Output: @AbCdEf123456...
# Encrypt an API key
cargo run --bin config_crypto_tool encrypt "sk-1234567890abcdef"
# Output: @XyZ789AbCdEf...
```
### 3. Use in Configuration
```toml
# config.prod.toml
[database]
url = "postgresql://user:@AbCdEf123456 ...@localhost:5432/mydb "
[session]
secret = "@XyZ789AbCdEf ..."
[oauth.google]
client_secret = "@GhI012JkLmNo ..."
[email]
sendgrid_api_key = "@PqR345StUvWx ..."
```
### 4. Verify Configuration
```bash
# Verify encryption key works
cargo run --bin config_crypto_tool verify
# Show decrypted values (for debugging)
cargo run --bin config_crypto_tool show-decrypted -c config.prod.toml
```
## Security Features
### Key Management
- **Automatic Generation**: Keys are generated using cryptographically secure random number generation
- **File Permissions**: Key files are created with restrictive permissions (0600 on Unix systems)
- **Key Rotation**: Support for safely rotating encryption keys
- **Backup Support**: Automatic backup during key rotation
### Encryption Details
- **Algorithm**: AES-256-GCM (Galois/Counter Mode)
- **Key Size**: 256 bits (32 bytes)
- **Nonce**: 96 bits (12 bytes), randomly generated for each encryption
- **Authentication**: Built-in authentication and integrity verification
- **Encoding**: Base64 encoding for text representation
### Security Best Practices
1. **Keep `.k` file secure** : Never commit to version control
2. **Backup encryption keys** : Store backups in secure location
3. **Use proper file permissions** : Ensure only authorized users can read the key
4. **Regular key rotation** : Rotate keys periodically in production
5. **Environment separation** : Use different keys for different environments
## Configuration Integration
### Automatic Decryption
The configuration system automatically decrypts values during loading:
```rust
use server::config::Config;
#[tokio::main]
async fn main() -> Result< (), Box< dyn std::error::Error > > {
// Load configuration - encrypted values are automatically decrypted
let config = Config::load()?;
// These values are now decrypted and ready to use
println!("Database URL: {}", config.database.url);
println!("Session secret: {}", config.session.secret);
Ok(())
}
```
### Mixed Approach
You can combine encrypted values with environment variables:
```toml
# config.prod.toml
[database]
url = "${DATABASE_URL}" # Environment variable
[session]
secret = "@encrypted_session_secret " # Encrypted value
[oauth.google]
client_id = "${GOOGLE_CLIENT_ID}" # Environment variable
client_secret = "@encrypted_google_secret " # Encrypted value
```
### Precedence Order
1. **Environment variables** (highest priority)
2. **Encrypted values** (decrypted during loading)
3. **Plain text values** (lowest priority)
## CLI Tools
### config_crypto_tool
The main CLI tool for managing encrypted configuration values:
```bash
# Basic commands
cargo run --bin config_crypto_tool generate-key # Generate new key
cargo run --bin config_crypto_tool encrypt "value" # Encrypt a value
cargo run --bin config_crypto_tool decrypt "@..." # Decrypt a value
cargo run --bin config_crypto_tool verify # Verify key works
# Key management
cargo run --bin config_crypto_tool key-info # Show key information
cargo run --bin config_crypto_tool rotate-key --confirm # Rotate key
# Configuration file operations
cargo run --bin config_crypto_tool find-encrypted -c config.toml
cargo run --bin config_crypto_tool show-decrypted -c config.toml
cargo run --bin config_crypto_tool encrypt-config -c config.toml -k "secret,api_key"
# Interactive mode
cargo run --bin config_crypto_tool interactive
```
### Command Examples
#### Encrypting Multiple Values
```bash
# Encrypt database password
DB_PASSWORD=$(cargo run --bin config_crypto_tool encrypt "my_db_password")
# Encrypt API key
API_KEY=$(cargo run --bin config_crypto_tool encrypt "sk-1234567890")
# Update configuration file
cargo run --bin config_crypto_tool encrypt-config \
-c config.prod.toml \
-k "session.secret,oauth.google.client_secret,email.sendgrid_api_key" \
--backup
```
#### Finding Encrypted Values
```bash
# Find all encrypted values in a config file
cargo run --bin config_crypto_tool find-encrypted -c config.prod.toml
# Show configuration with decrypted values (for debugging)
cargo run --bin config_crypto_tool show-decrypted -c config.prod.toml
```
## Environment Setup
### Development Environment
```bash
# Generate development key
cargo run --bin config_crypto_tool generate-key
# Encrypt development secrets
DEV_SECRET=$(cargo run --bin config_crypto_tool encrypt "dev-secret-key")
```
```toml
# config.dev.toml
[session]
secret = "@dev_encrypted_secret " # Use encrypted value
[database]
url = "postgresql://dev:dev@localhost:5432/dev_db " # Plain text for dev
```
### Production Environment
```bash
# Generate production key (on production server)
cargo run --bin config_crypto_tool generate-key
# Encrypt production secrets
PROD_SECRET=$(cargo run --bin config_crypto_tool encrypt "prod-secret-key-2024")
SENDGRID_KEY=$(cargo run --bin config_crypto_tool encrypt "SG.xyz123...")
```
```toml
# config.prod.toml
[session]
secret = "@prod_encrypted_secret "
[email]
sendgrid_api_key = "@encrypted_sendgrid_key "
```
## File Structure
```
project/
├── .k # Encryption key file (DO NOT COMMIT)
├── config.dev.toml # Development config
├── config.prod.toml # Production config (with encrypted values)
├── .env # Environment variables
├── .gitignore # Must include .k file
└── docs/
└── ENCRYPTION.md # This documentation
```
### .gitignore Setup
**CRITICAL**: Always add the `.k` file to your `.gitignore` :
```gitignore
# Encryption key file - NEVER COMMIT
.k
.k.backup
# Environment files
.env
.env.local
.env.production
# Backup files
*.backup
```
## Deployment
### Docker Deployment
```dockerfile
# Dockerfile
FROM rust:1.75 as builder
# Copy source code
COPY . .
# Build application
RUN cargo build --release
FROM debian:bookworm-slim
# Copy binary
COPY --from=builder /app/target/release/server /usr/local/bin/server
# Copy configuration
COPY config.prod.toml /app/config.toml
# Encryption key should be mounted as volume or secret
VOLUME ["/app/.k"]
WORKDIR /app
CMD ["server"]
```
```yaml
# docker-compose.yml
version: '3.8'
services:
app:
build: .
volumes:
- ./secrets/.k:/app/.k:ro # Mount key file
environment:
- ROOT_PATH=/app
- ENVIRONMENT=production
```
### Kubernetes Deployment
```yaml
# secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: app-encryption-key
type: Opaque
data:
.k: < base64-encoded-key-file-content >
---
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
template:
spec:
containers:
- name: app
image: myapp:latest
volumeMounts:
- name: encryption-key
mountPath: /app/.k
subPath: .k
readOnly: true
env:
- name: ROOT_PATH
value: /app
volumes:
- name: encryption-key
secret:
secretName: app-encryption-key
```
## Migration Guide
### From Environment Variables
1. **Backup current configuration** :
```bash
cp config.prod.toml config.prod.toml.backup
```
2. **Generate encryption key** :
```bash
cargo run --bin config_crypto_tool generate-key
```
3. **Encrypt sensitive values** :
```bash
# Encrypt each sensitive value
SESSION_SECRET_ENC=$(cargo run --bin config_crypto_tool encrypt "$SESSION_SECRET")
API_KEY_ENC=$(cargo run --bin config_crypto_tool encrypt "$API_KEY")
```
4. **Update configuration** :
```toml
# Before
session.secret = "${SESSION_SECRET}"
# After
session.secret = "@encrypted_session_secret "
```
5. **Test configuration** :
```bash
cargo run --bin config_crypto_tool verify
cargo run --bin config_crypto_tool show-decrypted -c config.prod.toml
```
### From Plain Text
Use the automated encryption tool:
```bash
# Encrypt specific keys in configuration file
cargo run --bin config_crypto_tool encrypt-config \
-c config.prod.toml \
-k "session.secret,oauth.google.client_secret,email.sendgrid_api_key" \
--backup
```
## Troubleshooting
### Common Issues
#### Key File Not Found
```
Error: Encryption key file not found
```
**Solution**: Generate a new key file:
```bash
cargo run --bin config_crypto_tool generate-key
```
#### Decryption Failed
```
Error: Failed to decrypt value
```
**Possible causes**:
- Wrong encryption key
- Corrupted encrypted value
- Key file was rotated without re-encrypting values
**Solution**:
1. Verify key works: `cargo run --bin config_crypto_tool verify`
2. Re-encrypt the value: `cargo run --bin config_crypto_tool encrypt "original_value"`
#### Permission Denied
```
Error: Failed to read encryption key file: Permission denied
```
**Solution**: Fix file permissions:
```bash
chmod 600 .k
```
#### Configuration Validation Failed
```
Error: Configuration validation failed
```
**Solution**: Check if all encrypted values are properly decrypted:
```bash
cargo run --bin config_crypto_tool show-decrypted -c config.toml
```
### Debug Mode
Enable debug logging to see encryption/decryption operations:
```bash
RUST_LOG=debug cargo run --bin config_crypto_tool verify
```
### Recovery Procedures
#### Lost Encryption Key
If you lose the `.k` file:
1. **Generate new key** : `cargo run --bin config_crypto_tool generate-key`
2. **Re-encrypt all values** : You'll need to re-encrypt all `@` prefixed values
3. **Update configuration** : Replace old encrypted values with new ones
#### Corrupted Key File
If the key file is corrupted:
1. **Check if backup exists** : Look for `.k.backup`
2. **Restore from backup** : `cp .k.backup .k`
3. **If no backup** : Generate new key and re-encrypt all values
## Best Practices
### Development
- Use separate keys for development and production
- Keep development keys in team-shared secure location
- Use plain text for non-sensitive development values
- Test encryption/decryption regularly
### Production
- Generate keys on production systems
- Use proper file permissions (0600)
- Regularly rotate encryption keys
- Monitor key file integrity
- Backup keys securely
- Use encrypted values for all sensitive data
### Key Management
- **Never commit `.k` files to version control**
- **Backup keys in secure, separate location**
- **Use different keys for different environments**
- **Rotate keys regularly (quarterly/yearly)**
- **Monitor key file access and modifications**
- **Have key recovery procedures documented**
### Security Considerations
- **Principle of least privilege**: Only necessary personnel should have access to keys
- **Secure backup**: Store key backups in encrypted, secure locations
- **Audit trail**: Log key access and usage
- **Environment separation**: Never use production keys in development
- **Regular security review**: Periodically review and update encryption practices
## Advanced Usage
### Programmatic Usage
```rust
use server::config::encryption::ConfigEncryption;
#[tokio::main]
async fn main() -> Result< (), Box< dyn std::error::Error > > {
// Initialize encryption
let encryption = ConfigEncryption::new(".")?;
// Encrypt a value
let encrypted = encryption.encrypt("my_secret_value")?;
println!("Encrypted: {}", encrypted);
// Decrypt a value
let decrypted = encryption.decrypt(&encrypted)?;
println!("Decrypted: {}", decrypted);
// Check if value is encrypted
if ConfigEncryption::is_encrypted(& encrypted) {
println!("Value is encrypted");
}
Ok(())
}
```
### Custom Integration
```rust
use server::config::{Config, ConfigError};
// Custom configuration loader with encryption
pub fn load_config_with_encryption() -> Result< Config , ConfigError > {
let mut config = Config::load()?;
// Verify encryption key
config.verify_encryption_key()?;
// Additional custom decryption logic
// ...
Ok(config)
}
```
## Support and Maintenance
### Regular Maintenance
- **Weekly**: Check key file integrity
- **Monthly**: Review encrypted values
- **Quarterly**: Consider key rotation
- **Annually**: Security audit and update procedures
### Monitoring
Monitor these metrics in production:
- Key file access patterns
- Decryption success/failure rates
- Configuration loading times
- Security events related to encryption
### Updates
When updating the encryption system:
1. Test in development environment
2. Backup current keys and configurations
3. Update gradually with rollback plan
4. Monitor for issues after deployment
2026-02-08 20:37:49 +00:00
For additional support, refer to the main configuration documentation and security guidelines.