Config values and environment variables

ProcessTier 2 · build and shipPhase 6 · Run it like a company

Settings that live outside the code, so the same code behaves differently in different environments.

The same code has to run in different places with different settings, database addresses, keys, and limits, and hard-coding those makes the code unshippable and leaks secrets. Config values and environment variables exist to keep those settings outside the code, so the same build runs anywhere and secrets stay out of the repository.

The same code runs in staging and production, but should talk to different databases and payment accounts. Those differences live in configuration, environment variables, rather than in the code itself. The code reads its settings from its environment.

This is why "it's just a config change" is a phrase: adjusting a setting is far lighter than changing and redeploying code, though config changes still need care.

A junior PM, stuck

A test order someone placed in staging charged a real card, and the dev says it looks like a "wrong env var." He opened the two .env files to show me, but I cannot tell which line is the live payment key and which is the safe test one, so I cannot confirm what actually went wrong or that it is fixed.

A test order charging a real card is almost always one line: a live key sitting where a test key belongs. Below are staging's and production's .env files, the settings each copy reads at startup, with the live key masked. The skill you need is reading which lines are secrets and which must differ between the two, and the bad line will stand out on its own.

TiffinBox staging and production .env, live key masked
staging.env
APP_ENV=staging
DATABASE_URL=postgres://db-staging.internal/tiffinbox_copy
PAYMENT_GATEWAY_KEY=pk_live_51h8xQ2eRtY
SMTP_URL=smtp://user:pass@smtp-sandbox.internal:2525
RATE_LIMIT_MAX=1000
production.env
APP_ENV=production
DATABASE_URL=postgres://db-prod.internal/tiffinbox
PAYMENT_GATEWAY_KEY=pk_live_****************
SMTP_URL=smtp://user:pass@smtp.internal:587
RATE_LIMIT_MAX=60

Click a step to see the lines it points at.

Skimming a .env top to bottom and assuming staging is safe because it is labeled staging. The label is one line; the payment key on another line is what decides whether money moves. Read the prefix, not the filename.
Treating every differing line between two env files as suspicious. DATABASE_URL and RATE_LIMIT_MAX are meant to differ per environment; only the wrong value on a secret line is the bug.
Asking for the production .env to be pasted so you can compare keys directly. The live key is a secret; ask the dev to confirm the prefix in words instead of moving the value around.
Closing the incident once the test charge is refunded without rotating the key. A pk_live_ key that sat in staging config has been exposed and should be rotated, not just swapped back.

Tell the dev: "Staging's PAYMENT_GATEWAY_KEY starts with pk_live_, so staging is pointed at the real gateway, which is why the test order charged a real card. It should be a pk_test_ key. Can you rotate the exposed live key and put the test key back?" You read two config files, sorted secret lines from settings, and found the single misconfigured value.

"Just a config change" usually means quick and low-risk, though not zero-risk; wrong config has caused outages.
It's why the same build can point at test payments in staging and real ones in production without code changes.

"That's a config value, we don't need a code deploy to change it."

Appears in Phase 6, Run it like a company.