Dependency drift is the gap that opens when the same application runs with different package versions in dev, staging, and production. The code is identical, but the libraries underneath it are not. That means what you tested is not what you shipped, and a vulnerability fix can exist in one place only.
A working definition
Drift has two halves. Declared drift is when manifests disagree, for example a package.json range that resolves differently on two dates. Actual drift is when the installed packages on running systems differ, even if the manifests agree. Actual drift is the one that hurts, because it is invisible in the repository.
A third kind is easy to miss: drift in things that are not packages in your manifest, such as the base image, operating system libraries, and the language runtime.
How drift starts
Most drift comes from a short list of habits:
| Cause | What happens |
|---|---|
| Version ranges with no lockfile | Each install picks the newest match on that day |
| Rebuilding per environment | Staging and prod build on different dates and resolve different versions |
| Mutable image tags | The same tag points at different content over time |
| Manual fixes on a server | A package is upgraded by hand and never recorded |
| Long-lived environments | Old hosts keep old libraries while new ones get new ones |
None of these is exotic. They are the defaults when nobody sets a rule.
Why it matters for security
Security teams scan the repository or the staging build and report a clean result. If production differs, that result describes something that is not running. The reverse also happens: a patched version passes tests in staging while production still carries the vulnerable one, and a ticket gets closed too early.
Drift also breaks incident response. When an advisory lands, the first question is which environments contain the affected version. If you cannot answer from data, you answer from memory.
How to spot it
- Pick one application and list the exact package versions in each environment, from the installed state and not only from the manifest.
- Compare the lists. Even a plain text diff shows the gap.
- Sort the differences by risk: anything with a known advisory first, then anything with a major version change, then the rest.
- Record how each difference got there. The cause tells you which control to add.
For a deeper method, see how to measure dependency version drift across services and how to check SBOM drift between build and production.
Try it yourself
Click through it at your own pace, or open it full screen.
Look at how one inventory view lists every package and version per project. Imagine producing that for each environment and comparing them.
What Safeguard does here
Safeguard produces an SBOM and dependency inventory from your projects and keeps scanning them against new advisories, so you can compare what each environment contains. You can try a free scan at gold.safeguard.sh/scan.
Quick check
Is drift always a problem?
No. Small differences in development tools are often harmless. The problem is unexplained differences in anything that ships, especially packages with known advisories.
Does a lockfile prevent drift completely?
It prevents resolution drift for the packages it covers. It does not cover base images, operating system packages, or manual changes on running hosts.
Last reviewed: 19 October 2026.