The Problem
API keys, database passwords, and encryption keys are frequently hardcoded in configuration files, environment variables, or even source code. This creates security risks when code is shared, deployed, or compromised.
Never Do This
# BAD — secrets in source code
DB_PASSWORD = "mysecretpass123"
# BAD — secrets in Dockerfiles
ENV DB_PASSWORD=mysecretpass123
# BAD — secrets in git history
git add .env # Contains secretsEnvironment Variables
The simplest approach for small deployments:
# Set in systemd service file
[Service]
EnvironmentFile=/etc/myapp/secrets.env
# secrets.env (restrict permissions)
# chmod 600 /etc/myapp/secrets.env
DB_PASSWORD=secure_value
API_KEY=another_secret.env Files
- Never commit
.envfiles to git - Add
.envto.gitignore - Provide a
.env.examplewith placeholder values - Set restrictive permissions:
chmod 600 .env
Docker Secrets
# Docker Compose
services:
app:
secrets:
- db_password
secrets:
db_password:
file: ./secrets/db_password.txtKey Rotation
Regularly rotate secrets on a schedule:
- Database passwords: every 90 days
- API keys: every 90 days or after personnel changes
- SSL certificates: automated with Let's Encrypt (every 60 days)