← All decisions
4. Secrets come from the environment, never the repository
Date: 2026-07-15
Status
Accepted
Context
The fastest way to leak a credential is to commit it. The second fastest is to commit it, notice, delete it, and forget that git remembers everything. A public teaching repo is exactly the kind of place a stray secret gets scraped within the hour.
Decision
- No secret is ever committed.
.envis gitignored; only.env.examplewith obviously-fake placeholder values is tracked. - Backends read configuration from environment variables at startup.
- Local development uses
.env. Real deployments inject secrets from a manager (Kubernetes Secrets, cloud secret managers, or a vault); theinfra/k8smanifests wire values fromSecretobjects, not literals. - The application connects to Postgres as the least-privilege
ticketing_approle, never as the superuser. Seecontract/db/migrations/0002_app_role.sql.
Any value in this repo ending in _local_dev_only is a placeholder and is safe
precisely because it protects nothing real.
Consequences
- Rotating a secret is a deployment concern, not a code change.
- Local onboarding costs one
cp .env.example .env. - We rely on discipline plus
.gitignoreplus (recommended) a pre-commit secret scanner. None of these is foolproof; committing secrets is a people problem that tooling only mitigates.