A manifest diff, an ordinary SBOM component diff, and an integrity-drift check answer three different questions. Treating them as interchangeable leaves a blind spot: a component can keep the same name and version while its bytes change.
| Layer | Primary question | Strongest signal | Important blind spot |
|---|---|---|---|
| Manifest or lockfile diff | What dependency resolution did the developer request or record? | Direct and resolved version changes | Does not prove what entered the built artifact |
| Ordinary SBOM component diff | What components does each build report? | Added, removed, and version-changed components | A same-name, same-version replacement can look unchanged |
| Hash / integrity drift | Did the recorded bytes change without the component version changing? | Unexpected same-version hash change | Signals investigation; it does not by itself prove malicious intent |
These layers complement one another. sbomlyze does not replace a package manager, an SBOM generator, signature verification, or a vulnerability scanner. It reviews the evidence produced by the build and classifies what changed between two points in time.
- github.com/google/uuid v1.5.0 + github.com/google/uuid v1.6.0
That is an excellent review surface. But the manifest describes dependency resolution, not necessarily the final artifact. It may omit operating-system packages, copied binaries, vendored files, build-stage tools, generated assets, or components introduced by the container base image.
Comparing two inventories reveals changes a manifest misses: a new transitive package, an OS package added by a base-image update, a component removed from the final artifact, a resolved version that differs from the source declaration, or a license and supplier change.
The naive implementation is a JSON diff, which produces noise from timestamps, serial numbers, generated identifiers, and ordering. sbomlyze matches component identity using stable identifiers when available — Package URLs and CPEs, with format-specific references and names as fallbacks — so it can compare SPDX, CycloneDX, and Syft evidence without identical layouts.
example at version 1.4.2 in both SBOMs, a name-and-version diff calls it unchanged — even if the component bytes are different.Integrity drift is the narrow condition where sbomlyze matches a component in both SBOMs, sees the same version, and finds that its recorded hash set changed. The version says consumers should be receiving the same release, while the hash says the recorded content is not the same. Those two facts disagree, so a reviewer should establish why before merging.
Some explanations are benign. The point of the check is not to label every hash change an attack. It is to prevent a silent mismatch from passing as “no dependency change.”
Hash comparison is only as stable as the evidence around it. Before making the check required:
That last case is small, specific, and easy to miss. Giving it its own policy signal turns an ambiguous SBOM diff into a review decision.