1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
|
"""Convert Sigstore attestations to PEP 740.
See https://github.com/trailofbits/pypi-attestations.
"""
# resolution fails without betterproto and protobuf-specs
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "pypi-attestations==0.0.22",
# "betterproto==2.0.0b6",
# ]
# ///
from __future__ import annotations
import json
import sys
from base64 import b64decode
from pathlib import Path
from pypi_attestations import Attestation, Distribution
from sigstore.models import Bundle
from sigstore.verify.policy import Identity
ROOT = Path(__file__).resolve().parent.parent
DIST = ROOT / 'dist'
bundle_path = Path(sys.argv[1])
signer_identity = sys.argv[2]
for line in bundle_path.read_bytes().splitlines():
dsse_envelope_payload = json.loads(line)['dsseEnvelope']['payload']
subjects = json.loads(b64decode(dsse_envelope_payload))['subject']
for subject in subjects:
filename = subject['name']
assert (DIST / filename).is_file()
# Convert attestation from Sigstore to PEP 740
print(f'Converting attestation for {filename}')
sigstore_bundle = Bundle.from_json(line)
attestation = Attestation.from_bundle(sigstore_bundle)
attestation_path = DIST / f'{filename}.publish.attestation'
attestation_path.write_text(attestation.model_dump_json())
print(f'Attestation for {filename} written to {attestation_path}')
print()
# Validate attestation
dist = Distribution.from_file(DIST / filename)
attestation = Attestation.model_validate_json(attestation_path.read_bytes())
identity = Identity(identity=signer_identity)
attestation.verify(identity=identity, dist=dist)
print(f'Verified {attestation_path}')
|