Seth Larson @ 2025-12-22
This year I authored PEP 770 which proposed a new standardized location for Software Bill-of-Materials (SBOM) data within Python wheel archives. SBOM data can now be stored in (package)-(version).dist-info/sboms/. You can see the canonical specification on packaging.python.org.
While writing this document we also reserved all .dist-info/ subdirectory names within a registry for future use in other standards. Reviewers agreed that this method of defining file-based metadata (such as SBOMs, but also licenses) is a great mechanism as it doesn’t require creating a new metadata field and version.
Creati…
Seth Larson @ 2025-12-22
This year I authored PEP 770 which proposed a new standardized location for Software Bill-of-Materials (SBOM) data within Python wheel archives. SBOM data can now be stored in (package)-(version).dist-info/sboms/. You can see the canonical specification on packaging.python.org.
While writing this document we also reserved all .dist-info/ subdirectory names within a registry for future use in other standards. Reviewers agreed that this method of defining file-based metadata (such as SBOMs, but also licenses) is a great mechanism as it doesn’t require creating a new metadata field and version.
Creating a new metadata field in particular requires large amounts of “head-of-line blocking” to rollout completely to an ecosystem of independent packaging installers, builders, publishers, and the Python Package Index; the proposed method side-steps all of this by making inclusion in the directory the mechanism instead.
So now that this PEP is published, what has happened since? A few things:
Unmasking the Phantom Dependency problem
In case you missed it, I published a white paper on this project with Alpha-Omega. If you want to learn more about the whole project from end-to-end, this is a good place to start!
Auditwheel and cibuildwheel
Back in 2022 there was a public issue opened for Auditwheel asking to generate an SBOM during the auditwheel repair command. Now in Auditwheel v6.5.0 which was released in early November, Auditwheel will now automatically generate SBOM data and include the SBOM in the PEP 770 specified location (.dist-info/sboms/auditwheel.cdx.json).
The manylinux images adopted the new auditwheel version soon after publication. These images are used by common Python wheel building platforms like cibuildwheel and multibuild. Because this functionality was enabled by default we can look at Python wheel data and determine how many packages already supply PEP 770 SBOM data:
When querying the pypi-code.org dataset including all code within Python wheels I was able to find 332 projects on PyPI that are shipping SBOM data in their wheels:
SELECT repository, project_name, path
FROM './dataset-*.parquet'
WHERE archive_path LIKE '%.dist-info/sboms/%'
AND skip_reason == '' LIMIT 10;
Of these projects, these are the top-10 most downloaded with SBOM data so far:
| Project | Downloads/Month |
|---|---|
| greenlet | 205M |
| numba | 33M |
| pymssql | 27M |
| ddtrace | 17M |
| psycopg-binary | 14M |
| faiss-cpu | 13M |
| logbook | 6M |
| simsimd | 2M |
| clang-format | 2M |
| nodejs-wheel-binaries | 1M |
There are far more projects which will likely require SBOM data on their bundled dependencies, so I’ll continue watching the numbers grow over time!
RedHat and Fedora adopt PEP 770
Back in July of this year, Miro Hrončok asked if there was a mechanism for specifying the "origin" of a package, as many tools incorrectly assume that any package that’s installed to an environment originated from the Python Package Index (and therefore would use a Package URLs like pkg:pypi/). Their use-case was Python packages provided by the system package manager, such as rpm on Fedora and RedHat Linux. Vulnerability scanners were incorrectly assuming packages like pip were vulnerable as older versions of pip are packaged, but with vulnerability patches backported and applied to older versions.
SBOMs to the rescue! Miro adopted PEP 770 for Fedora and RedHat Linux to reduce false-positives in vulnerability scans by defining the actual correct Package URL for the installed package in the SBOM:
{
"bomFormat": "CycloneDX",
"specVersion": "1.6",
"components": [
{
"type": "library",
"name": "python3.11-setuptools",
"version": "65.5.1-3.el9",
// This Package URL is for the RedHat distribution,
// of setuptools, not the PyPI distribution.
"purl": "pkg:rpm/redhat/python3.11-setuptools@65.5.1-3.el9?arch=src"
}
]
}
If scanners adopt this approach and other Linux distros do as well, there will be far fewer false-positives from scanning Python environments using those Linux distros. A win for everyone! Miro is asking for feedback on this approach by consuming tools.
Wow, you made it to the end!
- Share your thoughts with me on Mastodon, email, or Bluesky.
- Browse this blog’s archive of 154 entries.
- Check out this list of cool stuff I found on the internet.
- Follow this blog on RSS or the email newsletter.
- Go outside (best option)