Why build pipelines are now a primary attack surface
Recent software supply chain breaches—SolarWinds, MOVEit, 3CX, and the Applied Materials ransomware incident among them—have shifted attention to a critical weakness: the build process itself. Attackers who compromise build infrastructure can inject malicious code into artifacts that are then distributed to customers and partners. Traditional controls such as source scanning and repository allowlists no longer suffice. Organizations must now treat the build system with the same rigor as production environments.
The SLSA (Supply-chain Levels for Software Artifacts) framework, governed by the Open Source Security Foundation, provides a structured path for hardening build pipelines. GitHub Artifact Attestations can simplify the journey, particularly for reaching SLSA Level 3.
SLSA at a glance
SLSA defines four levels of increasing build security maturity:
- Level 0: No security guarantees.
- Level 1: Provenance exists for traceability, with minimal tamper resistance.
- Level 2: Provenance is signed by a managed build platform, deterring casual tampering.
- Level 3: Provenance comes from a hardened, tamper-resistant build platform.
Provenance is the cryptographic record attached to each artifact, documenting how, when, and by whom it was built. It functions as an unforgeable audit trail for verification.
What Level 3 actually requires
SLSA Level 3 is a significant benchmark because it closes off the most common attack vectors against build pipelines. Three requirements define it:
- Provenance generation and availability: Each build produces a detailed provenance record that is accessible to consumers.
- Managed build system: Builds run on ephemeral, on-demand environments that isolate each build, preventing cross-contamination.
- Restricted access to signing materials: User-defined build steps cannot access the cryptographic materials used to sign provenance. Signing is separated from the build itself.
The key architectural difference between Level 2 and Level 3 is where signing happens. At Level 3, signing occurs on dedicated infrastructure rather than within the build job. That separation is what GitHub Artifact Attestations can deliver using reusable workflows and GitHub-hosted runners.
Signing is only half the solution
Generating signed attestations provides no security benefit unless they are verified. Verification proves that the artifact is authentic and unmodified before it reaches production.
GitHub offers three native paths for this verification:
- GitHub CLI: The simplest method for verifying signatures at any CI/CD stage.
- Kubernetes Admission Controller: Automated, policy-driven verification before containers are admitted to a cluster.
- Offline verification: Attestations can be downloaded and verified locally, useful in isolated networks.
These can be applied before Terraform plan application, before Ansible or Salt configuration deployment, or as part of Flux-based GitOps workflows.
Reaching Level 3 with GitHub Artifact Attestations
Enabling Artifact Attestations on GitHub-hosted runners generates build provenance that already satisfies SLSA Level 2 by default. Moving to Level 3 requires one additional architectural decision: placing provenance generation inside a reusable workflow.
This approach centralizes build security policy across all repositories in an organization. It also enables stronger verification because consumers can confirm that a specific reusable workflow was used for signing. The implementation cost is modest—a few lines of YAML—and there is no need to manage key material or run additional infrastructure. GitHub operates the Sigstore instance and acts as the root certificate authority.
A reusable signing workflow
Organizations can define a reusable workflow that all projects call when they need to sign artifacts:
name: Sign Artifact
on:
workflow_call:
inputs:
artifact-path:
required: true
type: string
jobs:
sign-artifact:
runs-on: ubuntu-latest
permissions:
id-token: write
attestations: write
contents: read
steps:
- name: Attest Build Provenance
uses: actions/attest-build-provenance@<version>
with:
subject-name: ${{ inputs.subject-name }}
subject-digest: ${{ inputs.subject-digest }}
Any other workflow then invokes that reusable workflow as a job step:
name: Sign Artifact Workflow
on:
push:
branches:
- main
jobs:
sign:
runs-on: ubuntu-latest
steps:
- name: Sign Artifact
uses: <repository>/.github/workflows/sign-artifact.yml@<version>
with:
subject-name: "your-artifact.tar.gz" # Replace with actual artifact name
subject-digest: "your-artifact-digest" # Replace with SHA-256 digest
This pattern ensures that every signing operation runs on dedicated hardware separate from the build machine, and the developer triggering the build has no ability to alter the signing logic. Provenance is generated consistently across the organization.
Verifying the signed artifact
To confirm that an artifact was signed by the expected reusable workflow, the GitHub CLI provides a direct verification command:
gh artifact verify <file-path> --signer-workflow <owner>/<repository>/.github/workflows/sign-artifact.yml
Running this check ensures that the artifact passed through the organization's approved signing pipeline before it is deployed.
The takeaway
GitHub Artifact Attestations lower the operational burden of SLSA Level 3 compliance. By adding a reusable workflow that generates provenance on ephemeral GitHub-hosted runners, organizations gain tamper-resistant provenance without managing certificate infrastructure or rolling out custom signing services. Verification tools are available across the deployment pipeline to close the loop between what was built, what was signed, and what actually ships.



