Rustelo/docs/encryption.md
Jesús Pérex 2f0f807331 feat: add dark mode functionality and improve navigation system
- Add complete dark mode system with theme context and toggle
- Implement dark mode toggle component in navigation menu
- Add client-side routing with SSR-safe signal handling
- Fix language selector styling for better dark mode compatibility
- Add documentation system with mdBook integration
- Improve navigation menu with proper external/internal link handling
- Add comprehensive project documentation and configuration
- Enhance theme system with localStorage persistence
- Fix arena panic issues during server-side rendering
- Add proper TypeScript configuration and build optimizations

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-11 20:53:20 +01:00

14 KiB

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

# 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

# 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

# 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

# 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:

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:

# 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:

# 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

# 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

# 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

# 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")
# 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

# 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...")
# 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:

# Encryption key file - NEVER COMMIT
.k
.k.backup

# Environment files
.env
.env.local
.env.production

# Backup files
*.backup

Deployment

Docker Deployment

# 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"]
# 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

# 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:

    cp config.prod.toml config.prod.toml.backup
    
  2. Generate encryption key:

    cargo run --bin config_crypto_tool generate-key
    
  3. Encrypt sensitive values:

    # 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:

    # Before
    session.secret = "${SESSION_SECRET}"
    
    # After
    session.secret = "@encrypted_session_secret"
    
  5. Test configuration:

    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:

# 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:

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:

chmod 600 .k

Configuration Validation Failed

Error: Configuration validation failed

Solution: Check if all encrypted values are properly decrypted:

cargo run --bin config_crypto_tool show-decrypted -c config.toml

Debug Mode

Enable debug logging to see encryption/decryption operations:

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

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

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

For additional support, refer to the main configuration documentation and security guidelines.