Skip to main content

A library to convert between Sigstore Bundles and PEP-740 Attestation objects

Project description

pypi-attestations

CI PyPI version Packaging status

A library to generate and convert between Sigstore Bundles and PEP 740 Attestation objects.

[!IMPORTANT] This library is an implementation detail within the reference implementation of PEP 740. Most users should not need to interact with it directly; see the PyPI documentation for full details.

Installation

python -m pip install pypi-attestations

Usage as a library

See the full API documentation here.

Signing and verification

Use these APIs to create a PEP 740-compliant Attestation object by signing a Python artifact (i.e: sdist or wheel files), and to verify an Attestation object against a Python artifact.

from pathlib import Path

from pypi_attestations import Attestation, Distribution
from sigstore.oidc import Issuer
from sigstore.sign import SigningContext
from sigstore.verify import Verifier, policy

dist = Distribution.from_file(Path("test_package-0.0.1-py3-none-any.whl"))

# Sign a Python artifact
issuer = Issuer.production()
identity_token = issuer.identity_token()
signing_ctx = SigningContext.production()
with signing_ctx.signer(identity_token, cache=True) as signer:
    attestation = Attestation.sign(signer, dist)

print(attestation.model_dump_json())

# Verify an attestation against a Python artifact
attestation_path = Path("test_package-0.0.1-py3-none-any.whl.attestation")
attestation = Attestation.model_validate_json(attestation_path.read_bytes())
verifier = Verifier.production()
policy = policy.Identity(identity="example@gmail.com", issuer="https://accounts.google.com")
attestation.verify(verifier, policy, dist)

Low-level model conversions

These conversions assume that any Sigstore Bundle used as an input was created by signing a distribution file.

from pathlib import Path
from pypi_attestations import Attestation
from sigstore.models import Bundle

# Sigstore Bundle -> PEP 740 Attestation object
bundle_path = Path("test_package-0.0.1-py3-none-any.whl.sigstore")
with bundle_path.open("rb") as f:
    sigstore_bundle = Bundle.from_json(f.read())
attestation_object = Attestation.from_bundle(sigstore_bundle)
print(attestation_object.model_dump_json())

# PEP 740 Attestation object -> Sigstore Bundle
attestation_path = Path("attestation.json")
with attestation_path.open("rb") as f:
    attestation = Attestation.model_validate_json(f.read())
bundle = attestation.to_bundle()
print(bundle.to_json())

Usage as a command line tool

[!IMPORTANT] The python -m pypi_attestations CLI is intended primarily for experimentation, and is not considered a stable interface for generating or verifying attestations. Users are encouraged to generate attestations using the official PyPA publishing action or via this package's public Python APIs.

python -m pypi_attestations --help
usage: pypi-attestation [-h] [-v] [-V] COMMAND ...

Sign, inspect or verify PEP 740 attestations

positional arguments:
  COMMAND        The operation to perform
    sign         Sign one or more inputs
    verify       Verify one or more inputs
    inspect      Inspect one or more inputs

options:
  -h, --help     show this help message and exit
  -v, --verbose  run with additional debug logging; supply multiple times to
                 increase verbosity (default: 0)
  -V, --version  show program's version number and exit

Signing a package

[!NOTE] If run locally (i.e. not within GitHub Actions or another source of ambient OIDC credentials), this will open a browser window to perform the Sigstore OAuth flow.

# Generate a whl file
make package
python -m pypi_attestations sign dist/pypi_attestations-*.whl

Inspecting a PEP 740 Attestation

[!WARNING] Inspecting does not mean verifying. It only prints the structure of the attestation.

python -m pypi_attestations inspect dist/pypi_attestations-*.whl.publish.attestation

Verifying a PEP 740 Attestation

[!NOTE] The example below uses an email with --identity, but actual PyPI attestations will be signed with a machine identity corresponding to the workflow that generated the attestation. The format of that identity

python -m pypi_attestations verify --staging \
  --identity william@yossarian.net \
  test/assets/rfc8785-0.1.2-py3-none-any.whl

The attestation present in the test has been generated using the staging environment of Sigstore and signed by the identity william@yossarian.net.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pypi_attestations-0.0.13.tar.gz (29.1 kB view details)

Uploaded Source

Built Distribution

pypi_attestations-0.0.13-py3-none-any.whl (20.8 kB view details)

Uploaded Python 3

File details

Details for the file pypi_attestations-0.0.13.tar.gz.

File metadata

  • Download URL: pypi_attestations-0.0.13.tar.gz
  • Upload date:
  • Size: 29.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for pypi_attestations-0.0.13.tar.gz
Algorithm Hash digest
SHA256 2f61f3ba81d836b54359096f43f19d7ddb15fa13542d3236b9caf92bd8b3af65
MD5 2568fd11814c7671a889759109ab0cfa
BLAKE2b-256 807275f402ce0fc4ebb9e77e66b311140bf2354d97613c153617f900f2e6a54c

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypi_attestations-0.0.13.tar.gz:

Publisher: GitHub
  • Repository: trailofbits/pypi-attestations
  • Workflow: release.yml
Attestations:
  • Statement type: https://in-toto.io/Statement/v1
    • Predicate type: https://docs.pypi.org/attestations/publish/v1
    • Subject name: pypi_attestations-0.0.13.tar.gz
    • Subject digest: 2f61f3ba81d836b54359096f43f19d7ddb15fa13542d3236b9caf92bd8b3af65
    • Transparency log index: 142610047
    • Transparency log integration time:

File details

Details for the file pypi_attestations-0.0.13-py3-none-any.whl.

File metadata

File hashes

Hashes for pypi_attestations-0.0.13-py3-none-any.whl
Algorithm Hash digest
SHA256 cc4213c2aab3b9d06d54c353ed7f23febf92b2409b0bb4ce5d8ade0aadcbd6ed
MD5 9118d20fc4f535cbfa83dd3cec46917c
BLAKE2b-256 383b0b124adb548b85220e8ffd3656457869f27da2320e6c925b2557ab097646

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypi_attestations-0.0.13-py3-none-any.whl:

Publisher: GitHub
  • Repository: trailofbits/pypi-attestations
  • Workflow: release.yml
Attestations:
  • Statement type: https://in-toto.io/Statement/v1
    • Predicate type: https://docs.pypi.org/attestations/publish/v1
    • Subject name: pypi_attestations-0.0.13-py3-none-any.whl
    • Subject digest: cc4213c2aab3b9d06d54c353ed7f23febf92b2409b0bb4ce5d8ade0aadcbd6ed
    • Transparency log index: 142610048
    • Transparency log integration time:

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page