pypi/pypi-attestations

GitHub: pypi/pypi-attestations

用于对 Python 分发包进行 Sigstore 签名并生成 PEP 740 证明的库和命令行工具。

Stars: 14 | Forks: 10

# pypi-attestations [![CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/a598c3318e201012.svg)](https://github.com/pypi/pypi-attestations/actions/workflows/tests.yml) [![PyPI version](https://badge.fury.io/py/pypi-attestations.svg)](https://pypi.org/project/pypi-attestations) [![Packaging status](https://repology.org/badge/tiny-repos/python:pypi-attestations.svg)](https://repology.org/project/python:pypi-attestations/versions) 一个用于生成 Sigstore Bundles 和 [PEP 740] Attestation 对象并在它们之间进行转换的库。 ## 安装 ``` python -m pip install pypi-attestations ``` ## 作为库使用 在[此处]查看完整的 API 文档。 ### 签名与验证 使用这些 API,通过签署 Python artifact(即:sdist 或 wheel 文件)来创建符合 PEP 740 标准的 `Attestation` 对象,并针对 Python artifact 验证 `Attestation` 对象。 ``` from pathlib import Path from pypi_attestations import Attestation, Distribution from sigstore.oidc import Issuer from sigstore.models import ClientTrustConfig 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")) # 签名 Python artifact trust_config = ClientTrustConfig.production() issuer: Issuer = Issuer(trust_config.signing_config.get_oidc_url()) signing_ctx = SigningContext.from_trust_config(trust_config) with signing_ctx.signer(issuer.identity_token(), cache=True) as signer: attestation = Attestation.sign(signer, dist) print(attestation.model_dump_json()) # 针对 Python artifact 验证 attestation attestation_path = Path("test_package-0.0.1-py3-none-any.whl.attestation") attestation = Attestation.model_validate_json(attestation_path.read_bytes()) identity = policy.Identity(identity="example@gmail.com", issuer="https://accounts.google.com") attestation.verify(identity=identity, dist=dist) ``` ### 底层模型转换 这些转换假设任何作为输入使用的 Sigstore Bundle 都是通过签署分发包创建的。 ``` 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()) ``` ## 作为命令行工具使用 ``` 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 convert Convert a Sigstore bundle into a PEP 740 attestation 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 ``` ### 签署包 ``` # 生成 whl 文件 make package pypi-attestations sign dist/pypi_attestations-*.whl ``` ### 检查 PEP 740 Attestation ``` pypi-attestations inspect dist/pypi_attestations-*.whl.publish.attestation ``` ### 验证 PEP 740 Attestation ``` pypi-attestations verify attestation \ --identity https://github.com/trailofbits/pypi-attestations/.github/workflows/release.yml@refs/tags/v0.0.19 \ test/assets/pypi_attestations-0.0.19.tar.gz ``` ### 验证 PyPI 包 ``` # 从 PyPI 下载 artifact (及其 provenance) 并验证 pypi-attestations verify pypi --repository https://github.com/sigstore/sigstore-python \ pypi:sigstore-3.6.1-py3-none-any.whl # 或者,使用 direct URL: pypi-attestations verify pypi --repository https://github.com/sigstore/sigstore-python \ https://files.pythonhosted.org/packages/70/f5/324edb6a802438e97e289992a41f81bb7a58a1cda2e49439e7e48896649e/sigstore-3.6.1-py3-none-any.whl # 使用本地文件验证 artifact 及其 provenance pypi-attestations verify pypi --repository https://github.com/sigstore/sigstore-python \ --provenance-file ~/Downloads/sigstore-3.6.1-py3-none-any.whl.provenance \ ~/Downloads/sigstore-3.6.1-py3-none-any.whl ``` 此命令从 PyPI 下载 artifact 及其 provenance。然后针对 provenance 验证 artifact,同时检查 provenance 的签名身份是否与用户指定的仓库匹配。 ### 将 Sigstore bundle 转换为 PEP 740 Attestation ``` pypi-attestations convert --output-file /tmp/rfc8785-0.1.2-py3-none-any.whl.publish.attestation \ test/assets/rfc8785-0.1.2-py3-none-any.whl.sigstore ``` ## 许可证 ``` Copyright 2024 Trail of Bits Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ```
标签:Attestation, CVE, OIDC, PEP 740, PyPI, Python, Sdist, Sigstore, SLSA, Wheel, 代码签名, 依赖安全, 可验证构建, 密码学, 工件证明, 库文件, 手动系统调用, 数字签名, 文档安全, 文档结构分析, 无后门, 软件供应链安全, 软件完整性, 远程方法调用, 逆向工具, 验证器