What an SBOM is, in one paragraph
A Software Bill of Materials (SBOM) is an inventory of every third-party component a piece of software depends on — name, version, and an identifier precise enough for procurement or security teams to look it up. CycloneDX is one of the two dominant SBOM standards (the other being SPDX), maintained by OWASP, currently at specification version 1.5. Unlike a SARIF report, an SBOM does not describe vulnerabilities — it describes what your software is made of. The two are complementary: SARIF answers "what did you find," an SBOM answers "what do you depend on."
Generate the SBOM
One flag, same CLI as everything else:
./staticcodeaudit-linux-x86_64 /path/to/project --sbom
This writes SCA-SBOM-<timestamp>.json next to the usual HTML report. The scanner auto-detects dependency manifest files in your project root and include paths — no extra configuration needed.
Manifest files it reads
Six dependency manifest formats are parsed directly, covering the languages this scanner audits for vulnerabilities:
| Manifest | Ecosystem |
|---|---|
requirements.txt / pyproject.toml |
PyPI (Python) |
package.json |
npm (JavaScript/TypeScript) |
pom.xml |
Maven (Java) |
build.gradle |
Gradle (Java) |
*.csproj |
NuGet (C#) |
composer.json |
Packagist (PHP) |
Each manifest is read once per scan (root directory plus configured include paths, deduplicated by normalized path) — a project with both requirements.txt and package.json gets components from both in the same SBOM.
What the file actually contains
A real example — two pinned dependencies in a requirements.txt:
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"metadata": {
"timestamp": "2026-08-07T18:30:12.104Z",
"tools": [{ "name": "StaticCodeAudit", "version": "1.0.0" }],
"component": {
"type": "application",
"name": "your-project",
"version": "1.0.0"
}
},
"components": [
{
"type": "library",
"name": "requests",
"version": "2.31.0",
"purl": "pkg:pypi/requests@2.31.0"
},
{
"type": "library",
"name": "flask",
"version": "3.0.0",
"purl": "pkg:pypi/flask@3.0.0"
}
]
}
Each component carries a Package URL (purl) — a standardised identifier (pkg:pypi/requests@2.31.0) that procurement tools and vulnerability databases can match without ambiguity. The export lists name, version and purl; it does not compute or embed file hashes for each dependency.
SBOM or SARIF — not both in the same run
SBOM and SARIF exports are mutually exclusive per invocation — they serve different consumers (procurement/inventory vs. vulnerability triage) and combining them would make both harder to parse correctly downstream:
$ ./staticcodeaudit-linux-x86_64 /path/to/project --sarif --sbom
❌ --sarif and --sbom are mutually exclusive. Use one or the other.
Run the scan twice in CI if a pipeline needs both artifacts from the same commit — each run takes well under a second on a small-to-medium codebase. See the SARIF export guide for the vulnerability side.
Where this fits for regulated entities
For organisations in scope of the EU NIS2 directive, Article 21(2)(d) requires "measures" covering supply-chain security. A CycloneDX SBOM — combined with SARIF vulnerability findings from the same codebase — is the kind of concrete, machine-readable evidence an auditor or procurement reviewer can act on: exactly what dependencies are in a given release, at what version, cross-referenced against known vulnerabilities. More detail on the regulated industries page.
Frequently asked questions
Does generating an SBOM send my dependency list anywhere?
No. The SBOM is built entirely from local files (your requirements.txt, package.json, etc.) and written to local disk. StaticCodeAudit makes zero outbound network calls during a scan — generating an SBOM does not change that, since no external database lookup is involved.
Does the SBOM include known vulnerabilities for each dependency?
No — that's what the --with-deps flag and the SARIF export are for. The SBOM itself is a pure inventory (CycloneDX's components array): name, version, purl. Cross-referencing components against vulnerability databases is a separate step, typically done by whatever system consumes the SBOM downstream.
What if my project has no recognised dependency manifest?
The SBOM is still generated, with an empty components array — valid CycloneDX 1.5, just describing an application with no declared third-party dependencies. This is expected for e.g. a pure-HTML or infra-as-code project with no requirements.txt/package.json equivalent.
Can I get an SBOM for a monorepo with multiple manifest files?
Yes — the scanner walks the project root plus every path listed under include in audit.config.json, and merges components from every manifest it finds (e.g. a root package.json and a nested backend/requirements.txt in the same repo both contribute to one SBOM).
See a full SBOM on real code
Open the live demo report — no install, no signup — or run the binary against your own project and inspect the generated SBOM directly.
Open the live report Download the demo binary