Verify provenance for Python wheel artifacts

Retrieve the provenance for Python wheel content from the Pulp Integrity API to verify their origin and integrity.

Before you begin

Note
Python requires that the username and password be passed as HTTP basic authentication.

Procedure

  1. Set shell variables for the wheel to verify:
    WHEEL='<filename>.whl'
      PACKAGE='<package>'
      VERSION='<version>'
      REPOSITORY='<repository>'
      LIGHTWELL_USERNAME='<service-account-username>' 
      LIGHTWELL_TOKEN='<service-account-token>'

    where:

    <filename>
    Specifies the complete filename of the wheel to verify, including the .whl extension. For example, typer-0.16.1-0-py3-none-any.whl.
    <package>
    Specifies the normalized Python project name that is used by the Pulp Integrity API. For example, typer.
    <version>
    Specifies the Python package version that is used by the Pulp Integrity API, for example: 0.16.1
    <repository>
    Specifies the Lightwell Python repository path segment that contains the wheel, for example, validated.
    <service-account-username>
    Specifies the username for your Lightwell Network service account.
    <service-account-token>
    Specifies the token for your Lightwell Network service account.
  2. Download the Red Hat RELEASE3 public key from the Red Hat Product Signing Keys page and extract the Privacy-Enhanced Mail (PEM) public-key block:
    $ curl -fsSLo release3.txt \
          https://security.access.redhat.com/data/63405576.txt
      sed -n '/-----BEGIN PUBLIC KEY-----/,$p' release3.txt > release3.pub
  3. Download the wheel:
    $ curl -fsSLO \
           --user "${LIGHTWELL_USERNAME}:${LIGHTWELL_TOKEN}" \
           "https://packages.redhat.com/api/pulp-content/lightwell/python/${REPOSITORY}/${WHEEL}"
  4. Download the wheel provenance from the Pulp Integrity API:
    $ curl -fsSLo "${WHEEL}.provenance.json" \
             --user "${LIGHTWELL_USERNAME}:${LIGHTWELL_TOKEN}" \
    "https://packages.redhat.com/api/pypi/lightwell/python/${REPOSITORY}/integrity/${PACKAGE}/${VERSION}/${WHEEL}/provenance/"
    Pulp serves the provenance in Python Enhancement Proposal (PEP) 740 form.
  5. Map the envelope fields to the matching Dead Simple Signing Envelope (DSSE) representation that is accepted by Cosign:
    jq '
          .attestation_bundles[0].attestations[0].envelope
          | {
              payloadType: "application/vnd.in-toto+json",
              payload: .statement,
              signatures: [{sig: .signature}]
            }
        ' "${WHEEL}.provenance.json" > "${WHEEL}.dsse.json"
  6. Verify the RELEASE3 signature and the wheel digest binding in the SLSA statement with Cosign:
    $ cosign verify-blob-attestation \
          --insecure-ignore-tlog \
          --type https://slsa.dev/provenance/v1 \
          --key release3.pub \
          --signature "${WHEEL}.dsse.json" \
          "${WHEEL}"