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.