Safeguard
Developer Tools•

How do you make CI install exactly what the lockfile says?

Locked install modes for npm, Cargo, NuGet, Composer, Go and pip, and why CI should fail the build when a lockfile and its manifest drift apart.

Safeguard Security Team
4 min read

Use each package manager's locked or frozen install mode in CI, so the build fails when the lock and the manifest disagree instead of quietly resolving something new. npm has a clean install command, Cargo has a locked flag, NuGet has a locked restore mode, and Composer's install reads composer.lock. Here is each one.

Why CI should fail on drift

An ordinary install command is allowed to update the lock. That is convenient on a laptop and risky in a pipeline, because a build that rewrites its own lock is no longer testing what a person reviewed. Locked mode turns drift into a visible failure that someone fixes in a pull request.

The command for each ecosystem

EcosystemLocked installWhat happens on drift
npmnpm ciExits with an error if lock and package.json do not match
Cargocargo build with the locked flagErrors if the lock is missing or would change
NuGetdotnet restore with the locked-mode optionFails if dependencies changed after the lock was created
Composercomposer installInstalls the versions in composer.lock
Godefault readonly module modeReports an error if go.mod needs updating
pipinstall with require-hashesErrors if any requirement lacks a pinned version and hash

Details worth knowing, each from the official docs:

  • npm's clean install deletes an existing node_modules first, never writes to the manifest or lock, and requires an existing lockfile. Flags used to create the lock, such as the legacy peer deps option, must also be passed to the clean install, or errors are likely.
  • Cargo documents the locked flag as asserting that exactly the same dependencies are used as when the lock was generated. The frozen flag adds offline mode on top.
  • NuGet describes locked mode as restoring the exact packages in the lock file, or failing. It can be set on the command line or as the RestoreLockedMode property.
  • Composer says install uses the lock, and update is the command that rewrites it.
  • Go: since Go 1.16 the go command acts as if readonly mode were set, which reports an error if go.mod needs updating. If a vendor directory exists at go 1.14 or higher, the go command uses it by default.

Gotchas by language

NuGet notes that the .NET SDK can add implicit package references, and using a different SDK version can change those versions and break locked restores. Pin the SDK version with a global.json file so every developer and CI agent agree.

For pip, hash-checking is all or nothing. Specifying a hash on any requirement turns the mode on for all of them, and every dependency must be listed, hashed and pinned with an exact version. That makes it strict, which is the point.

A pipeline checklist

  1. Install in locked mode as the first dependency step.
  2. Make that step a required check, not a warning.
  3. Fail the build if the lockfile has uncommitted changes after install.
  4. Cache the package download directory, never the lock.
  5. Keep the update command in a separate, human triggered job.

Safeguard can help here: it scans dependencies and generates SBOMs, applies reachability analysis so you can sort findings by what your code can actually call, and enforces policies and gates on pull requests. You can try a free scan on a repository to see what it finds.

Try it yourself

Open the demo and watch a gate stop a change. Note which rule fired and what the developer sees.

Click through it at your own pace, or open it full screen.

Quick check

Is npm ci the same as npm install?

No. Per the npm docs, npm ci needs an existing lockfile, removes node_modules first, and errors if the lock and manifest disagree. It never modifies either file.

What does Cargo's frozen flag add?

According to the Cargo docs, it equals the locked flag plus offline mode.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.