# Production Secrets Management ## Overview This directory contains encrypted production secrets managed with Ansible Vault. **Security Model**: - Secrets are encrypted at rest with AES256 - Vault password is required for deployment - Decrypted files are NEVER committed to git - Production deployment uses secure SSH key authentication ## Files - `production-vault.yml` - **Encrypted** secrets vault (safe to commit) - `.gitignore` - Prevents accidental commit of decrypted files ## Quick Start ### 1. Initialize Secrets (First Time) ```bash cd deployment ./scripts/setup-production-secrets.sh init ``` This will: - Generate secure random passwords/keys - Create encrypted vault file - Prompt for vault password (store in password manager!) ### 2. Deploy Secrets to Production ```bash ./scripts/setup-production-secrets.sh deploy ``` Or via Gitea Actions: 1. Go to: https://git.michaelschiemer.de/michael/framework/actions 2. Select "Update Production Secrets" workflow 3. Click "Run workflow" 4. Enter vault password 5. Click "Run" ### 3. Update Secrets Manually ```bash # Edit encrypted vault ansible-vault edit deployment/ansible/secrets/production-vault.yml # Deploy changes ./scripts/setup-production-secrets.sh deploy ``` ### 4. Rotate Secrets (Monthly Recommended) ```bash ./scripts/setup-production-secrets.sh rotate ``` This will: - Generate new passwords - Update vault - Deploy to production - Restart services ## Vault Structure ```yaml # Database vault_db_name: framework_production vault_db_user: framework_app vault_db_password: [auto-generated 32 chars] # Redis vault_redis_password: [auto-generated 32 chars] # Application vault_app_key: [auto-generated base64 key] vault_jwt_secret: [auto-generated 64 chars] # Docker Registry vault_registry_url: git.michaelschiemer.de:5000 vault_registry_user: deploy vault_registry_password: [auto-generated 24 chars] # Security vault_admin_allowed_ips: "127.0.0.1,::1,94.16.110.151" ``` ## Security Best Practices ### DO ✅ - **DO** encrypt vault with strong password - **DO** store vault password in password manager - **DO** rotate secrets monthly - **DO** use `--ask-vault-pass` for deployments - **DO** commit encrypted vault to git - **DO** use different vault passwords per environment ### DON'T ❌ - **DON'T** commit decrypted vault files - **DON'T** share vault password via email/chat - **DON'T** use weak vault passwords - **DON'T** decrypt vault on untrusted systems - **DON'T** hardcode secrets in code ## Ansible Vault Commands ```bash # Encrypt file ansible-vault encrypt production-vault.yml # Decrypt file (for viewing only) ansible-vault decrypt production-vault.yml # Edit encrypted file ansible-vault edit production-vault.yml # Change vault password ansible-vault rekey production-vault.yml # View encrypted file content ansible-vault view production-vault.yml ``` ## Deployment Integration ### Local Deployment ```bash cd deployment/ansible ansible-playbook -i inventory/production.yml \ playbooks/setup-production-secrets.yml \ --ask-vault-pass ``` ### CI/CD Deployment (Gitea Actions) Vault password stored as Gitea Secret: - Secret name: `ANSIBLE_VAULT_PASSWORD` - Used in workflow: `.gitea/workflows/update-production-secrets.yml` ### Docker Secrets Integration Secrets are deployed as Docker Secrets for secure runtime access: ```bash # List deployed secrets on production ssh deploy@94.16.110.151 "docker secret ls" # Services automatically use secrets via docker-compose services: web: secrets: - db_password - redis_password - app_key ``` ## Troubleshooting ### "Decryption failed" Error **Cause**: Wrong vault password **Solution**: ```bash # Verify password works ansible-vault view deployment/ansible/secrets/production-vault.yml # If forgotten, you must reinitialize (data loss!) ./scripts/setup-production-secrets.sh init ``` ### Secrets Not Applied After Deployment **Solution**: ```bash # Manually restart services ssh deploy@94.16.110.151 "docker service update --force framework_web" # Or use Ansible cd deployment/ansible ansible-playbook -i inventory/production.yml playbooks/restart-services.yml ``` ### Verify Secrets on Production ```bash ./scripts/setup-production-secrets.sh verify # Or manually ssh deploy@94.16.110.151 "docker secret ls" ssh deploy@94.16.110.151 "cat /home/deploy/secrets/.env.production | grep -v PASSWORD" ``` ## Emergency Procedures ### Lost Vault Password **Recovery Steps**: 1. Backup current vault: `cp production-vault.yml production-vault.yml.lost` 2. Reinitialize vault: `./scripts/setup-production-secrets.sh init` 3. Update database passwords manually on production 4. Deploy new secrets: `./scripts/setup-production-secrets.sh deploy` ### Compromised Secrets **Immediate Response**: 1. Rotate all secrets: `./scripts/setup-production-secrets.sh rotate` 2. Review access logs on production 3. Update vault password: `ansible-vault rekey production-vault.yml` 4. Audit git commit history 5. Investigate compromise source ## Monitoring Check secrets deployment status: ```bash # Via script ./scripts/setup-production-secrets.sh verify # Manual check ansible production_server -i inventory/production.yml \ -m shell -a "docker secret ls | wc -l" # Should show 5 secrets: db_password, redis_password, app_key, jwt_secret, registry_password ``` ## Related Documentation - [Ansible Vault Documentation](https://docs.ansible.com/ansible/latest/user_guide/vault.html) - [Docker Secrets Best Practices](https://docs.docker.com/engine/swarm/secrets/) - Main Deployment Guide: `../README.md`