# 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> { // 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: --- # 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> { // 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 { 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 For additional support, refer to the main configuration documentation and security guidelines.