Hidden dependency
A hidden dependency is code, a package or a file that a build downloads and uses but that no lockfile or manifest lists, so most SBOMs miss it.
Last updated: November 11, 2026
A hidden dependency is code, a package or a file that a build downloads and uses but that no lockfile or manifest lists. Because most SBOM tools work from those lists, hidden dependencies are missing from most SBOMs, and they are where several recent supply chain attacks ran. In general software engineering the phrase also means undeclared coupling between modules; here it means the supply chain sense.
Common hidden dependencies
- Install hooks. npm runs a package's
preinstall,installandpostinstallscripts duringnpm install(npm docs). Whatever those scripts download never appears inpackage-lock.json. This is the route the Shai-Hulud worm used. - Build scripts. Cargo compiles and runs a crate's
build.rsjust before building the crate (Cargo book). Some build scripts download a C library or a prebuilt binary at that point, andCargo.lockdoes not record it. - Base images. In a container build, the base image and its operating system layers come from a registry, not from any language lockfile. See Docker image SBOMs.
- CI steps. Setup actions and
curl | shinstallers in a workflow fetch tools straight from a URL, with no lockfile, version pin or hash unless the author adds one.
Code committed to the repository (vendored dependencies) is another way components escape manifests, but it is not fetched during the build. "Phantom dependency" means something else again: in JavaScript, a package your code uses without declaring it, available only through hoisting.
Why SBOM tools miss them
Lockfile-based tools read the declared list in the lockfile, so they see only what was declared. Output scanners look at the finished artifact and work out what went in, which is guesswork for compiled code such as Rust. Neither sees what the build fetched along the way. The full list of what each approach misses, including caches and build tools, is in open source SBOM generators. A hidden dependency is a gap in SBOM completeness that the SBOM itself cannot reveal.
Pinning does not solve it either: a lockfile can be perfect and the install hook it pins can still download something new. Builds that fetch at build time are also one reason a reproducible build is hard to achieve.
How to find them
- Read the build log for downloads:
npm installandcargo buildoutput, and lines fromcurlorwget. - Compare an SBOM generated from the lockfile with the packages the install step reports.
- Search your SBOM for a package you know is in your base image, such as
libc6. If it is not there, the image layers are missing. - Grep your workflows for
curlandwget.
The reliable answer is to record what the build actually takes in over the network, rather than reconstructing it afterwards.
CRACI
CRACI sees the traffic coming into each build, so it records the hidden dependencies that lockfile-based tools miss. When it could not see everything, for example because a job allowed traffic that bypasses its package-aware proxy, the job's completeness state says so. Its egress policy also decides which hosts a build can reach at all, so a curl | sh to a host the policy does not allow fails. See build-time SBOMs.