Skip to main content
RunBook Academy

Git, CI/CD & GitOpsLXX · ProvenanceGitHub

GitHub Actions artifact attestations — actions/attest and the platform-native provenance

Advanced⏱ ~26 mingitgh

What you'll learn

  • Use actions/attest-build-provenance@v1 to attach a SLSA build provenance to a build artifact
  • Use actions/attest-sbom@v1 to attach an SBOM attestation to a build artifact
  • Identify the workflow identity that signs the GitHub-generated attestation
  • Locate the attestation in the GitHub UI and via the gh CLI for audit

Prerequisites

Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x

Not yet marked complete on this device.

GitHub Actions produces SLSA build provenance and SBOM attestations natively. The actions/attest-build-provenance@v1 action generates a SLSA build provenance attestation for the workflow; the actions/attest-sbom@v1 action generates an SBOM attestation for a SBOM file produced earlier in the workflow. The attestations are signed using the OIDC identity of the workflow (the same pattern Part LXIX-03 taught for keyless cosign signing), stored in the GitHub attestations API and as OCI referrers in the registry, and exposed in the GitHub UI for audit. The platform does the work; the workflow declares the input.

The build provenance action

The provenance action is a single step in the workflow that runs after the artifact is built:

- name: Build artifact
  run: ./build.sh
- name: Attest build provenance
  uses: actions/attest-build-provenance@v1
  with:
    subject-path: ./dist/app-binary

The subject-path is the file or directory the attestation covers. The action computes the digest, generates a SLSA build provenance attestation with the workflow’s identity as the signer, signs the attestation with the OIDC token, and uploads the attestation to the GitHub attestations API. The attestation carries the SLSA build provenance shape (buildDefinition, runDetails, metadata); the verifier downstream reads the attestation and checks the source against the policy.

The SBOM action

The SBOM action attaches an SBOM to an artifact as a signed attestation. The SBOM is generated upstream (by syft, by trivy, by the team’s own tool) and passed to the action as a file:

- name: Generate SBOM
  run: syft packages dir:./dist -o spdx-json > sbom.spdx.json
- name: Attest SBOM
  uses: actions/attest-sbom@v1
  with:
    subject-path: ./dist/app-binary
    sbom-path: sbom.spdx.json

The subject-path is the artifact the build produced; the sbom-path is the SBOM file the upstream tool wrote. The action wraps the SBOM in an in-toto Statement with predicateType: https://spdx.dev/Document, signs the statement with the workflow’s OIDC identity, and uploads the attestation to the GitHub attestations API.

flowchart LR
    A["Source (commit)"] --> B["Build step"]
    B --> C["Artifact"]
    B --> D["SBOM (syft)"]
    C --> E["attest-build-provenance@v1"]
    D --> F["attest-sbom@v1"]
    E --> G["OIDC token"]
    F --> G
    G --> H["Signed attestation"]
    H --> I["GitHub attestations API"]
    H --> J["OCI referrer"]
    I --> K["Verifier"]
    J --> K
    K --> L["Admit"]
    K --> M["Deny"]

What the action produces

The action produces three artifacts: a GitHub attestations API entry (queryable from the GitHub UI and via gh attestation), an OCI referrer for container images (the same shape as the SBOM in Part LXVIII-04), and a Sigstore bundle that includes the Fulcio certificate and the Rekor entry. The three artifacts are the same attestation in three locations; the verifier can fetch from any of them.

The workflow identity

The attestation is signed with the OIDC identity of the workflow. The canonical value is:

https://github.com/org/repo/.github/workflows/build.yml@refs/heads/main

The verifier pins the workflow path and the ref. The wildcard https://github.com/org/.* is too permissive (the same lesson from Part LXIX-03). The OIDC issuer is https://token.actions.githubusercontent.com; the verifier pins the issuer as well. The two pins together are the policy that turns the attestation into a verifiable claim.

Production discipline

  1. Add both actions to every build workflow. The provenance and the SBOM are the two claims the verifier expects.
  2. Pin the workflow path in the verifier. A wildcard is too permissive; the specific path is the policy.
  3. Verify the attestation in the admission controller. The attestation is the policy input; the verifier is the policy enforcer.
  4. Audit the attestations in the GitHub UI. The attestations API is the audit interface; the team can search by artifact, by workflow, by date.

Cross-course references

  • Git, CI/CD & GitOps — Part LXIX-03 (Keyless Signing with Fulcio) is the OIDC identity pattern the actions reuse.
  • Git, CI/CD & GitOps — Part LXVIII-04 (SBOM Distribution and Attestation) is the SBOM attestation shape the attest-sbom action produces.
  • Git, CI/CD & GitOps — Part LXX-04 (SLSA Source Track) is the source side that the provenance names.

Quiz

Knowledge check · 4 questions

  1. Q1. Which GitHub Actions action generates a SLSA build provenance attestation for a build artifact and signs it with the workflow's OIDC identity?

  2. Q2. The GitHub-generated provenance attestation is signed with a long-lived team key that the team stores in GitHub Secrets.

  3. Q3. Name the two inputs that the actions/attest-sbom@v1 action requires and what each one identifies.

  4. Q4. Diagnose why the attestations are not visible in the GitHub UI and recommend the fix.

    Team T adds actions/attest-build-provenance@v1 and actions/attest-sbom@v1 to the build workflow. The workflow runs successfully; the artifact is uploaded. The audit team opens the GitHub UI and finds no 'Attestations' tab on the artifact. The team checks the GitHub REST API and confirms the attestation API endpoint returns 404 for the artifact ID.

Passing score: 75%. Answers are checked in this browser.