intermediate
Secrets handling
Keep secrets out of code, logs, client bundles, stack traces, test fixtures, and long-lived process state.
Secrets (API keys, DB passwords, signing keys) must never live in source control, client bundles, or casual logs. Load at runtime from a secret manager or orchestrator-injected env — rotate without redeploying code when platform supports it.
Rules:
- No secrets in `git`, Dockerfile layers, or frontend env vars prefixed `NEXT_PUBLIC_`
- Redact in logger serializers and error middleware
- Least privilege DB users per service
- Short-lived tokens over long-lived master keys where possible
// Bad
const apiKey = 'sk-live-...';
// Better
const apiKey = requiredEnv('PAYMENT_API_KEY');
Memory: strings intern in V8 — avoid printing secrets; zeroing buffers is partial mitigation only. Test fixtures use fake credentials, never production copies.
On interviews: secret storage options (Vault, SSM, K8s secrets); rotation story; what happens when a key leaks.
Common pitfalls: `.env.example` with real values; secrets in URL query strings logged by proxies; sharing one DB superuser across services.
The trade-off is balancing simplicity, performance, safety, and operability — name which axis you optimized and what cost you accepted.
Checklist:
- Secret manager or sealed env injection.
- Scan repos for leaked keys (gitleaks).
- Separate build-time and runtime config.
- Incident runbook for key rotation.