Skip to main content

pypi-verify-now

This is a trust-on-first-use (TOFU) solution to the problem of verifying the build provenance of packages downloaded from PyPI, that is usable now for brave and/or impatient users that want to experiment with this immediately or even sooner.

Pre-abandonware

This tool is intended to never reach version 1.0. Instead, whenever Pip starts verifying signatures client-side, this tool will go to version 99.9 and be end-of-lifed.

How-to and security considerations

First run the tool in TOFU mode with arguments supported by pip lock -- the arguments will be passed on as-is to pip-lock, so you can use -r to process a requirements file, or --group to verify packages specified by a PEP735 dependency group, or any other mechanism supported by pip as long as it generates a lock file:

TOFU=1 python -m pypi_verify_now --group build

This generates a file called .provenance.txt, which for each package lists the repository URL that's expected to have signed it. If a package is signed, but its originating repository URL is not recorded here, the package signature will not be considered valid. The file is expected to be committed to source control, and any changes to be reviewed.

After this, for example in a CI pipeline, create a build step that runs without TOFU:

python -m pypi_verify_now --group build

If this ever fails the build, one of the following things happened:

  1. A package is being signed from a different URL
  2. A package has started uploading signatures to PyPI, but the repo URL isn't yet known
  3. A package is no longer signed, but was expected to be signed in .provenance.txt
  4. A malicious package was somehow uploaded to PyPI

All of these will fail the build. The .provenance.txt will need to be updated in some way. Removing failing packages from .provenance.txt and re-running with TOFU=1 will make the tool happy, but ONLY the user can review the validity of the resulting changes to .provenance.txt. If this manual review doesn't happen, I don't think the resulting security posture is meaningfully better.

Configuration

Three settings can be configured through passing in environment variables:

  • TOFU=1 (default 0): set to '1' to generate an updated version of the provenance file
  • STRICT=1 (default 0): set to '1' to fail if any package is missing a signature (unlikely to be usable currently in 2025Q3)
  • FILENAME=... (default .provenance.txt): path to file where for each dependency originating repository URL is configured

Security warning

For my use case, today, I think this is good enough, or at least better than no signature verification. My understanding of security, OIDC and SigStore is more than zero, but still limited. See the license text; "PROVIDED AS-IS" etc.

I expect the PyPA/pip developers to spend a lot more time thinking about this problem and tackle nuances that I haven't thought about, and that this process understandably takes longer than the few hours I spent banging out this script, so it's advisable to evaluate risks accordingly.

TOC/TOU

Now that pip provisionally supports installing from pylock.toml using the --requirements/-r flag, it's possible to avoid a Time-of-check/Time-of-use (TOC/TOU) race by first generating a lock file, verifying that lock file using --lock-file/-L, and then installing from that same lock file.

Links

Talk from PyCon 2025:

Metadata

Release files for pypi-verify-now 0.8.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pypi-verify-now 0.8.1
File Size Uploaded Provenance Actions
pypi_verify_now-0.8.1.tar.gz 7.9 kB With provenance Details for pypi_verify_now-0.8.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pypi-verify-now 0.8.1
File Interpreter ABI Platform Actions
pypi_verify_now-0.8.1-py3-none-any.whl Python 3 none any Details for pypi_verify_now-0.8.1-py3-none-any.whl

Total release size: 14.3 kB

Release files / pypi_verify_now-0.8.1.tar.gz

Download URL pypi_verify_now-0.8.1.tar.gz
Size 7.9 kB
Tags Source
SHA-256 checksum
How to use checksums
9f36335b1ec41cb4bca8f253af030a341fd8a6efc295ffb761de8f5c77cd302b
BLAKE2b-256 checksum
How to use checksums
fdc0d44ad531c5e9a5e7556a360cef882f859da3d21886190e903832658a5716
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.2.0 CPython/3.14.5

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitLab CI/CD, verified by PyPI on Jun 17, 2026.

Transparency log

Release files / pypi_verify_now-0.8.1-py3-none-any.whl

Download URL pypi_verify_now-0.8.1-py3-none-any.whl
Size 6.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0fd11dd3991fdeae7e57baa906bb166c91c767590c7abba22678213908e68a1a
BLAKE2b-256 checksum
How to use checksums
144f04d7aef7c49df0527c56376294283a1959c95ee8ed02c86c17691dd74d50
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.2.0 CPython/3.14.5

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitLab CI/CD, verified by PyPI on Jun 17, 2026.

Transparency log

Security for pypi-verify-now 0.8.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for pypi_verify_now-0.8.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitLab CI/CD, verified by PyPI on Jun 17, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page