Safeguard
SBOM

How Snyk Container generates a Software Bill of Materials...

How Snyk Container statically scans image layers, parses OS package databases and lockfiles, and exports CycloneDX/SPDX SBOMs — mechanically explained.

Karan Patel
Cloud Security Engineer
Updated 7 min read

Software Bills of Materials are only as good as the mechanism that produces them, and container images make that mechanism harder than it looks. An image is a stack of compressed filesystem layers, each potentially adding, modifying, or deleting files from the one below it — there's no single manifest listing "everything installed here." Snyk Container, part of the broader Snyk software platform, solves this by statically unpacking the image, walking its layers, and cross-referencing what it finds against package manager databases and language-ecosystem lockfiles, without ever running the container. The result is exported as a CycloneDX or SPDX document that lists every OS package and application dependency Snyk could identify, along with the layer that introduced it. This post walks through how that scanning and generation process actually works, based on Snyk's publicly documented CLI behavior and platform docs, and where an SBOM produced this way still leaves gaps that downstream tooling needs to fill.

What does Snyk Container actually scan to build an SBOM?

Snyk Container scans the unpacked filesystem of a container image, not a running instance of it. When you point the Snyk CLI at an image reference — for example snyk container sbom --format=cyclonedx1.4+json myapp:latest — the CLI pulls the image manifest and layer blobs from the registry or local Docker/Podman daemon, extracts each layer's tarball, and reconstructs the final filesystem state layer by layer. This static approach matters because it means the SBOM reflects what's actually shipped in the image artifact, including files added by intermediate build stages that never execute at runtime. It also means the scan doesn't need the application to start, have network access, or expose any instrumentation — a meaningful difference from runtime-dependent inventory approaches that only see what a process actually loads during a given execution path.

How does Snyk identify OS-level packages inside the image?

Snyk identifies OS packages by reading the same package manager metadata the OS itself uses to track installed software. For Debian and Ubuntu-based images that means parsing the dpkg status database (typically /var/lib/dpkg/status); for RHEL, CentOS, and Fedora-based images it reads the RPM database; for Alpine it reads the apk installed-packages database at /lib/apk/db/installed. Snyk maintains distro-specific detection logic because each package manager stores version strings, package names, and dependency metadata in a different format, and vulnerability data has to be matched against the correct distro's advisory feed — a package named openssl on Alpine and the same name on Debian can map to different CVE fix versions. This is why Snyk Container's supported base image list is explicit about which distros and versions it can parse reliably, rather than claiming universal OS coverage.

How does Snyk detect application-layer dependencies inside the image?

Snyk detects application dependencies by locating and parsing the manifest and lockfiles for each language ecosystem it finds baked into the image filesystem — package-lock.json or yarn.lock for Node.js, requirements.txt or installed dist-info metadata for Python, Gemfile.lock for Ruby, go.sum for Go modules, and JAR/WAR archive manifests for Java. For compiled or bundled artifacts where a lockfile isn't present in the final image (common in multi-stage Docker builds where the build stage is discarded), Snyk falls back to fingerprinting techniques such as inspecting JAR file contents against a database of known artifact hashes. This layered detection is why scan accuracy depends heavily on how an image was built: a Dockerfile that copies only a compiled binary into a minimal final stage gives Snyk far less to work with than one that leaves lockfiles or an installed package cache in place, which is one reason Snyk's documentation recommends multi-stage builds still retain dependency metadata where feasible for accurate scanning.

What SBOM formats does Snyk Container actually output?

Snyk Container outputs SBOM documents in CycloneDX and SPDX formats, generated on demand through the snyk container sbom CLI command rather than as a byproduct of every scan. As of Snyk's current CLI documentation, supported output options include CycloneDX 1.4 and 1.5 in both JSON and XML, and SPDX 2.3 in JSON, selected via a --format flag such as --format=cyclonedx1.5+json or --format=spdx2.3+json. This matters for compliance workflows because CycloneDX and SPDX are the two formats referenced by NTIA minimum-elements guidance and increasingly required in federal and enterprise procurement language; generating in the standard's native structure (rather than converting from a proprietary internal format) reduces the chance of field mapping errors when the SBOM is consumed by another tool, such as a vulnerability database matcher or an artifact repository that ingests SBOMs for provenance tracking.

How does layer attribution help prioritize what to fix?

Layer attribution matters because it tells you whether a vulnerable package came from the base image you chose or from something your own build steps installed. Snyk Container tracks which Dockerfile instruction or layer digest introduced each detected package by correlating the file paths found during extraction back to the layer that last modified them, and surfaces this in both snyk container test output and the base image remediation advice Snyk provides. In practice this means a scan result doesn't just say "CVE-2024-XXXX is present in libssl 3.0.2" — it can indicate that the package arrived via the node:18-slim base layer rather than a line in your application's own Dockerfile, which changes the remediation path entirely: bumping a base image tag versus patching an application-level dependency are different pull requests with different owners. This layer-level context is part of what separates an SBOM meant for compliance filing from one that's actually actionable for a build team triaging findings.

Does a point-in-time image scan capture the full software supply chain story?

A single image scan captures a static snapshot of one build, not the provenance of how that build happened or what changes between rebuilds. Snyk Container's SBOM answers "what packages and versions are present in this image right now," which is exactly what CycloneDX and SPDX are designed to express, but it doesn't independently attest to build reproducibility, verify that the registry-hosted image matches the source commit it claims to originate from, or track SBOM drift across the dozens of rebuilds a typical CI pipeline produces per week. Organizations that need to answer "did this image change unexpectedly between last week's scan and today's deploy" or "can we prove this artifact was built from the branch we think it was" are asking questions that sit adjacent to SBOM generation rather than inside it — which is where build attestation and artifact provenance tooling become the complementary layer.

How Safeguard Helps

Safeguard treats the SBOM as a starting point rather than the finish line. Where Snyk Container's snyk container sbom command gives you an accurate, standards-compliant inventory of a single image at scan time, Safeguard focuses on the supply chain context around that artifact: continuously tracking which commit and pipeline run produced a given image digest, flagging when a rebuilt image's dependency set drifts from its expected baseline without a corresponding source change, and correlating SBOM data across every service in a fleet so a newly disclosed CVE in a shared base layer or transitive dependency can be traced to every affected image without re-running a scan on each one manually. For teams already generating CycloneDX or SPDX documents through Snyk software, Safeguard ingests those SBOMs as input and layers provenance verification, cross-repository dependency correlation, and drift detection on top — turning a per-image inventory into a continuously monitored supply chain record. If your CI pipeline already produces SBOMs today, the question worth asking isn't whether the inventory is accurate, but whether anything is watching how it changes.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.