Silent rollback
Silent rollback is the design choice that lets Upwarden sit in front of a build pipeline without breaking it. A package manager that asks for “the latest 1.x” gets the latest safe 1.x — not a 403, not a stalled CI job, not an angry developer at 3am. The bad version is invisible to the resolver; the build resolves to the next-best safe version and proceeds.
The mechanic
Section titled “The mechanic”Package managers do dependency resolution in two steps:
- Fetch the package’s manifest — the list of available versions.
- Resolve the user’s version range against that list and download a specific version.
Upwarden intercepts step 1. When the proxy returns the manifest, it has already stripped out any version Upwarden would have BLOCKED or QUARANTINED. The resolver in step 2 simply doesn’t see those versions — there’s nothing to fail on.
A request for ^1.2.0 walks the safe-version list and picks the highest; if 1.5.7 is non-safe but 1.5.6 is, the developer ends up on 1.5.6. No error surface. No npm install failure.
Where you DO see the 403
Section titled “Where you DO see the 403”The 403 path only fires when a developer pins exactly to a non-safe version:
// package.json{ "dependencies": { "foo": "1.5.7" // exact pin to a BLOCKED version → 403 }}This is intentional: silent rollback protects builds that ask for “give me the safe one”; explicit pins to known-bad versions are a deliberate “I want this specific version” request and Upwarden refuses loudly.
Versions that disappear
Section titled “Versions that disappear”A consequence worth knowing: a version that’s currently in cooldown (younger than VANGUARD_DEFAULT_MIN_AGE_DAYS) is also stripped from the manifest. A brand-new legitimate release won’t get picked up by a floating range until cooldown clears. Builds stay green; the new version simply doesn’t appear in the resolution set yet.
If a developer needs the new version immediately (security fix, dependency override), the operator can either lower cooldown for that package via the policy override surface, or the developer can pin exactly — which surfaces a temporary 403, but the operator can allowlist that version explicitly.
Why not just BLOCK on the manifest?
Section titled “Why not just BLOCK on the manifest?”We considered it. The reason silent rollback won:
- CI determinism. A build that asked for
^1.2.0yesterday and got1.5.6should still get1.5.6today even if1.5.7published-and-got-flagged in between. Erroring the manifest would break every CI in the company because of one bad upstream release. - Floating-range semantics are already permissive. A developer who wrote
^1.2.0is already telling the resolver “any compatible version is fine”. Upwarden is honouring that — just with a smaller “compatible” set than the unfiltered registry. - The 403 surface is reserved for “you asked specifically for the bad thing”. That’s where the operator/developer attention needs to land.
Audit posture
Section titled “Audit posture”Silent rollback is not silent in the audit log. Every manifest request that strips a non-safe version writes a row showing what was filtered. Operators can query for “how many builds were saved from version X” — the answer is exactly the number of rollback-applied manifest rows.
What’s next
Section titled “What’s next”- Verdicts & the scanner — what makes a version non-safe in the first place.
- Troubleshooting — common reasons a package you expected was rolled back.
- Querying the audit log — find the rollback rows.