M14: Supply Chain Attestations & SLSA

Artifact signing (M13) answers “was this artifact signed by the expected identity?” Supply chain attestations answer a richer set of questions: where did the source come from, what was the build process, who ran the tests, and is the known CVE actually exploitable? This module covers SLSA, in-toto, VEX, and how to wire the full attestation stack into your pipeline.

Learning Objectives

By the end of this module you should be able to:

  • Implement SLSA Level 2 or 3 for your build process
  • Generate in-toto attestations for build, test, and source
  • Issue VEX statements to communicate non-applicable CVEs
  • Build an attestation consumer (e.g., admission controller)
  • Map SLSA to customer and regulatory requirements
  • Explain the difference between signing (M13) and attestations (this module)

1. Signatures vs. Attestations

These are different, complementary mechanisms:

AspectSignature (M13)Attestation (this module)
Question”Is this artifact signed by X?""Is this artifact the result of process P, run on source S, with test T passing?”
Issuercosign / KMSSLSA provenance generator, in-toto
ContentBinary signature over a digestStructured claim about a process
StorageOCI referrerOCI referrer (in-toto predicate)
Consumercosign verifyCustom verifier (e.g., Kyverno, Ratify)

A signature says who signed. An attestation says what was done. The two together: an artifact signed by CI, with an attestation that the CI run was triggered by a specific commit, on a hardened runner, with all tests passing.

2. SLSA: Supply Chain Levels for Software Artifacts

SLSA is a framework with four levels. Each level adds a guarantee:

LevelBuild provenanceSignedSourceHardened build
0NoneNoAnyNo
1DocumentedNoAnyNo
2Documented + tamper-resistantYesVerifiedSome
3Hardened, two-party, signedYesVerifiedYes (e.g., ephemeral)
4Two-party review, hermeticYesTwo-party reviewYes

Most orgs target SLSA L2 as a reasonable goal; L3 is the differentiator. L4 is hyperscaler territory.

What SLSA Requires (L2)

  • Build provenance generated and signed
  • Provenance is non-forgeable (signed by a separate key)
  • Source verified (commit hash in provenance matches git)
  • Build platform is trusted (e.g., GitHub Actions with OIDC)

What SLSA L3 Adds

  • Hardened build platform
  • Provenance is generated by the platform, not the build script
  • Build runs in an isolated, ephemeral environment
  • Strong separation of duties

3. The in-toto Attestation Framework

in-toto is a CNCF project. Attestations are JSON-LD documents with:

  • A predicateType — what kind of attestation
  • A predicate — the actual claim
  • A subject — what the attestation is about (image digest, source repo, etc.)
  • A signature (signed by cosign or KMS)

The standard predicate types:

  • SLSA Provenance — describes the build (source, builder, materials)
  • SPDX SBOM — inventory of components
  • CycloneDX SBOM — same, different format
  • VEX — vulnerability exploitability exchange
  • Link — generic predicate for any custom claim
  • Test Result — what tests ran, what passed
  • Code Review — review status of a change

4. Generating Provenance

SLSA GitHub Generator (slsa-github-generator)

A reusable GitHub Actions workflow that produces SLSA L3 provenance.

# .github/workflows/release.yml
name: release
on:
  push:
    tags: ['v*']
 
permissions:
  id-token: write
  contents: read
  packages: write
 
jobs:
  build:
    uses: slsa-framework/slsa-github-generator/.github/workflows/builder_go_slsa3.yml@v1.9.0
    with:
      go-version: 1.22
      module: github.com/my-org/my-app
      artifact-path: dist/my-app

The workflow:

  • Builds the Go binary in a hardened GitHub Actions runner
  • Generates SLSA provenance with source commit, build config, materials
  • Signs the provenance with the workflow’s OIDC identity
  • Uploads both binary and provenance to the release

The provenance contains:

{
  "_type": "https://in-toto.io/Statement/v0.1",
  "predicateType": "https://slsa.dev/provenance/v1",
  "subject": [{"name": "my-app", "digest": {"sha256": "abc..."}}],
  "predicate": {
    "buildDefinition": {
      "buildType": "https://slsa.dev/github-actions/v1",
      "externalParameters": {
        "workflow": {"ref": "refs/tags/v1.2.3", "repository": "https://github.com/my-org/my-app"}
      }
    },
    "runDetails": {
      "builder": {"id": "https://github.com/actions/runner/github-hosted"},
      "metadata": {"invocationId": "github-actions-run-12345"}
    }
  }
}

A consumer can verify: this artifact was built by GitHub Actions, on commit abc123, in repo my-org/my-app, on tag v1.2.3. If any of those don’t match what’s expected, the artifact is rejected.

5. VEX: Vulnerability Exploitability eXchange

VEX is the answer to “this dep has CVE-2024-XXXX, but I don’t use the vulnerable function.” It’s a structured statement that says: this vuln exists, but it’s not exploitable in this product, for this reason.

VEX States (CycloneDX)

  • not_affected — the vuln is in a dep, but not reachable
  • affected — the vuln is reachable, fix is planned
  • fixed — the vuln was reachable, but a fix has been applied
  • in_triage — under investigation
  • false_positive — the vuln doesn’t apply; scanner was wrong
  • resolved — same as fixed; included for clarity
  • exploitable — the vuln is reachable, no fix available, mitigation required
  • resolved_with_pedigree — fixed in a way that may not be obvious

When to Issue VEX

  • A scanner reports a vuln in your product
  • You determine the vuln is not reachable in your code
  • You publish a VEX statement describing the non-applicability
  • Customers consume the VEX and clear the finding on their side

VEX Workflow

  1. Trivy/Snyk finds CVE-2024-XXXX in image
  2. Engineer triages: "we don't call the vulnerable function"
  3. Engineer files VEX: state=not_affected, justification=code_not_present
  4. VEX is signed and published (attestation to the SBOM)
  5. Customer ingests VEX, suppresses the finding
  6. Re-scan: VEX-aware scanner shows the finding as cleared

VEX Tools

  • cve-bin-tool — generates VEX from reachability analysis
  • VulnTotal — multi-scanner aggregation with VEX output
  • Manual authoring — for known cases, write the VEX JSON by hand and attach as attestation

6. The Full Attestation Stack

  +--------------------+
  |  Source commit     |  <-- signed by git
  +---------+----------+
            |
            v
  +--------------------+
  |  Build             |  <-- SLSA provenance (in-toto)
  |  (SLSA L3)         |      signed by CI OIDC
  +---------+----------+
            |
            v
  +--------------------+
  |  Artifact (image)  |  <-- cosign signature
  +---------+----------+
            |
            +-- SBOM (CycloneDX)  <-- signed, in-toto
            +-- VEX              <-- signed, in-toto
            +-- Test results     <-- signed, in-toto
            +-- Code review      <-- signed, in-toto
            |
            v
  +--------------------+
  |  Deploy target     |  <-- admission controller
  |  (K8s, ECS, etc.)  |      verifies signatures
  |                    |      verifies provenance
  |                    |      consumes VEX
  +--------------------+

Every step is signed. Every claim is verifiable. Every claim can be re-checked at any time without re-running the build.

7. Customer-Facing Attestations

Customers increasingly demand evidence of supply-chain integrity. The artifacts to provide:

  • SBOM (CycloneDX or SPDX)
  • SLSA provenance (verifiable)
  • VEX feed (continuously updated)
  • Compliance attestations (SOC2 controls, ISO mappings)
  • Vulnerability disclosure policy (how to report a vuln to you)

Distribution channels:

  • Public attestation registry
  • OCI artifacts alongside your product image
  • Web portal with on-demand access
  • API with token-based access for enterprise customers

8. SLSA + Customer Requirements

Customer requirementSLSA levelWhy
”Show me your SBOM”L1Documented build = documented inventory
”Show me your build process”L2Provenance is non-forgeable
”Prove the binary came from your source”L3Hardened build, two-party signing
”We need to verify it independently”L3+Verifiable provenance with public keys
”We need to replay your build”L4Hermetic, reproducible

Most enterprise security questionnaires map to SLSA L2. FedRAMP and similar frameworks are starting to require L3. Plan for L3 as the long-term target.

9. Implementing SLSA L3: The Path

Month 1: Inventory

  • Where do you build? (GitHub Actions, GitLab, Jenkins, Buildkite)
  • Are builds reproducible? (Same source → same artifact?)
  • Is the build platform hardened? (Ephemeral, isolated, no manual access)
  • What is the source verification story? (Signed commits, branch protection)

Month 2: Provenance Generation

  • Pick a provenance generator (slsa-github-generator, Tekton Chains, in-toto-golang)
  • Integrate into the build pipeline
  • Verify provenance is generated for every release
  • Sign the provenance

Month 3: Verification

  • Stand up an admission controller (Kyverno, Ratify)
  • Configure it to verify provenance
  • Test: unsigned image is rejected
  • Roll out to all clusters

Month 4: Hardening

  • Migrate to ephemeral runners
  • Two-party review on release (release engineer + security engineer)
  • Document the SLSA L3 posture
  • Audit by an external party

10. Common Pitfalls

PitfallConsequenceFix
Provenance generated but not verifiedPointless; deploy accepts anythingVerify at admission
Provenance claims source but doesn’t verifyProvenance is just textSign and verify against git
VEX issued but not machine-readableManual suppression, driftCycloneDX VEX format, signed
No transparency logCannot detect tamperingRekor for everything
SBOM signed but not attached to imageCustomer can’t find itAttach as OCI referrer
L3 aspirations with L0 build platformCannot honestly claim L3Harden the platform first

11. Self-Check

  1. What SLSA level is your build process at, honestly? Use the slsa.dev self-assessment.
  2. Can a customer today verify that your binary came from your source? If not, generate provenance.
  3. When a new CVE drops, how long does it take you to publish a VEX for known-not-applicable cases?

12. The Attestation Lifecycle

An attestation has a lifecycle similar to a signature:

  1. Generation — at build time, by the build platform
  2. Storage — as an OCI referrer, alongside the artifact
  3. Distribution — via the registry; consumer pulls by digest
  4. Verification — at deploy time, by the admission controller
  5. Re-verification — at any time, by re-pulling the attestation
  6. Retention — the attestation lives as long as the artifact

The attestation is the evidence trail. The signature is the authentication. Together, they prove both what the artifact is and where it came from.

13. Provenance and Reproducible Builds (Deep Dive)

Reproducible builds (M09) and provenance are complementary:

  • Reproducible — given source S, the build produces artifact A, deterministically
  • Provenance — a signed claim that A was built from S

Reproducible builds enable independent verification: the customer can rebuild from S and check that the result equals A. Provenance attests that the build was done by a specific platform.

For the highest assurance (SLSA L4, defense, financial regulators), you want both:

  1. Rebuild from S in a clean environment
  2. Compare the result to A
  3. Verify the provenance claims the build was done correctly
  4. Both checks pass → the artifact is genuine

The combination is rare in practice; most orgs do provenance first, rebuilds second.

14. The in-toto Attestation Predicate Catalog

The in-toto project maintains a list of standard predicate types. As of 2025:

PredicatePurposeTypical use
SLSA ProvenanceBuild provenanceSLSA L2+
SPDX SBOMLicense + component inventoryM08
CycloneDX SBOMSame, different formatM08
VEXVulnerability applicabilityCustomer disclosure
LinkGeneric claimCustom assertions
Test ResultWhat tests ran, what passedCompliance
Code ReviewReview statusCode-review compliance
Hera WorkflowArgo Workflows runWorkflow provenance
Run DetailsGeneric build metadataCustom build systems

Custom predicates are allowed but should be avoided unless none of the standard types fits.

15. The SLSA Levels in Practice

LevelWhat you needWhat’s hard
0Nothing
1Documented build processEasy
2Signed provenanceMedium (requires OIDC, slsa-github-generator or similar)
3Hardened build platformHard (ephemeral runners, two-party review)
4Two-party review, hermetic buildsVery hard (reproducible builds, isolation)

Most orgs target L2. L3 is the differentiator for high-value customers. L4 is rare outside defense and financial regulators.

16. The Hardening Checklist for SLSA L3

For an org targeting SLSA L3:

  • All builds run on ephemeral runners (no shared state)
  • All builds use OIDC (M12) to authenticate to the build platform
  • All build provenance is generated by the platform, not the build script
  • All provenance is signed (Rekor transparency log)
  • All source is verified (commit hash in provenance matches git)
  • All builds are isolated (no network access during build, except to allowed mirrors)
  • All build dependencies are pinned (lockfile)
  • Two-party review is required for releases
  • All consumers verify provenance at deploy

After completing the checklist, the org can honestly claim SLSA L3.

17. Attestation and the Audit Trail

ControlAttestation evidence
SOC 2 CC8.1 (change management)Provenance is part of the change record
ISO A.8.32 (change management)Provenance for every release
FedRAMP SI-7 (software/firmware integrity)Provenance + signature
FedRAMP CM-5 (access restrictions)Provenance generation is restricted to the build platform
SLSA L2/L3Provenance is the implementation
EU CRAProvenance + SBOM is the evidence
US EO 14028Provenance + SBOM is the requirement

The audit asks “how do you know the artifact was built correctly?” The answer is the provenance. The verification is the cryptographic check at deploy.

18. The Transparency Log: Rekor and Friends

Rekor is one of several transparency logs in the supply-chain space:

  • Rekor (Sigstore) — generic, free, public
  • Binary Transparency (Google) — for binaries
  • in-toto.io/gossip — peer-to-peer log
  • TUF / The Update Framework — for software updates

The pattern: an append-only log of claims, cryptographically verifiable, no central authority. The log is the audit trail that no one party can forge.

For most orgs, Rekor is sufficient. For air-gapped environments, run your own.

19. Attestation in the Customer-Facing Posture

The customer-facing supply-chain posture document (M18) includes:

  • SBOM (M08)
  • Provenance (this module)
  • VEX (this module)
  • Vulnerability disclosure policy
  • Compliance certifications (SOC 2, ISO 27001)
  • Build platform hardening (SLSA level claim)
  • Test coverage and methodology

The customer can verify each claim independently. The posture is the single document the customer uses to assess supply-chain risk.