A hands-on technical reference for platform engineers operationalizing Nix-based SBOMs, CVE remediation, and supply chain controls in real C

Syft vs Nix2sbom vs Native Nix SBOM Tooling Comparison

Nix's derivation-based provenance breaks standard SBOM tools designed for filesystem scanning.

· 10 min read
Cover illustration for “Syft vs Nix2sbom vs Native Nix SBOM Tooling Comparison”
SBOM Generation Workflows · September 25, 2026 · 10 min read · 2,232 words

Why Nix provenance differs fundamentally from what most SBOM tools expect

Software supply chain compliance is arriving on a fixed schedule, and most SBOM tools were built for a world where Nix doesn't exist. Nix records provenance in a form that filesystem scanners cannot see at all; the tool a team picks now affects whether its documentation holds up under audit two years from now. Get the choice wrong, and an auditor's question exposes the gap at the worst possible moment: when the SBOM has no way to answer it.

Nix builds packages as pure functions of their inputs. Feeding the same inputs into the same derivation produces an output that comes out identical, byte for byte, every time. That single design choice moves provenance to the derivation graph, a different place in the system. It doesn't live in the filesystem artifact running on a server. It lives in the derivation graph, the network of .drv files recording exactly which inputs, which build steps, and which dependencies produced a given package.

The Nix store backs this up structurally. Every path is content-addressed, and the relationships between packages sit directly inside those .drv files rather than getting inferred after the fact by parsing a manifest or walking installed files on disk. Most package managers work the other way around: a tool has to guess "this depends on that" once the software already exists on disk, reconstructing intent from leftover evidence instead of reading it straight from the build.

The depth here is easy to underestimate. Compile a plain hello-world program in C through the standard Nix build environment, and it pulls in over 150 packages once gcc, stdenv, glibc, bash, and the bootstrapping infrastructure needed to get a compiler running are all counted. None of that survives into the deployed binary. A scanner looking at the finished artifact sees one file, with no way to know that 150-plus packages went into producing it, because that information was never encoded anywhere the scanner can reach.

The split that matters is runtime versus buildtime. The full closure of a Nix derivation includes compilers, build tools, and standard libraries used during the build and then discarded from what ships. A tool that only inspects the deployed binary misses that whole buildtime layer, and that layer happens to be exactly where a lot of supply chain risk concentrates: compromised build tools, poisoned compiler toolchains, tampered intermediate dependencies. If that layer is missed, the SBOM documents the shell, not the process that filled it.

How Syft generates SBOMs and where its Nix coverage stops

Syft is the most widely used open-source SBOM generator on the market, with a GitHub following north of 6,000 stars, a CLI-first design, support for 30-plus package ecosystems, and export to both SPDX and CycloneDX. It earned that popularity by working well at the layer where most software actually lives: container images, filesystem trees, archives.

It works as an external scanner. It looks at a finished artifact, a Docker image or an unpacked filesystem, and figures out what's inside by matching files against known package signatures. Paired with Grype for vulnerability lookups, that combination covers the core requirement in Executive Order 14028 and the machine-readable inventory expectations coming out of the EU Cyber Resilience Act in an afternoon of setup. For most application stacks, that's the whole job, and there's no case for reaching past it.

Nix breaks the model Syft depends on, and it breaks it completely rather than partially. Syft never sees a .drv file. It sees the store paths that made it into the final image, with no way to reconstruct the buildtime closure that produced them, no visibility into patches applied mid-build, and no path back to the upstream source repository a package came from. It scans what's there, not what was used to build what's there. For a Nix-built environment, that gap separates an inventory from a supply chain record, and treating the two as interchangeable is where compliance programs quietly fail.

Vendor tooling built on top of Syft, policy engines, NIST and FedRAMP compliance automation, centralized SBOM management for federal and regulated environments, inherits that same ceiling. Such tooling can enforce policy on whatever Syft reports. It cannot enforce policy on the buildtime layer Syft never captured in the first place, no matter how sophisticated the policy engine sitting on top of it looks. That's the part procurement teams tend to miss when they assume a platform built on that kind of scanner "handles" Nix because it runs without erroring out.

What nix2sbom does, and its current maturity level limits its use in production

nix2sbom starts from the opposite end of the problem. Instead of scanning a finished artifact, it reads Nix derivations directly and builds an SBOM from the derivation graph itself, with support for standard SBOM output formats.

Internally it constructs a graph representing the relationships between Nix store paths the way Nix itself understands them, then walks that graph to identify source derivations, detect patches applied during the build, and map Nix-specific package attributes onto standard Package URLs (PURLs), the identifier format most vulnerability databases expect. That design keeps the core graph logic separate from the mechanics of serializing to a given output format, a sound architectural choice where the hard part, reconstructing the graph, stays decoupled from the easy part, writing it out.

What that buys in practice is real depth. nix2sbom works by reconstructing the derivation graph, propagating metadata through it, and tracking patches applied along the way. The approach aims for a transparent view into the software supply chain of a Nix environment, built by reconstructing the package hierarchy from derivations rather than guessing at it from installed files.

That's genuine capability, closing exactly the buildtime gap Syft can't touch. It is not, however, a tool to bet a compliance deadline on sight unseen. Treat it the way any actively developed CLI utility deserves to be treated: run it against a specific environment, vet the output line by line, and confirm the numbers before anyone signs off on them. Betting a December compliance deadline on a tool nobody has stress-tested against the actual production flake is the mistake to avoid here, not a hypothetical one.

Diagram: What Each Tool Sees in a Nix Build. Visualizes: Visualize the stark coverage gap between filesystem scanners and derivation-native tools against the actual Nix build stack.

The native Nix SBOM ecosystem: sbomnix, nix-sbom-helper, and Genealogos compared on capability

Three more tools work closer to the Nix build model than Syft does, and each stakes out different ground on scope and integration. Of the three, sbomnix is the one built for production use today. The other two solve narrower problems well, but neither is a general-purpose replacement.

sbomnix, developed by tiiuae, is the most feature-complete of the group, and it isn't one tool so much as a suite. sbomnix itself generates an SBOM from a flake reference or a store path, nixgraph queries and visualizes the dependency graph, vulnxscan runs vulnerability scanning against the generated SBOM, and additional tools including a provenance command round out the set. By default it reports runtime dependencies, but a --buildtime flag switches it to traverse the full .drv closure, the same 150-plus-package layer described earlier, compilers and bootstrapping infrastructure included.

When the target is a flake reference, sbomnix pulls in nixpkgs metadata: descriptions, licenses, maintainers, homepage links. Both its CycloneDX and SPDX outputs record a set of nixpkgs-specific fields (nixpkgs:metadata_source_method, nixpkgs:path, nixpkgs:rev, nixpkgs:flakeref, nixpkgs:version, nixpkgs:message), giving an auditor a direct trail back to the exact nixpkgs revision a package came from. It also ships a provenance command that generates SLSA v1.0 compliant attestation files in JSON, directly relevant to the attestation language in EO 14028, plus a flakevuln tool that runs as a GitHub Action or local CLI for daily vulnerability scans on Nix flake projects.

All of this comes out of the Ghaf Framework, a Nix-based deployment project, so the tooling has already been exercised somewhere that isn't a demo environment. There's a real trade-off in runtime mode, though: scanning has to build the target to know what its runtime dependencies actually are, which means realizing whatever's being scanned. Buildtime mode sidesteps that cost.

nix-sbom-helper, from cyberus-technology, takes a narrower but sharper focus: flake integration, full stop. Rather than running as a separate command after the build, it gets added as a flake input and called directly, nix-sbom-helper.sbomsForFlakeOutputs self, wiring SBOM generation into the build graph itself instead of bolting it on afterward. By default it produces attributes for every package and every nixosConfiguration defined in a flake.

Its reproducibility story is explicit: build timestamps are forced to a fixed value, so the SBOM output itself is reproducible right alongside the underlying package. That guarantee only goes as far as sbomnix's own guarantees for the same input, since nix-sbom-helper builds on sbomnix's engine rather than replacing it. NixOS system coverage exists too, through nix-sbom-helper.support.buildSbom { input = iso.config.system.build.toplevel; }, though that path is less direct than the flake-output case. For a team already flake-first that wants SBOM output treated as a build artifact rather than a side job, this is the tool built for exactly that workflow, and nothing else on this list fits the niche as well.

Genealogos, developed at Tweag under an NLNet NGI0-entrust grant, generates BOMs in a standard component-manifest format (JSON and XML, compliant with the 1.3, 1.4, and 1.5 CycloneDX specifications) from output produced by Nix evaluation tools, currently nixtract. As of May 2026 it carries 55 GitHub stars. The grant is also funding a public website with pre-generated SBOMs for every package in nixpkgs, alongside a human-readable viewer, a meaningful piece of ecosystem infrastructure if it ships as planned.

Genealogos works at what's described as the "Nix level," and that has a real cost: it misses certain runtime-injected dependencies, things like asset bundles or references to a font service embedded in some packages, because pulling string contexts out of Nix code isn't a fully solved problem yet. Running it also means running two tools instead of one, Genealogos plus nixtract, a pipeline one practitioner described as something that "involved another thing called nixtract and you sort of start to lose the will." That's a real usability cost next to Syft's single-binary experience. Genealogos outputs CycloneDX only, no SPDX, a gap for any team whose compliance workflow specifically requires the ISO-standardized SPDX format.

Format support, dependency graph fidelity, and compliance readiness across all three approaches

On format flexibility, Syft still wins outright: SPDX and CycloneDX both, no caveats. nix2sbom supports multiple output formats, and sbomnix, and by inheritance nix-sbom-helper, matches it too, with the nixpkgs metadata extensions layered into both output formats as a bonus. Genealogos is the outlier here, CycloneDX only, versions 1.3 through 1.5, with no SPDX path. Any team whose compliance workflow runs on SPDX, common in license-compliance contexts tied to ISO standardization, needs to look elsewhere or plan on converting after the fact.

Dependency graph fidelity is where the native Nix tools separate from Syft structurally, not incrementally. Picking Syft for a Nix environment produces an SBOM that will be wrong in a specific, predictable way: it sees whatever sits in the filesystem of a finished image and nothing else. It cannot see the buildtime closure, cannot see patches applied mid-build, and cannot trace a package back to its upstream git source, because none of that information persists into the deployed artifact. That is the option to rule out first for any team running Nix in production, no matter how convenient the existing Syft pipeline feels.

nix2sbom narrows that gap by reconstructing the package hierarchy straight from derivations, with patch tracking built into the approach. sbomnix goes further still: runtime closure by default, full buildtime closure on request, reaching the over-150-package depth in a trivial C program that a filesystem scanner has no way to reach. Genealogos sits in between, working at the Nix level but with a known, acknowledged gap around runtime-injected string-context dependencies.

The CycloneDX 1.7 specification adds BOM types that go beyond software entirely: SaaSBOM, HBOM, AI/ML-BOM, CBOM, native VEX support. Tools still outputting older CycloneDX versions, which currently includes Genealogos at 1.3 through 1.5, will need updates before they can produce those newer BOM types, a detail that matters for anyone planning compliance documentation more than a year or two out.

On SLSA provenance specifically, sbomnix stands alone among the tools discussed here with a dedicated provenance command generating SLSA v1.0 compliant attestation files. That capability speaks directly to attestation requirements already active under EO 14028 and likely to resurface in implementing acts under the CRA.

None of this is academic. Under the CRA, vulnerability and incident reporting obligations took effect September 11, 2026, and full SBOM requirements apply from December 11, 2027, with penalties reaching €15 million or 2.5% of global annual turnover for non-compliance, and documentation retention required for ten years after a product ships. In the US, EO 14028 is already being enforced in federal procurement: vendors without SBOMs are losing contracts now, not at some point down the road. Supply chain attacks are estimated to cost $80.6 billion in 2026, a rise of 76 percent over 2023 figures. Against that backdrop, choosing between a filesystem scanner and a derivation-native tool comes down to one question: does the resulting document reflect what was actually built, or only what happened to survive until deployment? For anything running on Nix, only one of those answers holds up under audit, and it's the one that starts from the .drv file, which starts from the finished image.

Sources

  1. Best SBOM Tools 2026: Syft Leads OSS, FOSSA Leads Commercial
  2. GitHub - anchore/syft: CLI tool and library for generating a Software Bill of Materials from container images and filesystems
  3. FOSDEM 2026 - Describing Nix closures using SBOMs
  4. GitHub - tiiuae/sbomnix: SBOM, provenance, dependency graph, and vulnerability tools for Nix.
  5. Nix State of the SBOM | Engelen Open Source
  6. pkg.go.dev
  7. deepwiki.com
  8. github.com

More in SBOM Generation Workflows