Comparison
An AI-generated SBOM is a guess about your build. Regulators ask for a record.
Asking a model to write an SBOM is quick, and the output looks right. It is not the same artifact as an SBOM recorded during the build, and the difference matters under the CRA and the 2026 CISA minimum elements.
Why teams try it
The appeal is real. You paste a repository or a lockfile into a coding assistant, ask for CycloneDX, and a well formed document comes back in seconds. It can even fill fields that scanners routinely leave empty. The supplier field is the usual example: most generators have no source for it, so it comes out blank. A model asked for a complete document can write something into every field.
That last point is the problem in miniature. A scanner that does not know the supplier leaves the field blank. A model that does not know it may still produce a plausible answer. The document looks more complete and is less reliable.
What the model actually sees
A model generating an SBOM works from the text in front of it: manifests, lockfiles, perhaps a Dockerfile. It does not observe the build. So it cannot see:
- which versions the package manager resolved when a repository commits no lockfile,
- packages restored from a CI cache,
- tools, OS packages and binaries that a build step downloads directly,
- what went into a compiled binary that ships alongside an almost empty manifest.
Two repositories show how thin the files can be. expressjs/express 5.2.1 commits no lockfile, so its
package.json lists dependencies as version ranges and the actual versions are decided at install time.
The anthropics/claude-code repository at v2.1.259 has no dependency manifest or lockfile of any kind,
and its published npm package declares zero runtime dependencies while wrapping a prebuilt native binary.
A deterministic scanner pointed at that repository has nothing to read that describes the binary.
A model given the same files has the same lack of information, and more freedom to fill the gap.
Hallucination is a documented failure mode
Language models name packages that do not exist. The best measured case is code generation rather than SBOM writing, but the failure it shows applies just as well to a list of components. A USENIX Security 2025 study generated 576,000 code samples with 16 models and found an average hallucinated package rate of at least 5.2% for commercial models and 21.7% for open source models, with 205,474 unique hallucinated package names. GitHub's own documentation for Copilot Autofix warns that it "may suggest fabricated dependencies published under statistically probable names."
Models also do not give the same answer twice. Anthropic's documentation states that "even with temperature set to 0, the results will not be fully deterministic and identical inputs may produce different outputs across API calls." Two SBOMs generated from the same commit can differ, and neither says which one is right.
In an SBOM, a hallucinated entry is not a harmless typo. A package that does not exist, or the wrong version of one that does, sends a vulnerability lookup to the wrong place, and the result comes back confident and wrong.
What the standards expect an SBOM to contain
NTIA minimum elements (2021)
The NTIA baseline defined seven data fields: supplier name, component name, version of the component, other unique identifiers, dependency relationship, author of SBOM data, and timestamp. It paired them with automation support and a set of practices and processes. Every field describes a fact about the software, not an opinion about it.
CISA 2026 minimum elements
On July 29, 2026, CISA, the NSA, the FBI and international partners published updated minimum elements that replace the 2021 baseline. Several additions are hard to satisfy without observing the build:
- SBOM Generation Context: "the relative software lifecycle phase and data available at the time the SBOM author generated the SBOM," with "before build," "build," and "after build" as examples. A model reading a repository is, at best, before build.
- Component Hash Value: "the output generated from applying a cryptographic hash algorithm to an executable component artifact." If the author does not have the artifact, "the SBOM author should indicate the value is unknown." A model that never touched the artifact cannot produce a hash, only text shaped like one.
- SBOM Tool Name and Version: the tool used to generate the SBOM has to be named.
- Coverage: "An SBOM should include information for all components that make up the target software, including transitive dependencies. There is no minimum depth."
- Explicitly identifying unknown information: the author "should explicitly state whether the information is unknown." A fabricated value is the opposite of that.
The EU Cyber Resilience Act
The CRA makes the SBOM a legal obligation for manufacturers of products with digital elements. Annex I, Part II requires them to "identify and document vulnerabilities and components contained in products with digital elements, including by drawing up a software bill of materials in a commonly used and machine-readable format covering at the very least the top-level dependencies of the products." Annex VII places the SBOM in the technical documentation, and a market surveillance authority can request it to check compliance with the essential requirements.
None of these texts bans AI tools. What they ask for is data that describes the actual product, and honest statements about what is unknown. An SBOM written from inference struggles with both.
| Capability | CRACI | AI-generated SBOM |
|---|---|---|
| Observes the build | Package traffic recorded during the job, plus CI caches | Works from the files and text it was given |
| Generation context | Build (recorded while the job ran) | Before build at best: the model never saw the build |
| Resolved versions | What the install actually fetched | From a lockfile, or guessed from a range |
| Unknowns stated | Five completeness states per job and per cache | Gaps and fabrications look like valid entries |
| Same input, same output | The same record every time | Output may differ between runs |
| Signed link to the shipped artifact | Provenance from artifact to build | |
| Works without running a build | Records builds on CRACI runners | Seconds from pasted files |
| Works outside GitHub Actions | GitHub Actions only today | Any repository or lockfile |
- Included
- Partly
- Not included
How CRACI produces the SBOM
CRACI runs your GitHub Actions jobs on its own runners. You change runs-on to craci, and
runs still appear in GitHub. While the job runs, a package-aware proxy observes traffic to package sources, so the
SBOM records what the build actually pulled, including transitive dependencies. Dependency evidence rides with CI
caches, so a package restored from a cache stays in the record.
- Ecosystems: npm, PyPI, RubyGems, Cargo, Go, Nix and OCI, plus OS and direct download sources.
- Completeness: every job and cache is marked Complete, Complete with connections, Incomplete, Unavailable or Not recorded, so unknowns are stated rather than filled in.
- Formats: CycloneDX and SPDX, with declared license metadata included in the export.
- Provenance: signed evidence (Ed25519 over SHA-512) links an artifact, including an OCI image, to the build that produced it.
CRACI automates a significant part of the supply chain visibility and evidence a wider CRA compliance process needs. It does not make a product compliant on its own. Build-time SBOM generation covers the details, and our CRA overview covers the timeline.
Where AI does help with SBOMs
Once you have a recorded SBOM, a model is good at working with it: summarizing which components carry risk, explaining an advisory in plain language, or drafting the documentation around it for a human to review. The rule is simple. Let the build produce the record, and let the model read it.
See the SBOM your build actually produces
Book a demo and we will record an SBOM for one of your builds, with its completeness state and provenance.
Book a demo