Skip to content

VOL 08 / CH 10 / LESSON 01

10.1 Dependencies and SBOM: Knowing What's Inside an Artifact ​

The previous chapter bound checks to a delivery digest. This chapter follows that digest to ask what the package contains and who can account for its origin.

The software supply chain includes more than open-source packages: it also contains source code repositories, build scripts, compilers, base images, CI actions, plugins, package repositories, and distribution channels. An SBOM answers the question: What components make up this product? But it does not alone prove that those components are trustworthy or that the build process hasn't been tampered with.

Dependency Graph Is Closer to Real Risk Than a List ​

text
application
├── direct dependency A
│   └── transitive dependency C
├── generated client B
├── base image packages
└── bundled runtime / native library

A manifest expresses the scope of what a developer intends to include, while a lockfile usually records resolved versions and, in some ecosystems, integrity digests. Lockfile guarantees vary. The final artifact may vary due to differences in packaging, trimming, or dynamic downloads. All three perspectives are necessary; scanning only package.json or pom.xml is insufficient.

During installation, disable unnecessary lifecycle scripts, use a controlled registry or mirror, verify checksums and signatures, and pin CI actions and base image digests. To mitigate dependency confusion, ensure private namespaces do not fall back to publicly available, higher-version packages with the same name.

SBOM Binding to Specific Artifacts ​

A practical SBOM should be tied to an artifact digest and include sufficient information about component identity, version, supplier, relationships, and the tool used to generate it. SPDX and CycloneDX are common formats. Choose according to the ecosystem and consumers instead of inventing an incompatible JSON format.

text
artifact sha256:abc...
  contains package-url pkg:maven/...@version
  dependsOn ...
  generatedBy tool/version at timestamp

An SBOM generated from scanning a source directory may differ from the final container SBOM. At release time, the SBOM should be derived from or verified against the final artifact, with specific testing for fat JARs, statically linked binaries, vendored source code, and multi-stage images.

SBOM Quality Requires Validation ​

  • completeness: Are all components within the final artifact identified?
  • correctness: Are component names, versions, and PURLs/CPEs accurate?
  • dependency relationships: Are both direct and transitive dependencies preserved?
  • freshness: Is the SBOM tied to the current digest, not the previous build?
  • integrity: Is the SBOM signed or attested alongside the artifact?
  • availability: Can deployment locations for each component be queried at runtime?

Use a fixed test artifact containing known application libraries, base-system packages, and a manually added native binary. Compare each item with the SBOM, then remove a component or update its version and rebuild: the SBOM should change accordingly. Preserve the path and digest of unidentified binaries and mark them unknown rather than silently claiming complete coverage.

Vulnerability Matching Requires Context ​

CVE matching can be misaligned due to ecosystem naming conventions, backporting, or incorrect version range interpretation. A distribution may retain the upstream version while changing its package revision to backport a fix. Check the complete distribution version and advisory rather than upstream semver alone; and the presence of a library does not guarantee that vulnerable functions are reachable.

VEX can express the state and rationale of a product regarding a vulnerability, for example, "not affected because the vulnerable code is not present." VEX needs a verifiable producer identity, exact product/artifact scope, analytical evidence, and an update timestamp; it cannot serve as a generic, batched "not exploitable" exemption label.

Event priority should be determined by factors such as real-world exploitation, reachability, exposure surface, and data impact. Even if a vulnerability is currently unreachable, the conditions under which it should be re-evaluated after configuration or feature changes must be documented.

Dependency Updates Are a Continuous Delivery Capability ​

Small, automated updates are easier to review and roll back than infrequent, large-scale upgrades. Dependency update bots must operate within a change strategy: they should enforce constraints on source origins, version ranges, test coverage, changelogs, and signature validation. They must never bypass review simply because a "bot commit" was made.

Dependencies that can no longer be maintained should be replaced, isolated, or removed. Forking shifts responsibility for patching, releases, and vulnerability response to the team, rather than removing risk from the dashboard alone.

The next lesson checks whether the expected source and trusted build platform produced this digest.

References ​

Built with VitePress | Software Systems Atlas