Skip to content

software bill of materials (SBOM)

A software bill of materials, or SBOM, is a formal, machine-readable inventory of every component, version, and dependency that goes into building a piece of software. You typically generate one automatically during a build and attach it to a release as a signed artifact. Security tools then consume the file to answer questions like “are any of your deployed services using the vulnerable version of this library?”

How It Shows Up in Practice

For a Python developer, an SBOM is typically generated as a step in a CI pipeline right after dependency resolution. Teams reach for one of three common tools, all of which read a project’s lockfile or installed environment and write a JSON document on the way out:

Language: Shell
$ # OWASP cyclonedx-bom (ships the cyclonedx-py CLI)
$ cyclonedx-py requirements requirements.txt -o bom.json

$ # PyPA pip-audit, which doubles as a vulnerability scanner
$ pip-audit -r requirements.txt -f cyclonedx-json -o sbom.cdx.json

$ # Anchore syft, a polyglot scanner that also handles container images
$ syft dir:. -o cyclonedx-json=sbom.cdx.json

The resulting file lists each library, its pinned version, and a unique identifier such as a package URL of the form pkg:pypi/requests@2.31.0. Once produced, the SBOM is uploaded as a build artifact, attached to a GitHub release, or pushed alongside a container image so downstream consumers can verify what they are running. The same file becomes the input to a threat modeling session, a license audit, or an incident response when a new CVE drops.

A Python program only needs the standard library to read one:

Language: Python
import json

sbom = {
    "bomFormat": "CycloneDX",
    "specVersion": "1.6",
    "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"},
    ],
}

print(f"{sbom['bomFormat']} {sbom['specVersion']}")
print(f"Components: {len(sbom['components'])}")
for component in sbom["components"]:
    print(f"- {component['name']} {component['version']}")
Language: Program Output
CycloneDX 1.6
Components: 2
- requests 2.31.0
- flask 3.0.0

Common Variations

Two formats dominate practice. CycloneDX is maintained by OWASP and standardized as Ecma-424. It is the format most security tooling produces by default and is favored for vulnerability tracking. SPDX is maintained by the Linux Foundation and standardized as ISO/IEC 5962:2021. It carries richer license metadata and is favored by legal and compliance teams.

NTIA’s “Minimum Elements for a Software Bill of Materials” defines seven required fields that any usable SBOM must include: supplier name, component name, version, other unique identifiers like PURL or CPE, dependency relationships, the SBOM author, and a timestamp.

SBOMs are mandated in a growing list of contexts. US Executive Order 14028, signed in May 2021, directed federal agencies to require SBOMs from software vendors. The FDA has required SBOMs for premarket submissions of medical “cyber devices” since October 2023.

The EU Cyber Resilience Act extends the requirement to any “product with digital elements” sold in Europe, with reporting obligations starting September 2026 and full SBOM obligations from December 2027.

Tutorial

Using Python's pip to Manage Your Projects' Dependencies

What is pip? In this beginner-friendly tutorial, you'll learn how to use pip, the standard package manager for Python, so that you can install and manage packages that aren't part of the Python standard library.

basics tools

For additional information on related topics, take a look at the following resources:


By Martin Breuss • Updated May 29, 2026