This commit fixes critical issues with the database encryption system: **Database Write Operations Fixed:** - Modified credential creation/update operations to use EncryptedDBOperations - Fixed SSH data and credential access to properly decrypt data - All sensitive data writes now go through encryption layer **Database Schema Migration:** - Added missing columns (private_key, public_key, detected_key_type) to ssh_credentials table - Fixed "no such column" SQLite errors during encrypted operations **Application Startup Order:** - Fixed DatabaseEncryption initialization timing issues - Moved encryption-dependent modules to load after encryption initialization - Prevents "DatabaseEncryption not initialized" errors **Key Management Improvements:** - Enhanced EncryptedDBOperations.insert() to return properly decrypted data with all fields - Fixed TypeScript type issues with database insert operations - Improved error handling for database encryption context All credential operations now properly encrypt sensitive data including SSH keys, passwords, and authentication tokens before writing to database.
5.7 KiB
Security Guide for Termix
Database Encryption
Termix implements AES-256-GCM encryption for sensitive data stored in the database. This protects SSH credentials, passwords, and authentication tokens from unauthorized access.
Encrypted Fields
The following database fields are automatically encrypted:
Users Table:
password_hash- User password hashesclient_secret- OIDC client secretstotp_secret- 2FA authentication seedstotp_backup_codes- 2FA backup codes
SSH Data Table:
password- SSH connection passwordskey- SSH private keyskeyPassword- SSH private key passphrases
SSH Credentials Table:
password- Stored SSH passwordsprivateKey- SSH private keyskeyPassword- SSH private key passphrases
Configuration
Required Environment Variables
# Encryption master key (REQUIRED)
DB_ENCRYPTION_KEY=your-very-strong-encryption-key-32-chars-minimum
⚠️ CRITICAL: The encryption key must be:
- At least 16 characters long (32+ recommended)
- Cryptographically random
- Unique per installation
- Safely backed up
Optional Settings
# Enable/disable encryption (default: true)
ENCRYPTION_ENABLED=true
# Reject unencrypted data (default: false)
FORCE_ENCRYPTION=false
# Auto-encrypt legacy data (default: true)
MIGRATE_ON_ACCESS=true
Initial Setup
1. Generate Encryption Key
# Generate a secure random key (Linux/macOS)
openssl rand -hex 32
# Or using Node.js
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
2. Set Environment Variable
# Add to your .env file
echo "DB_ENCRYPTION_KEY=$(openssl rand -hex 32)" >> .env
3. Validate Configuration
# Test encryption setup
npm run test:encryption
Migration from Unencrypted Database
If you have an existing Termix installation with unencrypted data:
1. Backup Your Database
# Create backup before migration
cp ./db/data/db.sqlite ./db/data/db-backup-$(date +%Y%m%d-%H%M%S).sqlite
2. Run Migration
# Set encryption key
export DB_ENCRYPTION_KEY="your-secure-key-here"
# Test migration (dry run)
npm run migrate:encryption -- --dry-run
# Run actual migration
npm run migrate:encryption
3. Verify Migration
# Check encryption status
curl http://localhost:8081/encryption/status
# Test application functionality
npm run test:encryption production
Security Best Practices
Key Management
- Generate unique keys for each installation
- Store keys securely (use environment variables, not config files)
- Backup keys safely (encrypted backups in secure locations)
- Rotate keys periodically (implement key rotation schedule)
Deployment Security
# Production Docker example
docker run -d \
-e DB_ENCRYPTION_KEY="$(cat /secure/location/encryption.key)" \
-e ENCRYPTION_ENABLED=true \
-e FORCE_ENCRYPTION=true \
-v termix-data:/app/data \
ghcr.io/lukegus/termix:latest
File System Protection
# Secure database directory permissions
chmod 700 ./db/data/
chmod 600 ./db/data/db.sqlite
# Use encrypted storage if possible
# Consider full disk encryption for production
Monitoring and Alerting
Health Checks
The encryption system provides health check endpoints:
# Check encryption status
GET /encryption/status
# Response format:
{
"encryption": {
"enabled": true,
"configValid": true,
"forceEncryption": false,
"migrateOnAccess": true
},
"migration": {
"isEncryptionEnabled": true,
"migrationCompleted": true,
"migrationDate": "2024-01-15T10:30:00Z"
}
}
Log Monitoring
Monitor logs for encryption-related events:
# Encryption initialization
"Database encryption initialized successfully"
# Migration events
"Migration completed for table: users"
# Security warnings
"DB_ENCRYPTION_KEY not set, using default (INSECURE)"
Troubleshooting
Common Issues
1. "Decryption failed" errors
- Verify
DB_ENCRYPTION_KEYis correct - Check if database was corrupted
- Restore from backup if necessary
2. Performance issues
- Encryption adds ~1ms per operation
- Consider disabling
MIGRATE_ON_ACCESSafter migration - Monitor CPU usage during large migrations
3. Key rotation
# Generate new key
NEW_KEY=$(openssl rand -hex 32)
# Update configuration
# Note: Requires re-encryption of all data
Compliance Notes
This encryption implementation helps meet requirements for:
- GDPR - Personal data protection
- SOC 2 - Data security controls
- PCI DSS - Sensitive data protection
- HIPAA - Healthcare data encryption (if applicable)
Security Limitations
What this protects against:
- Database file theft
- Disk access by unauthorized users
- Data breaches from file system access
What this does NOT protect against:
- Application-level vulnerabilities
- Memory dumps while application is running
- Attacks against the running application
- Social engineering attacks
Emergency Procedures
Lost Encryption Key
⚠️ Data is unrecoverable without the encryption key
- Check all backup locations
- Restore from unencrypted backup if available
- Contact system administrators
Suspected Key Compromise
- Immediately generate new encryption key
- Take application offline
- Re-encrypt all sensitive data with new key
- Investigate compromise source
- Update security procedures
Support
For security-related questions:
- Open issue: GitHub Issues
- Discord: Termix Community
Do not share encryption keys or sensitive debugging information in public channels.