07 β Secrets & Configuration
The core rule: no passwords, keys, or credentials anywhere in your code, config files, Docker image, or Git history.
Secrets are injected into the running container by Kubernetes at startup. Your app reads them as normal environment variables. The DevOps team creates the Kubernetes Secrets with the actual values β you just make sure your app reads env vars and never hardcodes anything.
Never commit
- Database passwords or usernames
- API keys or tokens
.envfiles (a.env.examplewith placeholder values is fine)- AWS credentials of any kind
- Any secret value inside a ConfigMap (ConfigMaps are not encrypted)
If a secret ever lands in Git history β even in a deleted commit β treat it as compromised: tell DevOps immediately so it can be rotated. Removing it from history is not enough.
Standard environment variables
| Variable | Source | What it is |
|---|---|---|
DB_HOST |
Secret | PostgreSQL server hostname |
DB_PORT |
Secret | PostgreSQL port (usually 5432) |
DB_NAME |
Secret | Database name |
DB_USER |
Secret | Database username |
DB_PASSWORD |
Secret | Database password β never hardcode |
APP_PORT |
ConfigMap | Port your HTTP server listens on |
APP_ENV |
ConfigMap | production or staging |
LOG_LEVEL |
ConfigMap | info, debug, or warn |
Secrets β Kubernetes Secret. Non-sensitive config β Kubernetes ConfigMap. The DevOps team creates both; your deployment.yaml references them via secretKeyRef / configMapKeyRef (see guide 04).
Need an extra secret (a third-party API key, SMTP password, etc.)? Add it to your deployment.yaml as another secretKeyRef on the same <app>-secrets Secret, document it in source/README.md, and give the actual value to DevOps through a secure channel (never Slack/email in plain text β ask DevOps for the approved channel).
What source/README.md must include
A table of every environment variable the app reads:
## Environment Variables
| Variable | Required | Default | Source | Description |
|-------------|----------|---------|-----------|------------------------------------|
| DB_HOST | Yes | β | Secret | PostgreSQL server hostname |
| DB_PORT | Yes | 5432 | Secret | PostgreSQL port |
| DB_NAME | Yes | β | Secret | Database name |
| DB_USER | Yes | β | Secret | Database username |
| DB_PASSWORD | Yes | β | Secret | Database password |
| APP_PORT | Yes | 3000 | ConfigMap | Port the HTTP server listens on |
| APP_ENV | Yes | β | ConfigMap | production or staging |
| LOG_LEVEL | No | info | ConfigMap | info / debug / warn |
Plus: required PostgreSQL extensions, and anything else DevOps must provision.
Self-check before submitting
git grep -iE 'password|secret|api[_-]?key|token' -- ':!*.md' ':!*.example'
git log -p | grep -iE 'BEGIN (RSA|OPENSSH) PRIVATE KEY|AKIA[0-9A-Z]{16}' || true
Both should come back clean. Consider adding a secret scanner (e.g. gitleaks) to your PR workflow.