99A library to generate and convert between Sigstore Bundles and [ PEP 740]
1010Attestation objects.
1111
12+ > [ !IMPORTANT]
13+ > This library is an implementation detail within the reference implementation
14+ > of [ PEP 740] . Most users should not need to interact with it directly;
15+ > see the [ PyPI documentation] for full details.
16+
1217## Installation
1318
1419``` bash
1520python -m pip install pypi-attestations
1621```
1722
18- ## Usage as a command line tool
19-
20- ```` bash
21- python -m pypi_attestations --help
22- usage: pypi-attestation [-h] [-v] [-V] COMMAND ...
23-
24- Sign, inspect or verify PEP 740 attestations
25-
26- positional arguments:
27- COMMAND The operation to perform
28- sign Sign one or more inputs
29- verify Verify one or more inputs
30- inspect Inspect one or more inputs
31-
32- options:
33- -h, --help show this help message and exit
34- -v, --verbose run with additional debug logging; supply multiple times to
35- increase verbosity (default: 0)
36- -V, --version show program' s version number and exit
37- ````
38-
39- ### Signing a package
40-
41- ```bash
42- # Generate a whl file
43- make package
44- python -m pypi_attestations sign dist/pypi_attestations-*.whl
45- ```
46-
47- _Note_: This will open a browser window to authenticate with the Sigstore
48- OAuth flow.
49-
50- ### Inspecting a PEP 740 Attestation
51-
52- ```bash
53- python -m pypi_attestations inspect dist/pypi_attestations-*.whl.publish.attestation
54- ```
55- _Warning_: Inspecting does not mean verifying. It only prints the structure of
56- the attestation.
57-
58- ### Verifying a PEP 740 Attestation
59-
60- ```bash
61- python -m pypi_attestations verify --staging \
62- 63- test/assets/rfc8785-0.1.2-py3-none-any.whl
64- ```
65- The attestation present in the test has been generated using the staging
66- environment of Sigstore and signed by William.
67-
6823## Usage as a library
6924
7025See the full API documentation [ here] .
@@ -77,19 +32,19 @@ Use these APIs to create a PEP 740-compliant `Attestation` object by signing a P
7732``` python
7833from pathlib import Path
7934
80- from pypi_attestations import Attestation
35+ from pypi_attestations import Attestation, Distribution
8136from sigstore.oidc import Issuer
8237from sigstore.sign import SigningContext
8338from sigstore.verify import Verifier, policy
8439
85- artifact_path = Path("test_package-0.0.1-py3-none-any.whl")
40+ dist = Distribution.from_file( Path(" test_package-0.0.1-py3-none-any.whl" ) )
8641
8742# Sign a Python artifact
8843issuer = Issuer.production()
8944identity_token = issuer.identity_token()
9045signing_ctx = SigningContext.production()
9146with signing_ctx.signer(identity_token, cache = True ) as signer:
92- attestation = Attestation.sign(signer, artifact_path )
47+ attestation = Attestation.sign(signer, dist )
9348
9449print (attestation.model_dump_json())
9550
@@ -98,10 +53,11 @@ attestation_path = Path("test_package-0.0.1-py3-none-any.whl.attestation")
9853attestation = Attestation.model_validate_json(attestation_path.read_bytes())
9954verifier = Verifier.production()
10055policy
= policy.Identity(
identity = " [email protected] " ,
issuer = " https://accounts.google.com" )
101- attestation.verify(verifier, policy, attestation_path )
56+ attestation.verify(verifier, policy, dist )
10257```
10358
10459### Low-level model conversions
60+
10561These conversions assume that any Sigstore Bundle used as an input was created
10662by signing a distribution file.
10763
@@ -125,6 +81,79 @@ bundle = attestation.to_bundle()
12581print (bundle.to_json())
12682```
12783
84+ ## Usage as a command line tool
85+
86+ > [ !IMPORTANT]
87+ > The ` python -m pypi_attestations ` CLI is intended primarily for
88+ > experimentation, and is not considered a stable interface for
89+ > generating or verifying attestations. Users are encouraged to
90+ > generate attestations using [ the official PyPA publishing action]
91+ > or via this package's [ public Python APIs] .
92+
93+ ```` bash
94+ python -m pypi_attestations --help
95+ usage: pypi-attestation [-h] [-v] [-V] COMMAND ...
96+
97+ Sign, inspect or verify PEP 740 attestations
98+
99+ positional arguments:
100+ COMMAND The operation to perform
101+ sign Sign one or more inputs
102+ verify Verify one or more inputs
103+ inspect Inspect one or more inputs
104+
105+ options:
106+ -h, --help show this help message and exit
107+ -v, --verbose run with additional debug logging; supply multiple times to
108+ increase verbosity (default: 0)
109+ -V, --version show program' s version number and exit
110+ ````
111+
112+ ### Signing a package
113+
114+ > [!NOTE]
115+ > If run locally (i.e. not within GitHub Actions or another source of
116+ > ambient OIDC credentials), this will open a browser window to perform
117+ > the Sigstore OAuth flow.
118+
119+ ```bash
120+ # Generate a whl file
121+ make package
122+ python -m pypi_attestations sign dist/pypi_attestations-*.whl
123+ ```
124+
125+ ### Inspecting a PEP 740 Attestation
126+
127+ > [!WARNING]
128+ > Inspecting does not mean verifying. It only prints the structure of
129+ > the attestation.
130+
131+ ```bash
132+ python -m pypi_attestations inspect dist/pypi_attestations-*.whl.publish.attestation
133+ ```
134+
135+ ### Verifying a PEP 740 Attestation
136+
137+ > [!NOTE]
138+ > The example below uses an email with `--identity`, but actual PyPI
139+ > attestations will be signed with a machine identity corresponding to the
140+ > workflow that generated the attestation. The format of that identity
141+
142+ ```bash
143+ python -m pypi_attestations verify --staging \
144+ 145+ test/assets/rfc8785-0.1.2-py3-none-any.whl
146+ ```
147+
148+ The attestation present in the test has been generated using the staging
149+ environment of Sigstore and signed by the identity `[email protected] `. 150+
128151[PEP 740]: https://peps.python.org/pep-0740/
129152
130153[here]: https://trailofbits.github.io/pypi-attestations
154+
155+ [public Python APIs]: https://trailofbits.github.io/pypi-attestations
156+
157+ [the official PyPA publishing action]: https://github.com/pypa/gh-action-pypi-publish
158+
159+ [PyPI documentation]: https://docs.pypi.org/attestations
0 commit comments