Skip to content

✨ feat(build): add SBOM timestamp and generator metadata - #3269

Merged
gaborbernat merged 2 commits into
pypa:mainfrom
gaborbernat:sbom-metadata-tools
Sep 19, 2026
Merged

gaborbernat merged 2 commits into
pypa:mainfrom
gaborbernat:sbom-metadata-tools

Conversation

@gaborbernat

Copy link
Copy Markdown
Contributor

The embedded SBOM's metadata block only carries the root component. auditwheel and Microsoft's bocpy, which hand-roll the same CycloneDX shape virtualenv does, both go further: auditwheel names itself in metadata.tools, and bocpy adds metadata.timestamp plus a nested metadata.tools.components entry for its own generator script. Neither puts build-environment details like the OS or Python version anywhere in the SBOM. That's the SLSA build provenance attestation's job, and the release workflow already generates one; duplicating it here would blur the line between what an SBOM describes (composition) and what an attestation describes (the build process), on top of risking the same reproducibility bug serialNumber had before #3268.

hatch_build.py now derives metadata.timestamp from hatchling's own get_reproducible_timestamp(), the helper it already uses for the wheel's zip entry timestamps, so setting SOURCE_DATE_EPOCH for a reproducible build still produces a byte-identical SBOM. 🔁 I built the wheel twice with a fixed SOURCE_DATE_EPOCH and diffed the resulting metadata.timestamp and serialNumber values to confirm it. metadata.tools.components names hatch_build.py as the generator with no version number, since it has no version of its own and ships in lockstep with virtualenv. tasks/validate_sbom.py checks both fields the same way it checks serialNumber.

auditwheel and bocpy both hand-roll the same CycloneDX shape virtualenv
does, and bocpy is the one precedent that adds metadata.timestamp and
metadata.tools rather than leaving them out. Neither precedent puts
build-environment details (OS, Python version, toolchain) anywhere in
the document: that's already covered separately by the SLSA build
provenance attestation the release workflow generates, so duplicating
it here would blur the SBOM/attestation split and risk reproducibility
if a runner's exact environment string ever varied between otherwise
identical builds.

metadata.timestamp is derived from hatchling's own
get_reproducible_timestamp(), the same SOURCE_DATE_EPOCH-aware helper
it uses for the wheel's own zip entries, so a reproducible build keeps
producing a byte-identical SBOM. metadata.tools names hatch_build.py
as the generator without a version number, since it isn't an
independently versioned package and ships in lockstep with virtualenv
itself.
@gaborbernat
gaborbernat merged commit f4f69f8 into pypa:main Sep 19, 2026
64 checks passed
@gaborbernat gaborbernat added the security Fixes a vulnerability or hardens the supply chain, CI or release label Sep 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement security Fixes a vulnerability or hardens the supply chain, CI or release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant