Config Management
Critical rules
- Validate the entire config once at startup. Bad config fails the process before traffic.
- Never read
process.envmid-request. Resolve once; inject typed config throughdeps. - Keep secrets out of the environment: load from a secret manager into memory (
preventProcessEnvWrite). - No fallback defaults for required values — fail fast.
- Prefer ephemeral/rotating credentials; scan git history for secrets in CI.
- Before implementing loaders or tests, read references/examples.md and references/testing.md.
Workflow
- Define the config schema (node-env-resolver validators or Zod).
- Resolve at startup: non-secrets from env, secrets from secret manager into memory.
- Wire typed config into the composition root
deps. - Make
getConfig(resolvers?)injectable so tests pass mock resolvers — see references/testing.md. - Add TruffleHog/Gitleaks over full history in CI.
- Prefer short-lived credentials with refresh where available.
Resources
- references/examples.md — resolver/Zod loaders, deps injection, secrets, fail-fast. Read when implementing.
- references/testing.md — env variants, mock resolvers, CI scanning, rationalizations. Read for tests and hardening.
Validation
- [ ] Config validated once at startup; process exits on failure
- [ ] No required value has a silent default
- [ ] Config injected via
deps, not re-read fromprocess.env - [ ] Secrets from secret manager with
preventProcessEnvWrite - [ ] Config type inferred from schema
- [ ] Tests inject mock resolvers/config objects
- [ ] CI secret-scans full git history
Constraints
- Per-request HTTP input is
validation-boundary, not this skill. Dynamic feature-flag evaluation is separate from startup config. - Related:
validation-boundary,fn-args-deps,strict-typescript,observability.