CI/CD component for provenance generation with Sigstore
Overview
As part of our incremental approach towards SLSA L3, we want to create CI/CD component to be used by customers that will integrate with Sigstore and abstract away the complexity of provenance attestation generation.
Success Criteria
- A merged functional CI/CD component that generates and signs a provenance statement using Sigstore, and tested in a sample pipeline.
Implementation Plan
Our architecture design document goes into details on the CI/CD component. This includes the following YAML configurations:
GitLab CI component
# .gitlab/components/provenance-signer.yml
component:
inputs:
variables:
TARGET_ARTIFACT: "" # Path to the artifact
BUNDLE_FILE: "provenance.json" # Output bundle file
RUNNER_METADATA_FILE: "artifacts-metadata.json" # This is the default filename when artifacts aren't explicitly named
id_tokens:
GITLAB_OIDC_TOKEN:
aud: sigstore
variables:
REKOR_SERVER: "https://rekor.sigstore.dev"
FULCIO_SERVER: "https://fulcio.sigstore.dev"
image: alpine:latest
before_script:
- apk add --update cosign jq
script:
- echo "Fetching GitLab Runner metadata..."
- export RUNNER_METADATA=$(jq -c . ${RUNNER_METADATA_FILE})
- echo "Generating predicate for ${TARGET_ARTIFACT}..."
- echo "${RUNNER_METADATA}" | jq -c .predicate > predicate.json
- echo "Attesting provenance for ${TARGET_ARTIFACT}..."
- cosign attest-blob --predicate predicate.json \
--type slsaprovenance1 \
--oidc-issuer "${CI_SERVER_HOST}" \
--fulcio-url "${FULCIO_SERVER}" \
--rekor-url "${REKOR_SERVER}" \
--identity-token "${GITLAB_OIDC_TOKEN}" \
--bundle "${BUNDLE_FILE}" \
"${TARGET_ARTIFACT}"
artifacts:
paths:
- ${BUNDLE_FILE}
- ${RUNNER_METADATA_FILE}
expire_in: 7d
Using the CI component
stages:
- build
- provenance
- verification
variables:
RUNNER_GENERATE_ARTIFACTS_METADATA: "true"
RUNNER_METADATA_FILE: "artifacts-metadata.json" # This is the default filename when artifacts aren't explicitly named
build_artifact:
stage: build
script:
- echo "Building artifact..."
- mkdir -p dist
- echo "Example artifact content" > dist/example-artifact.txt
artifacts:
paths:
- dist/
expire_in: 7d
generate_provenance:
stage: provenance
needs: ["build_artifact"]
component: .gitlab/components/provenance-signer.yml
variables:
TARGET_ARTIFACT: "dist/example-artifact.txt"
BUNDLE_FILE: "dist/provenance.json"
RUNNER_METADATA_FILE: "${RUNNER_METADATA_FILE}"
verify_provenance:
stage: verification
needs: ["generate_provenance"]
variables:
TARGET_ARTIFACT: "dist/example-artifact.txt"
BUNDLE_FILE: "dist/provenance.json"
script:
- echo "Verifying signed provenance..."
- cosign verify-blob-attestation --type slsaprovenance1 \
--bundle ${BUNDLE_FILE} \
--certificate-identity-regexp ".*" \
--certificate-oidc-issuer ${CI_SERVER_URL} \
${TARGET_ARTIFACT}
Edited by Nate Rosandich