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}"