Notebook
Note
Download Markdown

Managing Environment Variables

3 min read

Over time, you’ll want to develop an app-template markdown file containing all the prerequisites and rules that you want Claude to follow when it makes you an app. Here are some key components that need to be in there. They stem from issues I’ve had.

Environment-variable contract — single source of truth for app secrets and variables

Ask your AI to create an Environment Variable Contract for your project. The objective is to prevent env var names (Environment Variables) from living in several uncoordinated places and starting to diverge which will break your app.

Here is a prompt you can use:

Md
Set up an "Environment Variable Contract" for this project — a single source of truth for every environment variable the app reads, enforced automatically so a misnamed or missing variable can never fail silently in production while CI stays green.

Background: env var names tend to live in several uncoordinated places — the code's process.env.X reads, a secrets template file, a setup script, an .env.example, and the deploy platform's config. Nothing forces these to agree, so a variable named slightly differently in two places (e.g. MY_KEY in code vs MY_KEY_V1 in the secrets file) fails silently: the app falls back to a default or throws quietly, while CI passes because it runs in a mock/test mode that never touches the real secret. Build a system that makes this class of bug impossible to ship.

Create all of the following:

1. A single declarative list of every env var the app uses, each tagged with: its name, a category (secret / runtime-config / optional / build-or-test-only), whether the code reads it directly, and whether it must be provisioned as a real secret in production.

2. An automated test that runs in CI on every change and cross-checks, in both directions:
   - every process.env.X-style read in the source is declared in the list (catches a new or renamed read that was never declared)
   - every declared "read in code" entry is still actually read somewhere (catches a stale, unused declaration)
   - every var marked "must be a real secret" appears under the exact same name in the secrets/deploy template — this is the load-bearing check, the one that catches a name typed two different ways
   - the secrets/deploy template doesn't provision a name that was never declared

3. A runtime health-check endpoint or command that reports the status of each critical piece of config — but checks the thing that actually has to be true (e.g. "can this storage endpoint be reached," "is this key the right length"), not a shallow proxy like "is the variable merely set."

4. A deploy-time preflight check that verifies every required secret is actually staged on the target hosting environment (not just present in a local template file) before a deploy is allowed to proceed.

5. A short written workflow describing how secrets move from wherever they're stored (e.g. a password manager or secrets vault) to the hosting platform, with one rule called out explicitly: the name used in the deploy/secrets config must be byte-identical to the name the code reads — the vault item's display title can be anything, but the actual key must match exactly, and the CI test in step 2 is what enforces that permanently.

Make this a standard part of project setup — all four pieces should exist before any real integration work begins, not bolted on afterward. Adapt the implementation (test framework, health-check format, deploy tooling) to whatever this project uses.