Secrets inventory
Every environment variable the site reads, whether it is secret, whether it reaches the browser, and where it is used.
- Status: Current
- Last updated: 2026-11-01
- Related ADRs: ADR-0005, ADR-0016
Snapshot of the system as it stands today. Edit in place; never record what changed.
Inventory
The variables are read directly where they are used. Locally they live in .env.local, which
.gitignore excludes (.env*.local). .env.example at the repository root lists every
variable below, with a comment and no value.
| Variable | What it is | Secret? | Reaches the browser? | Read by | Rotation |
|---|---|---|---|---|---|
SITE_URL | The site's public address, an https origin with no path; without it every page is noindex (ADR-0035) | No — public, and printed on every share image | Only as the address in pages' links and images; never as a variable | src/lib/seo.ts, src/app/og/[...slug]/route.tsx, scripts/sync-content.ts | When the domain changes |
NEXT_PUBLIC_ALGOLIA_APP_ID | Algolia application ID | No | Yes, inlined into the client bundle | src/lib/algolia.ts, scripts/sync-content.ts | With the Algolia application |
NEXT_PUBLIC_ALGOLIA_SEARCH_KEY | Algolia search-only API key | No — public by design, but it can read every record in the index | Yes, inlined into the client bundle | src/lib/algolia.ts | On suspicion of abuse, in the Algolia dashboard |
ALGOLIA_WRITE_KEY | Algolia key with write access to the index | Yes | No | scripts/sync-content.ts only | On suspicion, or yearly, in the Algolia dashboard |
Rules
- No secret is ever a string literal — not in source, config, comments, tests or docs.
NEXT_PUBLIC_*publishes a value to every browser. Never a secret; each one is reviewed as a publication.ALGOLIA_WRITE_KEYmust never gain the prefix..env*.localfiles stay out of git..env.exampleis committed and documents every variable with a comment, never a value.- A build that publishes refuses to run without the secrets it needs, naming the variable
and never printing its value.
scripts/sync-content.tsrefuses in the same way withoutSITE_URL, so production cannot silently gonoindex. - If a secret is ever committed, rotate it immediately. Removing it from the tree or from history is not enough.