# 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

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