SLSA Framework
Implement Supply chain Levels for Software Artifacts (SLSA) to prove build provenance and achieve hermetic, reproducible builds.
SLSA Framework
SLSA (Supply chain Levels for Software Artifacts) is a security framework that defines levels of supply chain integrity. It provides a common language for describing how secure your build process is.
What is SLSA?
SLSA (pronounced "salsa") answers the question: "How can we trust this artifact?"
It defines 4 levels of increasing security:
| Level | Requirements | Protection |
|---|---|---|
| SLSA 1 | Build process documented | Basic transparency |
| SLSA 2 | Signed provenance | Tamper-evident builds |
| SLSA 3 | Hardened build platform | Insider threat protection |
| SLSA 4 | Two-party review + hermetic builds | Highest integrity |
Why SLSA Matters
SolarWinds Attack Analysis
SolarWinds breach would have been prevented by SLSA 3:
Attack: Compromised build server injected malware
SLSA 3 Requirement: Hardened build platform with access controls
Result: Attack detected via provenance verification
Codecov Breach
Attack: Modified bash script in CI
SLSA 2 Requirement: Signed provenance with script hashes
Result: Tampering detected before deployment
SLSA Levels Explained
SLSA 1: Build Documentation
Requirements:
- Build process exists
- Provenance generated (unsigned)
Example provenance:
{
\"buildType\": \"https://github.com/actions/workflow\",
\"builder\": {\"id\": \"https://github.com/myorg/myapp/.github/workflows/build.yml@main\"},
\"invocation\": {
\"configSource\": {
\"uri\": \"git+https://github.com/myorg/myapp\",
\"digest\": {\"sha1\": \"abc123\"}
}
},
\"metadata\": {
\"buildStartedOn\": \"2025-01-24T10:00:00Z\",
\"buildFinishedOn\": \"2025-01-24T10:15:00Z\"
}
}
Benefit: Know how artifact was built
SLSA 2: Signed Provenance
Requirements:
- Everything in SLSA 1
- Provenance is signed
- Service generates provenance (not user script)
Example:
# Generate signed provenance
slsa-provenance generate \\
--artifact myapp:v1.0.0 \\
--builder github.com/myorg/myapp/.github/workflows/release.yml \\
--output provenance.json
# Sign with Cosign
cosign sign-blob provenance.json --bundle provenance.json.bundle
# Attach to image
cosign attach attestation myapp:v1.0.0 --attestation provenance.json
Benefit: Tamper-evident builds
SLSA 3: Hardened Build Platform
Requirements:
- Everything in SLSA 2
- Build environment is isolated
- Access controls and audit logging
- Provenance can't be forged by build steps
GitHub Actions SLSA 3:
GitHub's hosted runners with SLSA generator:
name: SLSA 3 Build
on:
release:
types: [created]
permissions:
contents: write
id-token: write
jobs:
build:
uses: slsa-framework/slsa-github-generator/.github/workflows/[email protected]
with:
image: ghcr.io/${{ github.repository }}
registry-username: ${{ github.actor }}
secrets:
registry-password: ${{ secrets.GITHUB_TOKEN }}
Benefit: Protection against insider threats
SLSA 4: Two-Party Review
Requirements:
- Everything in SLSA 3
- All changes require approval from two trusted persons
- Hermetic builds (no network access)
- Reproducible builds
Example (Google Bazel):
# BUILD.bazel with hermetic dependencies
container_image(
name = \"app\",
base = \"@distroless//cc\",
files = [\":binary\"],
# All dependencies pinned by hash
)
Benefit: Highest supply chain integrity
Generating SLSA Provenance
GitHub Actions SLSA Generator
For Container Images:
name: SLSA Provenance
on:
push:
tags: ['v*']
permissions:
actions: read
id-token: write
packages: write
contents: write
jobs:
build:
permissions:
contents: read
packages: write
outputs:
digest: ${{ steps.build.outputs.digest }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build and push
id: build
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ghcr.io/${{ github.repository }}:${{ github.ref_name }}
provenance:
needs: [build]
permissions:
actions: read
id-token: write
packages: write
uses: slsa-framework/slsa-github-generator/.github/workflows/[email protected]
with:
image: ghcr.io/${{ github.repository }}
digest: ${{ needs.build.outputs.digest }}
registry-username: ${{ github.actor }}
secrets:
registry-password: ${{ secrets.GITHUB_TOKEN }}
For Binaries (Go):
jobs:
build:
permissions:
id-token: write
contents: write
uses: slsa-framework/slsa-github-generator/.github/workflows/[email protected]
with:
base64-subjects: \"${{ needs.build.outputs.hashes }}\"
upload-assets: true
in-toto Attestation
SLSA provenance uses in-toto attestation format:
{
\"_type\": \"https://in-toto.io/Statement/v0.1\",
\"subject\": [
{
\"name\": \"ghcr.io/myorg/myapp\",
\"digest\": {\"sha256\": \"abc123...\"}
}
],
\"predicateType\": \"https://slsa.dev/provenance/v0.2\",
\"predicate\": {
\"builder\": {\"id\": \"https://github.com/myorg/myapp/.github/workflows/release.yml@refs/heads/main\"},
\"buildType\": \"https://github.com/slsa-framework/slsa-github-generator@v1\",
\"invocation\": {...},
\"buildConfig\": {...},
\"metadata\": {...},
\"materials\": [
{\"uri\": \"git+https://github.com/myorg/myapp@refs/heads/main\", \"digest\": {\"sha1\": \"def456\"}}
]
}
}
Verifying SLSA Provenance
slsa-verifier Tool
# Install
go install github.com/slsa-framework/slsa-verifier/v2/cli/slsa-verifier@latest
# Verify container image
slsa-verifier verify-image ghcr.io/myorg/myapp:v1.0.0 \\
--source-uri github.com/myorg/myapp \\
--source-tag v1.0.0
# Output
Verified build using builder \"https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@refs/tags/v1.9.0\" at commit abc123
Policy Enforcement
Kubernetes admission controller:
apiVersion: policy.sigstore.dev/v1beta1
kind: ClusterImagePolicy
metadata:
name: require-slsa3
spec:
images:
- glob: \"ghcr.io/myorg/**\"
authorities:
- attestations:
- predicateType: \"https://slsa.dev/provenance/v0.2\"
name: slsa3-attestation
policy:
type: cue
data: |
predicateType: \"https://slsa.dev/provenance/v0.2\"
predicate: builder: id: =~\"^https://github.com/slsa-framework/slsa-github-generator/\"
Achieving Each SLSA Level
Path to SLSA 1
- Generate build provenance
- Store with artifact
- Done!
# Minimal provenance
echo '{\"buildType\":\"manual\",\"builder\":{\"id\":\"local\"},\"invocation\":{}}' > provenance.json
Path to SLSA 2
- Everything in SLSA 1
- Use trusted service to generate provenance (GitHub Actions, GitLab CI)
- Sign provenance
- Attach to artifact
cosign attest --predicate provenance.json --type slsaprovenance image:tag
Path to SLSA 3
- Everything in SLSA 2
- Use SLSA 3 generator (slsa-github-generator)
- Harden build environment
- Enable audit logging
- Implement access controls
GitHub Actions: Use slsa-github-generator (shown above)
Self-hosted:
- Isolated build environment (containers, VMs)
- No network access during build
- Audit all build activities
Path to SLSA 4
- Everything in SLSA 3
- Require two-party code review
- Hermetic builds (pinned dependencies)
- Reproducible builds
Example (Bazel):
load(\"@io_bazel_rules_docker//container:container.bzl\", \"container_image\")
container_image(
name = \"app\",
base = \"@distroless_base//image\",
files = [\":binary\"],
# Hermetic: all deps declared explicitly
)
SLSA Best Practices
Start with SLSA 2
- Most organizations should target SLSA 2
- GitHub Actions provides this out-of-the-box
Verify provenance before deployment
slsa-verifier verify-image $IMAGE --source-uri $REPOStore provenance with artifacts
- Attach to container registry
- Include in release assets
Audit provenance regularly
- Check builder identity
- Validate source repository
Combine with signing
# Generate and sign provenance cosign attest --predicate provenance.json --type slsaprovenance image:tagMonitor provenance changes
- Alert on unexpected builders
- Track provenance patterns
Document your SLSA level
- README badges
- Security policy
SLSA Tooling
Generators
- slsa-github-generator (GitHub Actions, SLSA 3)
- slsa-verifier (Verification tool)
- in-toto (Provenance framework)
Verification
- slsa-verifier (CLI)
- Sigstore Policy Controller (Kubernetes)
- Kyverno (Policy engine)
Build Systems
- GitHub Actions (SLSA 3 with generator)
- Google Cloud Build (SLSA 3)
- Bazel (SLSA 4 capable)
Next Steps
- CI/CD Integration — Automate SBOM, signing, and SLSA provenance
Key takeaway: SLSA 2 is achievable for most teams today. Use slsa-github-generator to generate signed provenance automatically.
Found an issue?