A Software Bill of Materials is an itemized inventory of every component that makes up a piece of software - every direct dependency, and every dependency of those dependencies, down to specific versions. It sounds like paperwork until a component you didn't know you depended on turns out to have a critical vulnerability, and an SBOM is the difference between finding out in minutes versus days of manual auditing.

Why This Became Urgent, Not Optional

The 2021 Log4Shell vulnerability (a critical remote code execution flaw in the widely-used Log4j logging library) exposed how few organizations could quickly answer "do we use this component, and where?" - Log4j wasn't usually a direct dependency, it was buried three or four layers deep inside other libraries applications did depend on directly. Teams with an existing SBOM could query it in minutes. Teams without one spent days manually grepping dependency trees across every service they ran, under active exploitation pressure the whole time.

This is also increasingly a compliance requirement, not just good practice: the US Executive Order 14028 requires SBOMs for software sold to federal agencies, and the EU's Cyber Resilience Act introduces similar obligations for products sold in the EU market.

The Two Real Formats

SPDX (Software Package Data Exchange) originated in open-source license compliance and is now an ISO standard (ISO/IEC 5962:2021). CycloneDX was purpose-built for security use cases from the start and has slightly richer vulnerability-relevant metadata. Neither is objectively "the right one" - many tools support exporting to both, and the choice often comes down to what a specific customer or regulatory requirement asks for by name.

Generating One for Your Stack

# Node.js / npm
npx @cyclonedx/cyclonedx-npm --output-file sbom.json

# Python
pip install cyclonedx-bom
cyclonedx-py -o sbom.json

# PHP / Composer
composer require --dev cyclonedx/cyclonedx-php-composer
composer CycloneDX:make-sbom --output-file=sbom.json

# Universal - scans a container image or filesystem, not just one ecosystem
syft packages dir:. -o cyclonedx-json > sbom.json

Generate it as part of your build pipeline, not as a manual one-off - a Bill of Materials for a version of the application that no longer matches what's actually deployed is worse than no SBOM, because it creates false confidence.

What to Actually Do With It

An SBOM by itself is an inventory, not a security control - its value comes from matching it against a vulnerability database on an ongoing basis, not from generating it once. Tools like grype (paired with Syft) or GitHub's own dependency graph can take an SBOM and flag every component with a known CVE, which is the step that turns "we know what we have" into "we know what's actually a problem right now."

# Match a CycloneDX SBOM against known vulnerabilities
grype sbom:sbom.json

Keeping It Current

Dependencies update, get added, and get removed on every deploy - an SBOM generated once at launch and never regenerated drifts out of sync within weeks on any actively-developed codebase. Wire generation into CI so a fresh SBOM is produced (and ideally, automatically checked against a vulnerability database) on every build, the same way tests run automatically rather than being triggered manually before a release.

Where This Fits With Shieldome

See our SBOM generation documentation for how Shieldome produces and exports this automatically as part of a scan, and our SaaS security scanner for the broader CI/CD-integrated scanning this fits into. Create a free account to see it generated from a real scan.