Verify Vendored Files Never Silently Drift
Vendoring pulls external code into your own repository so it's reviewable, diffable, and not
subject to an upstream registry going away. But once those files land on disk, nothing has watched
them since. A teammate edits a vendored file directly to work around a bug. A pull can interrupt
partway through. CI reuses a runner's disk across jobs. Every one of these leaves your checkout
silently out of sync with what Atmos actually vendored. The first sign of trouble is usually a
broken terraform plan weeks later — not the moment the drift happened.
The Problem
The atmos vendor pull command always re-fetches everything, every time, whether or not anything
actually changed. That makes it slow to lean on as a drift check, so most teams just don't run it that
way — they trust the checkout and find out otherwise the hard way. There was also no way to answer
"does what's on disk still match what was vendored" without a network round trip, and no way to
choose how loudly a stale checkout should complain before Atmos quietly re-fetches it.
The Fix
Every atmos vendor pull now records a vendor.lock.yaml receipt for each vendored source: its
declared origin, a resolved identity, and a checksum for every file it wrote. That receipt is what
atmos vendor verify checks against, with zero network access:
atmos vendor verify
COMPONENT PATH REASON
vpc components/terraform/vpc/main.tf checksum mismatch
It exits non-zero the moment anything doesn't match — a missing file or a modified one — so it
drops straight into a CI gate. Add --component <name> to scope the check, or --format json for
machine-readable output.
You also get to choose how a drifted checkout behaves on the next atmos vendor pull, instead of
always silently re-fetching:
vendor:
lock:
enforcement: warn # silent | warn | strict
- The
silentmode re-fetches with no reporting — the behavior everyvendor pullhad before this existed. - The
warnmode (the default) re-fetches and prints one line naming what drifted and why. - The
strictmode refuses to run at all until you pass--refresh-lock, so an unreviewed local edit can never get silently overwritten — or silently kept — without someone noticing.
How to Use It
Gate CI on drift the same way you'd gate on any other check:
atmos vendor verify || exit 1
Override enforcement for a single invocation without touching atmos.yaml:
atmos vendor pull --lock-enforcement=strict
And when a source genuinely needs to move — not just recover from drift — version: can now be a
semver range instead of only an exact pin:
sources:
- component: vpc
source: github.com/cloudposse/terraform-aws-vpc.git
version: "^1.0.0"
The first atmos vendor pull resolves that range to a concrete tag and locks it there — every
later pull reuses the locked version with no network call at all, until an explicit
atmos vendor update or --refresh-lock re-resolves it. An exact pin like version: v1.5.0
behaves exactly as it always has: the manifest itself remains the single source of truth for what
gets fetched.
Get Involved
Questions about lock enforcement, vendor verify, or version ranges are welcome in the
Atmos GitHub repository and the community Slack.
