Skip to content

What is PEP 740?

PEP 740: Index support for digital attestations defines how a package index such as PyPI accepts, stores, and serves cryptographically signed attestations for uploaded distributions. Accepted and marked Final in 2024, it standardizes the answer to a question installers could not previously ask: who actually published this file?

What an attestation proves

A digital attestation is a signed statement bound to a specific distribution file (a wheel or sdist). It records the identity that produced the file and the artifact’s hash, signed so that anyone can verify the binding without trusting the index to be honest.

The signature covers who published the file, not what the file contains. A reader can already inspect a wheel’s contents; what they cannot otherwise confirm is whether the upload came from the project’s real release pipeline or from an attacker who stole a token. An attestation closes that gap.

Why the index needs a standard

Sigstore and in-toto existed before PEP 740. What was missing was an agreement on how an index ingests these attestations and hands them back. PEP 740 specifies that contract:

  • An upload API that accepts attestation objects alongside each distribution
  • Retrieval of those attestations through PyPI’s HTML and JSON indexes, so installers can fetch them at resolve time
  • A fixed attestation object format every index and client can parse

Without that shared format, each tool would invent its own way to attach and read provenance, and an installer would have no guarantee that an attestation was present or parseable.

How an attestation is structured

PEP 740 attestations are in-toto v1 Statement objects signed through Sigstore. The signature uses ECDSA over the NIST P-256 curve with SHA-256 digests. A statement binds a subject (the distribution and its hash) to a predicate, a typed claim about that file.

PyPI accepts two predicate types: SLSA Provenance (https://slsa.dev/provenance/v1), which describes how the file was built, and PyPI Publish (https://docs.pypi.org/attestations/publish/v1), which asserts only that a trusted publisher uploaded the file. The publish predicate is what the PyPA publish action and attest-action produce, and its predicate field is empty because the signing identity carries the claim. This is the statement PyPI serves for the attrs 25.1.0 wheel:

{
  "_type": "https://in-toto.io/Statement/v1",
  "subject": [
    {
      "name": "attrs-25.1.0-py3-none-any.whl",
      "digest": {
        "sha256": "c75a69e28a550a7e93789579c22aa26b0f5b83b75dc4e08fe092980051e1090a"
      }
    }
  ],
  "predicateType": "https://docs.pypi.org/attestations/publish/v1",
  "predicate": null
}

Sigstore’s keyless signing removes the key-management burden for open source. Instead of maintaining a long-lived private key, a publisher signs with a short-lived certificate tied to an OpenID Connect (OIDC) identity, the same identity that trusted publishing already uses. For a package built in GitHub Actions, that identity is the workflow itself, and PyPI records it as the publisher’s kind, repository, workflow, and environment.

How publishing and verification work

On the publishing side, every path starts from a trusted publisher, because PyPI rejects attestations signed by any other identity. The PyPA publish action generates and uploads attestations by default. For uv publishes, astral-sh/attest-action writes the attestation files before uv publish uploads them, and the pypi-attestations CLI covers GitLab CI/CD and Google Cloud. How to publish Python packages with digital attestations shows each workflow.

On the reading side, each attested file on pypi.org shows a Provenance entry linking back to the workflow that produced it. For programmatic checks, the PyPI Integrity API exposes the signing identity and source workflow for each artifact, and pypi-attestations verify pypi checks a file against it. pip and uv do not yet reject unsigned packages by default; attestations today are evidence a consumer can record and audit rather than an install-time gate, one signal among the checks in how to vet a package before installing it.

Why a leaked token no longer hides an attack

Before PEP 740, a leaked upload token let an attacker publish a malicious release that looked identical to a legitimate one. With attestations recorded, that release either has no Provenance entry or carries a different publisher identity. pylock.toml reserves an attestation-identities table so that identity can be pinned in a lockfile and reviewed as a diff; Why pylock.toml includes digital attestations explains that design and what installers write today.

Last updated on