If a target has no lockfiles, you cannot know from the repository which dependency versions were used. Build the inventory from the deployed artifact or container image, label it as derived, and make pinning dependencies a post close task.
Why it matters
A manifest typically states ranges, such as "this version or newer within the same major line". A lockfile records the exact resolved versions. Without it, two builds a week apart can contain different code, and an inventory made from the manifest describes a possibility, not a product.
The GitHub dependency graph is a summary of manifest and lock files in a repository. With manifests alone it can show what a project asks for, but the resolved versions need a lockfile or a submission from a build.
Three ways to get a truthful inventory
| Approach | How | Confidence |
|---|---|---|
| Scan the shipped artifact | Inspect the built image or package | High for what shipped on that date |
| Resolve in a clean build | Run the build in a sandbox, capture the resolved tree | Medium, reflects today not the past release |
| Ask the build system | Pull dependency data from the CI job that made the release | High if the job logs it |
Prefer the first. It answers the question the buyer cares about: what is in the thing customers run.
Steps
- Identify the artifacts currently deployed and their build dates.
- Generate an inventory from each artifact.
- Mark the inventory as derived from the artifact, with the date.
- Try one clean rebuild and compare. Differences show how much versions drift.
- Record "no lockfile" as a finding with the list of affected repositories.
What to ask
- Does the build use a private mirror that freezes versions?
- Are any versions pinned inside the manifest itself?
- Has the product been rebuilt recently, or is the deployed artifact old?
- Is there a reason lockfiles are not committed, for example a library that is consumed by others?
The library exception
Some libraries intentionally do not commit lockfiles because consumers resolve versions. If the target ships libraries, the question shifts: which versions do their own applications resolve? Ask for those applications' inventories.
Remediation after close
Commit lockfiles for applications, enable installs that fail when the lockfile and manifest disagree, and add a build step that emits an inventory per release. This takes days for most projects and removes the largest source of uncertainty.
Safeguard can generate the inventory from a repository or an image and add a pull request gate so lockfile changes get reviewed. Try a free scan at gold.safeguard.sh/scan.
Quick check
Can I trust a manifest only inventory?
Treat it as a lower bound with ranges, not as proof of versions. Confirm against the built artifact.
Is this a deal breaker?
Usually no. It is a fixable engineering gap, but it should be recorded and priced into the integration plan, not ignored.
Sources
Last reviewed: 19 October 2026.