What this article covers
- Architectural Prerequisites: Understanding the specific infrastructure requirements for SLSA Level 3, including ephemeral build environments and isolated signing operations.
- Upstream Security: Integrating CleanStart zero-vulnerability base images to establish a trusted foundation before the build process begins.
- Identity Federation: Configuring GitHub Actions OpenID Connect (OIDC) to enable keyless signing via Sigstore without managing long-lived secrets.
- Implementation Method A (Native): Configuring the actions/attest-build-provenance action within reusable workflows to achieve isolation.
- Implementation Method B (OpenSSF): Utilizing the slsa-framework/slsa-github-generator for ecosystem-specific rigor (Go, Containers, Generic).
- Verification Procedures: Validating provenance signatures and builder identities using the GitHub CLI and slsa-verifier.
- Policy Enforcement: Strategies for automated admission control and verifiable audit trails.
Step 1: Establish the Trusted Foundation (Upstream Thinking)
Before configuring the build pipeline itself, it is critical to address the components that enter the pipeline. A secure build process (SLSA Level 3) applied to vulnerable artifacts creates a false sense of security; it merely proves that a vulnerable artifact was built correctly. "Upstream thinking" necessitates shifting focus from scanning artifacts after they are built to ensuring the integrity of the inputs before the build commences. The primary input for containerized applications is the base image. Standard base images from public registries (e.g., Docker Hub) frequently contain "security debt"—accumulated vulnerabilities (CVEs), unnecessary system packages, and unverified binaries.
Action: Select and Verify CleanStart Base Images
To align with the "secure by design" philosophy required for high-assurance supply chains, you must replace generic base images with hardened, minimal alternatives.
- Select a Hardened Image: Choose a CleanStart base image that matches your runtime requirements (e.g., cleanstart/alpine, cleanstart/python, or cleanstart/go).
- Context: CleanStart images are engineered to be 100% vulnerability-free at release.1 This is achieved not just by patching, but by removing non-essential components (attack surface reduction), often resulting in images 30-60% smaller than standard equivalents.2
- Technical Benefit: By removing shells, package managers, and debugging tools from the runtime image, you mitigate the risk of "living off the land" attacks where an adversary exploits a vulnerability to execute system commands.1
- Verify Base Image Provenance: Before your build script runs docker build, it should verify the signature of the base image. This ensures that your "Point A" (the base) is trustworthy before you move to "Point B" (your application).
- CleanStart images are cryptographically signed using Sigstore. Verification prevents Typosquatting (pulling a malicious image with a similar name) and Tag Mutability (pulling the latest tag that has been compromised).3
Code Example: Verifying Base Image Signature
In your initial workflow setup, use Cosign to validate the CleanStart image. YAML
Why this matters for SLSA: SLSA primarily tracks the "Build" provenance. However, the integrity of the "Materials" (inputs) is equally vital. By verifying the base image, you extend the chain of custody. You can now prove: "I built this application (SLSA L3) on top of this specific, verified base image (CleanStart Provenance)."
Step 2: Configure Identity Federation (OIDC)
SLSA Level 3 requires that the provenance is authenticated and non-falsifiable. Historically, this required managing private GPG keys or signing secrets, which introduces the risk of key exfiltration. The modern, compliant approach utilizes OpenID Connect (OIDC) to establish a temporary, verifiable identity for the build workflow.
Action: Enable OIDC Permissions in Workflows
To generate valid provenance, the GitHub Action runner must request a short-lived identity token from GitHub's OIDC provider. This token is then exchanged for a signing certificate from a Certificate Authority (Fulcio), binding the public key to the identity of the workflow (e.g., repo:org/project:ref:refs/heads/main).
- Modify Workflow Permissions: You must explicitly grant id-token: write permissions to the job responsible for signing. Without this, the runner cannot authenticate with Sigstore or GitHub's internal attestation authority.
Configuration: YAML
Understanding the Mechanism:
- The runner requests a JSON Web Token (JWT) from GitHub's OIDC provider.
- The JWT contains claims asserting the workflow's identity (job_workflow_ref, repository, sha).
- The signing tool (e.g., attest-build-provenance or slsa-github-generator) sends this token to Fulcio.
- Fulcio validates the token against GitHub and issues a short-lived X.509 certificate.
- The tool signs the artifact with an ephemeral private key and attaches the X.509 certificate.
- The signature and certificate are logged to Rekor (transparency log), creating an immutable record.
This "Keyless" architecture ensures that even if a build environment is compromised after the build, the attacker cannot forge provenance for future builds because they cannot steal a long-lived private key.4
Step 3: Implement SLSA Level 3 Provenance (Method A: Native)
The actions/attest-build-provenance action provides a streamlined path to generating signed provenance. However, to strictly meet SLSA Level 3 requirements regarding isolation, you cannot simply run this action in the same job that builds the artifact if that job runs on self-hosted runners or lacks strict boundaries. The most rigorous implementation uses Reusable Workflows to separate the user-defined build steps from the trusted signing process.
Action: Isolate Build and Signing Logic
- Create a Reusable Workflow: Define a workflow that encapsulates the build and attestation logic. Because this workflow is defined in a separate file (and potentially a separate trusted repository), it acts as a "Trusted Builder."
File: .github/workflows/reusable-build-attest.yml YAML
2. Call from Main Workflow: The developer's workflow calls the trusted builder.
File: .github/workflows/release.yml YAML
Technical Nuance:
- Isolation: By using a reusable workflow, the build-and-attest job runs in a fresh virtual environment defined by the reusable workflow definition, not the caller. This satisfies the SLSA L3 requirement that the build runs in an ephemeral environment isolated from other builds.4
- Predicate Type: This action generates provenance using the SLSA v1.0 predicate. It captures the build configuration, the GitHub context (actor, run ID), and the resolved dependencies.7
- Storage: The attestation is stored in the GitHub Attestations store (internally linked to the repository) and, for public repositories, signed via the public Sigstore instance.7
Step 4: Implement SLSA Level 3 Provenance (Method B: OpenSSF Generator)
For projects requiring strict adherence to the OpenSSF specifications, or for ecosystems where specific "Builders" are required (e.g., Go, Node.js), the slsa-framework/slsa-github-generator is the industry standard. This method differs by using a strictly defined "Generator" workflow that trusts only the digest provided by the build, signing it with a highly restricted identity.
Action: Configure the Generic Generator
The "Generic Generator" is ideal for arbitrary binaries or artifacts where a language-specific builder (like the Go builder) is not feasible.
- Calculate Digest in Build Job: The build job must output the SHA256 digest of the artifact.
File: .github/workflows/slsa-generic.yml YAML
Critical Configuration Details:
- Immutable References: You must refer to the generator workflow by a specific tag (e.g., @v2.0.0). The generator will fail if referenced by a branch (like @main) to prevent mutable code from masquerading as a trusted builder.9
- Subject Encoding: The base64-subjects input expects a string formatted as the output of sha256sum, then base64 encoded. This ensures complex filenames or newlines don't break the input handling.10
- Privacy: By default, the OpenSSF generator logs to the public Rekor instance. If you are in a private repository and wish to avoid leaking the repository name to the public log, you must set private-repository: true (if supported by the specific version/configuration) or accept the metadata leak. GitHub's native method (Method A) handles private repositories opaqueley using an internal log.7
Container Generator Variant:
If building a container image, use the generator_container_slsa3.yml workflow. This workflow pushes the attestation to the container registry, attaching it to the image manifest. YAML
Step 5: Verify Provenance (The Consumer)
Provenance generation is futile without verification. Consumers (deployment systems, users, or downstream builds) must verify the attestation to confirm the artifact is authentic and meets SLSA Level 3 standards.
Action: Verify using CLI Tools
Verifying Native Attestations (Method A) Use the GitHub CLI (gh) to verify artifacts signed by the attest-build-provenance action.
Interpretation of Results:
- Pass: The tool confirms the artifact's digest matches the signed attestation and that the signature was generated by a workflow within the specified owner (organization).
- Pass: The tool confirms the artifact's digest matches the signed attestation and that the signature was generated by a workflow within the specified owner (organization).
Verifying OpenSSF Attestations (Method B)
Use the slsa-verifier tool for artifacts generated by the OpenSSF workflows. This tool provides granular control over the expected builder identity. Bash
Deep Insight - The "Source" Check: The --source-uri flag is the most critical security control here. It prevents a "forking attack" where an attacker forks your repository, runs the valid SLSA generator in their fork (producing valid provenance signed by their workflow), and presents the malicious artifact + valid provenance to a user. slsa-verifier checks that the OIDC identity specifically matches the expected source repository, rejecting valid provenance from unauthorized sources.13
Step 6: Policy Enforcement and Automation
For enterprise environments, manual verification is insufficient. SLSA verification should be automated via admission controllers or policy engines.
Kubernetes Admission Control (Kyverno/Gatekeeper)
Deploy policies that block any container image lacking a valid SLSA Level 3 attestation from the authorized organization.
- CleanStart Integration: Enhance this policy to require two attestations:
- The CleanStart base image attestation (verifying the OS layer is vulnerability-free).
- The Application layer attestation (verifying your code was built securely).
This "chained verification" ensures that a secure build process wasn't wasted on a compromised foundation.14
Notes / Tips
- Offline Verification: In air-gapped environments, standard verification may fail because the tool cannot reach the Rekor transparency log. You must export the necessary transparent log bundles and public keys to the air-gapped environment to allow offline verification.12
- Private Repositories: Be aware that the OpenSSF generator, by default, writes to the public Rekor log (rekor.sigstore.dev). While the artifact content is not logged, metadata like the repository name and workflow path are. If this metadata is confidential, use the GitHub Native method (which uses a private internal log) or configure the OpenSSF generator with privacy flags if available.11
- Private Repositories: Be aware that the OpenSSF generator, by default, writes to the public Rekor log (rekor.sigstore.dev). While the artifact content is not logged, metadata like the repository name and workflow path are. If this metadata is confidential, use the GitHub Native method (which uses a private internal log) or configure the OpenSSF generator with privacy flags if available.11
Requirements
- GitHub Plan: GitHub Actions is available on all plans, but Artifact Attestations for private repositories require GitHub Enterprise Cloud.12
- Permissions: Repository settings must allow "GitHub Actions to create and approve pull requests" (if using PR-based triggers) and OIDC tokens must be enabled (usually on by default).
- CleanStart Access: Access to CleanStart images requires a valid subscription or usage of their public community images.16
Related articles (internal links)
Analysis of SLSA Level 3 Requirements & CleanStart Integration
This section provides deep research insights into why the above steps constitute a robust security posture, analyzing the interplay between SLSA standards and CleanStart's upstream philosophy.
The Mechanics of Isolation
SLSA Level 3's defining characteristic is Isolation. In a non-isolated build (Level 2 or lower), a build script might have access to secrets used for signing, or it might run on a machine ("runner") that has persisted files from a previous build.
- Threat: A malicious build step (e.g., a compromised dependency running a post-install script) could exfiltrate the signing key or poison the cache for the next build.
- Mitigation: GitHub-hosted runners are ephemeral VMs. They are provisioned from a clean image for every job and destroyed immediately after. This provides strong isolation. By moving the signing logic into a Reusable Workflow, we create a logical boundary. The user-defined build steps happen in the caller job (or a separate job), and the signing happens in a context the user cannot modify during execution. The OIDC token used for signing identifies the reusable workflow, not the caller, creating a "trusted builder" identity.4
The "Upstream Thinking" Differentiator
Most SLSA tutorials focus solely on the build process. However, a SLSA Level 3 build that compiles malware is still a valid SLSA Level 3 build—it just accurately proves that malware was built securely.
- CleanStart's Role: CleanStart addresses the input vector. By ensuring the base image is "Clean" (Zero CVEs, minimal footprint) and "Started" correctly (signed provenance), you mitigate the risk of inheriting vulnerabilities.
- Data Insight: Standard Docker Hub images often contain 100-300+ vulnerabilities upon retrieval.17 CleanStart images reduce this to near-zero. This massive reduction in noise allows security teams to focus on actual threats in the application layer rather than triaging hundreds of irrelevant base OS vulnerabilities. This creates a high-signal, low-noise security posture.2
Comparing Method A and Method B
Feature
GitHub Native (attest-build-provenance)
OpenSSF (slsa-github-generator)
SLSA Compliance
Level 2 by default; Level 3 requires Reusable Workflow architecture.
Level 3 by design (enforces trusted builder pattern).
Verification Tool
gh attestation verify
slsa-verifierPrivacy
High: Uses internal private log for private repos.
Medium: Defaults to public Rekor log (leaks repo name).
Ecosystem Support
Generic (file paths, Docker images).
Specialized builders for Go, Node.js, Java, Containers.
Complexity
Low (Native action, minimal config).
Moderate (Requires strict workflow structure).
Adoption Strategy
Best for enterprises already deep in the GitHub ecosystem requiring privacy.
Best for open-source projects wanting distinct, community-standard verification.
Stage 3: Test and security attestation
Test attestations prove security scans passed and tests succeeded before deployment.
Implementation example
Adding VEX documents
VEX (Vulnerability Exploitability eXchange) documents explain why specific vulnerabilities don't affect your application:
The Future of Supply Chain Security
The integration of SLSA Level 3 provenance with automated policy enforcement represents the future of DevSecOps. We are moving away from implicit trust ("I trust this developer") to explicit, cryptographic verification ("I trust this artifact because it was built by this specific workflow, on this platform, from this commit, on this verified base image"). CleanStart's approach of providing "pre-verified" components aligns perfectly with this future. Instead of every organization spending resources hardening the same Alpine or Ubuntu images, they consume a verified upstream artifact, chaining their provenance to it. This reduces the global "computational waste" of security patching and accelerates the adoption of secure-by-default pipelines.1
Detailed Troubleshooting Scenarios
Scenario 1: slsa-verifier fails with "provenance mismatch"
Deployment attestations record where and when artifacts were deployed.
- Analysis: This often happens when the artifact modified during the upload process (e.g., compression, re-tagging) or when the wrong subject is attested.
- Fix: Ensure the base64-subjects passed to the generator matches exactly the binary being released. If using the generic generator, verify that the sha256sum calculation includes only the intended files and no extra whitespace/newlines in the base64 encoding.10
Scenario 2: "Resource not accessible by integration"
- Analysis: The workflow is trying to write to the repository (uploading assets or attestations) but lacks the token scope.
- Fix: Check the permissions block. Specifically, attestations: write and contents: write are often missed in complex workflows where permissions are set at the top level but overridden at the job level.12
Scenario 3: Private Repository Name Leaked
- Analysis: You used the OpenSSF generator without private-repository: true (or the feature wasn't supported in your version). The build was successful, but your repo name, my-secret-project, is now visible in the public Rekor log.
- Fix: For strictly internal projects, prefer the GitHub Native method (attest-build-provenance), which uses an internal transparency log that does not replicate to the public Sigstore instance, maintaining confidentiality while providing auditability.7
Implementation Checklist for Architects
- [ ] Base Image: Migrated Dockerfile to use FROM cleanstart/....
- [ ] Verification: Added cosign verify step for base image in CI.
- [ ] Isolation: Moved build logic to a Reusable Workflow.
- [ ] Identity: Configured permissions: id-token: write.
- [ ] ** provenance**: Added attest-build-provenance or slsa-github-generator step.
- [ ] Registry: Configured push-to-registry: true for OCI artifacts.
- [ ] Validation: Verified the final artifact using gh attestation verify locally.
- [ ] Policy: Updated Kubernetes admission controller to require signed provenance.
This structured approach ensures that your organization not only "checks the box" for SLSA compliance but fundamentally elevates the security posture of its software delivery, mitigating risks from the source code all the way to the production runtime.
Works cited
- Knowledge Hub - CleanStart, accessed on January 23, 2026, https://www.cleanstart.com/knowledge-hub
- CLEANSTART | NMRM Infotech, accessed on January 23, 2026, https://www.nmrminfotech.com/copy-of-xendata
- From Awareness to Assurance: Building Trust in a Cloud-Native, AI-Driven World - CleanStart, accessed on January 23, 2026, https://www.cleanstart.com/blogs/from-awareness-to-assurance-building-trust-in-a-cloud-native-ai-driven-world
- Enhance build security and reach SLSA Level 3 with GitHub Artifact Attestations, accessed on January 23, 2026, https://github.blog/enterprise-software/devsecops/enhance-build-security-and-reach-slsa-level-3-with-github-artifact-attestations/
- Achieving SLSA 3 Compliance with GitHub Actions and Sigstore for Go modules, accessed on January 23, 2026, https://github.blog/security/supply-chain-security/slsa-3-compliance-with-github-actions/
- Introduction to SLSA - Chainguard Academy, accessed on January 23, 2026, https://edu.chainguard.dev/compliance/slsa/what-is-slsa/
- Artifact attestations - GitHub Docs, accessed on January 23, 2026, https://docs.github.com/en/actions/concepts/security/artifact-attestations
- Provenance - SLSA.dev, accessed on January 23, 2026, https://slsa.dev/spec/v0.1/provenance
- Language-agnostic SLSA provenance generation for Github Actions, accessed on January 23, 2026, https://github.com/slsa-framework/slsa-github-generator
- slsa-github-generator/internal/builders/generic/README.md at main ..., accessed on January 23, 2026, https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/generic/README.md
- slsa-github-generator/internal/builders/container/README.md at main, accessed on January 23, 2026, https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md?ref=thomasvitale.com
- Using artifact attestations to establish provenance for builds - GitHub Docs, accessed on January 23, 2026, https://docs.github.com/actions/security-for-github-actions/using-artifact-attestations/using-artifact-attestations-to-establish-provenance-for-builds
- slsa-framework/slsa-verifier: Verify provenance from SLSA compliant builders - GitHub, accessed on January 23, 2026, https://github.com/slsa-framework/slsa-verifier
- Artifact Attestation on Action Runner Controller · community · Discussion #151472 - GitHub, accessed on January 23, 2026, https://github.com/orgs/community/discussions/151472
- SLSA, it's all about provenance attestation | by Rémi Rey - Medium, accessed on January 23, 2026, https://medium.com/@rrey94/slsa-its-all-about-provenance-attestation-09a83b7b9de7
- Cleanstart - Images repository, accessed on January 23, 2026, https://images.cleanstart.com/
- Solution Document - Cleanstart, accessed on January 23, 2026, https://cdn.prod.website-files.com/688cb1df5bbf5068ddce4492/68d65d47051e1b0ca7a66228_Solution%20Document%20-%20Cleanstart.pdf
- OpenSSF Welcomes New Members and Presents Golden Egg Award, accessed on January 23, 2026, https://openssf.org/press-release/2025/06/26/openssf-welcomes-new-members-and-presents-golden-egg-award/
