SPB Git

spb/ultra-sharp-agent-skills Public

Ultra-Sharp Agent Skills — a research-first skill-authoring system + 72 production-ready skills for AI agents.

Python 100%

# name: managing-configuration description: Structures backend service configuration the 12-factor way — environment variables into one typed config object validated at startup, secrets kept out of code and VCS, per-environment overrides without per-environment code. Use when the user asks how to manage config, environment variables, .env files, secrets in a service, add a config setting, or fix per-environment behavior. Do not use for infrastructure provisioning (Terraform/CloudFormation) or CI/CD pipeline configuration.

# Managing Configuration

# When to use / when NOT to use

  • Use for: application-level configuration: env vars, .env files, secrets handling, typed config objects, feature flags vs config.
  • Do NOT use for: provisioning infrastructure (Terraform etc.) or CI/CD pipeline YAML — different lifecycles and tools.

# Core rules

  1. All config comes from the environment (12-factor). Code reads env vars; nothing environment-specific is baked into the artifact — the same image runs in dev, staging, and prod.
  2. One typed config object, validated at startup. Parse env once into a frozen, typed structure; every missing/invalid key crashes the boot with the key named.
    • Settings() raises DATABASE_URL: field required before serving
    • os.environ["DATABASE_URL"] scattered across 30 files, failing at first use in prod.
  3. Secrets are not config. Passwords, API keys, signing keys come from a secret manager or injected env at deploy time — never committed, never in Docker images, never logged. .env is for local dev only and gitignored.
  4. No per-environment code paths. Behavior differences are driven by config values, not environment names.
    • if settings.payments_sandbox: (set true in staging's env)
    • if ENV == "staging": use_sandbox() sprinkled through the codebase.
  5. Defaults are safe for dev, explicit for prod. Local dev works out of the box (localhost DB, DEBUG level); production values must be provided — a prod boot with dev defaults should fail validation (e.g., SECRET_KEY has no default).
  6. .env.example is the single, current catalog of every variable: name, purpose, example value, required/optional. A new variable isn't merged without its line.
  7. Feature flags are not settings. Flags are runtime-togglable and short-lived (removed after rollout); config is boot-time and long-lived. Don't grow a flag system inside your config object.

# Workflow

  1. Inventory every os.environ / process.env access; move each into the central typed config object.
  2. Classify each key: plain config vs secret; route secrets to the secret manager / injected env.
  3. Set dev defaults where safe; mark prod-critical keys as required (no default).
  4. Update .env.example with every key; gitignore .env; purge any committed secrets (and rotate them — history remembers).
  5. Validate: boot with one required var unset → assert the process exits naming that key; run git log -p | grep -iE "api_key|secret|password" and a repo scan (gitleaks detect) → must be clean.

# Edge cases & failure modes

  • A secret was committed → rotating the secret is mandatory; rewriting git history is optional. Treat it as leaked.
  • Config needed before the config system loads (log level for the config parser itself) → read that one var directly, document the exception.
  • Multi-tenant / per-customer settings → that's data, not config: store in the database, not env vars.
  • Large config values (PEM certs) → mount as files and put the path in env; multiline env vars break tooling.
  • Different values per process in one deploy (worker vs web concurrency) → separate variables (WEB_CONCURRENCY, WORKER_CONCURRENCY), not conditionals on process type.

# References

Deeper recipes and gotchas: see references/patterns.md