Skip to main content

Porting env-sync, and the safety net it never had

· 2 min read

env-sync started as a set of scripts inside a skills repo. They pushed 1Password secrets to six platforms, and they did it well. They had one gap: nothing stopped a push to production that you did not mean to run.

The port to a standalone tool kept the original behavior exactly. All 191 original tests carry over as a pinned baseline, and a set of golden fixtures records every adapter's readCurrent and pushValues behavior. Then the port added one thing on purpose: a confirmation gate before any push --apply that cannot be proven safe.

Getting that gate right took three tries. Checking the --env string alone was unsafe, because Vercel, Render, and CapRover ignore --env completely. Checking each target's manifest fields was better, but an adversarial review found that a Vercel target declared as development can still update a live entry scoped to production. The rule that shipped auto-approves only targets whose write scope is derived from --env in code. Everything else asks. The architecture page has the full story.

The same golden fixtures now also check a second, independent implementation in Go, which is on the way to a single static binary. It passes every fixture. It has not yet run against a real 1Password Service Account, so the TypeScript CLI remains the one to use today.