pypi/pypi-attestations
GitHub: pypi/pypi-attestations
用于对 Python 分发包进行 Sigstore 签名并生成 PEP 740 证明的库和命令行工具。
Stars: 14 | Forks: 10
# pypi-attestations
[](https://github.com/pypi/pypi-attestations/actions/workflows/tests.yml)
[](https://pypi.org/project/pypi-attestations)
[](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, 代码签名, 依赖安全, 可验证构建, 密码学, 工件证明, 库文件, 手动系统调用, 数字签名, 文档安全, 文档结构分析, 无后门, 软件供应链安全, 软件完整性, 远程方法调用, 逆向工具, 验证器