← Guides

Env drift checklist: stop shipping the wrong secrets

~4 min read · Updated 2026-08-11 · Works with any stack

Most “works on my machine” outages are not mysterious. Someone changed a key in staging, forgot it in production, rotated a secret in the vault but not in the deploy pipeline, or left a debug flag only on their laptop. Configuration drift is the quiet killer: the app starts, then fails halfway through a payment call or silently uses the wrong database.

This guide is a pre-deploy checklist you can run by hand or wire into CI. It is deliberately stack-agnostic: Docker, bare metal, Kubernetes, and serverless all have the same underlying problem — more than one place claims to own “the environment.”

What “drift” actually looks like

Three failure modes show up over and over:

  1. Missing key. Prod never received STRIPE_SECRET_KEY. The process boots; first charge throws.
  2. Wrong value. Staging URL still points at a sandbox host after go-live. Everything “works” with toy data.
  3. Extra / zombie key. An old feature flag still on in prod after you removed the code path — or worse, a debug bypass left enabled.
If your team only copies a single .env around in chat or email, you already have drift — you just have no audit trail for when it happened.

1. Inventory every source of truth

Before you can diff anything, write down where config lives. A realistic service often has five or more:

Pick a baseline for each stage (dev, staging, prod). For many small teams the baseline is a key-only .env.example plus a short doc that says “prod secrets live in X.” Mark each key required or optional. Optional keys without a default are how silent feature-off switches get deployed by accident.

Make ownership explicit

Assign one human (or on-call rotation) as owner of “prod config.” When two people can edit vault paths without a PR trail, drift is a process bug, not a tooling bug.

2. Diff keys with redaction (never paste raw secrets)

Compare key sets, not full values in Slack. A useful report answers three questions:

Prefer tools that redact values in shared output. Secret managers’ audit UIs, editor plugins, and dedicated env-diff CLIs all work; pick something the team will actually run. Pasting a full prod dump into a ticket is a security incident waiting for a forward button.

# Conceptual: key-set only compare (illustrative)
# left = .env.example keys, right = exported key names from staging
comm -3 <(sort example.keys) <(sort staging.keys)

3. Separate “missing” from “wrong”

Treat these differently in process and in automation:

A common trap: the app accepts empty string as “present.” Your health check is green; the third-party API rejects empty auth. Validate that required secrets are non-empty at boot, not only that the key exists.

4. Wire CI so PRs that touch config cannot skip the check

On any PR that changes env examples, Helm values, Compose files, or Terraform that injects env, run a key-set check against the baseline. Fail closed for required keys. Optional niceties:

5. Pre-deploy checklist (print or ticket template)

6. After the fire: make the same class of bug boring

When drift does bite, write a one-page postmortem with the actual key name (not the value) and the stage that was wrong. Then add one automatic check that would have caught it. Teams that only “remind everyone to be careful” get the same incident quarterly.

Related reading: Dotenv tooling landscape — how teams split dotenv files, vaults, linters, and platform config without overbuying SaaS.

Related: Dotenv tooling landscape · Browser JSON tools · Tactical Data Concepts