Fortifying Your Software Supply Chain: SLSA & Sigstore Deep Dive


Introduction
The digital world runs on software, and the integrity of that software is paramount. Recent high-profile attacks, such as SolarWinds and the Log4j vulnerability, have thrust software supply chain security into the spotlight. These incidents demonstrated that merely securing your perimeter is no longer enough; attackers are increasingly targeting the upstream components and processes that contribute to your final product.
Securing the software supply chain involves ensuring the trustworthiness of every component, dependency, and process from development to deployment. This comprehensive guide introduces two pivotal open-source initiatives designed to combat these threats: SLSA (Supply-chain Levels for Software Artifacts) and Sigstore. Together, they provide a robust framework for establishing build integrity, verifiable provenance, and cryptographic guarantees for your software artifacts, empowering organizations to build and consume software with greater confidence.
Prerequisites
To get the most out of this guide, a basic understanding of the following concepts will be beneficial:
- Software Development Life Cycle (SDLC) and CI/CD pipelines.
- Containerization (e.g., Docker) and container registries.
- Version control systems (e.g., Git, GitHub Actions).
- Familiarity with public-key cryptography concepts is helpful but not strictly required.
1. Understanding the Software Supply Chain Threat Landscape
The software supply chain is a complex ecosystem encompassing source code, open-source dependencies, build tools, CI/CD systems, package managers, and deployment infrastructure. Each link in this chain presents a potential attack vector. Attackers might:
- Inject malicious code into open-source dependencies (e.g., npm package hijacking).
- Compromise build systems to alter compiled artifacts or inject backdoors.
- Tamper with release artifacts after they are built but before distribution.
- Exploit vulnerabilities in build tools or CI/CD platforms.
- Distribute unsigned or falsely signed artifacts, making it impossible to verify their origin.
These threats highlight the urgent need for mechanisms that can attest to the origin, integrity, and authenticity of every software artifact throughout its lifecycle. Without such assurances, trust in the software we use and produce crumbles.
2. Introducing SLSA: Supply-chain Levels for Software Artifacts
SLSA (pronounced "salsa") is a security framework, developed by Google and adopted by the OpenSSF, designed to enhance the integrity of software artifacts and prevent tampering. It's not a tool but a set of standards and controls that increase the assurance level of your software supply chain. SLSA aims to make it significantly harder for attackers to compromise a supply chain and remain undetected.
SLSA defines four levels of assurance (SLSA 1 through SLSA 4), each building upon the previous one with stricter requirements for provenance, build integrity, and non-repudiation. The goal is to move organizations towards SLSA 4, which offers the highest level of security, but even achieving SLSA 1 provides significant benefits.
- SLSA 1: Provenance Generation: Requires that a build process generates provenance (metadata about how an artifact was built) and that this provenance is available to consumers. The build system itself doesn't need to be highly secured.
- SLSA 2: Hosted Build: Requires that the build process runs on a version control system and uses a hosted build service that prevents arbitrary tampering with the build definition. Provenance must be signed.
- SLSA 3: Isolated & Hermetic Build: Demands a hardened build service that is isolated, ephemeral, and hermetic (meaning it doesn't access external networks during the build). Provenance must be non-falsifiable.
- SLSA 4: Two-person Review & Reproducible Build: The highest level, requiring two-person review of all changes, reproducible builds, and further hardening of the build environment to ensure maximum integrity and auditability.
3. SLSA's Core Principles: Provenance and Build Integrity
At the heart of SLSA are two fundamental concepts:
Provenance
Provenance is verifiable metadata that describes how a software artifact was built. It answers crucial questions like:
- What source code was used (commit hash, repository URL)?
- What build tools and dependencies were involved (versions, configurations)?
- When and where was the build executed (timestamp, environment details)?
- Who initiated the build?
SLSA provenance is designed to be machine-readable (typically JSON) and tamper-proof, allowing consumers to verify the origin and integrity of the software they receive. This transparency is critical for trust and auditability.
Build Integrity
Build integrity refers to the assurance that the build process itself has not been tampered with. This involves protecting the build environment, ensuring it's isolated, ephemeral, and deterministic. A compromised build system can inject malicious code into seemingly legitimate artifacts, making build integrity a cornerstone of supply chain security. SLSA's higher levels progressively introduce requirements like hermetic builds and isolated environments to bolster build integrity.
4. Achieving SLSA Levels: Practical Steps
Implementing SLSA is an incremental journey. Here's a simplified view of practical steps for moving through the levels:
SLSA 1: Basic Provenance Generation
Start by ensuring your build process generates a provenance file. Many modern CI/CD systems or tools can help with this. The provenance should ideally be automatically generated and associated with the artifact.
SLSA 2: Hosted Build and Signed Provenance
To reach SLSA 2, you need to use a managed CI/CD service (like GitHub Actions, GitLab CI, CircleCI) that runs builds based on version-controlled definitions. Crucially, the provenance generated must be cryptographically signed to prevent tampering. This is where tools like Sigstore's Cosign become invaluable.
SLSA 3: Isolated, Hermetic, Ephemeral Builds
Achieving SLSA 3 often requires specialized build services designed for high-assurance builds. These services provide:
- Isolation: Builds run in dedicated, clean environments.
- Hermeticity: Builds only use specified inputs and do not access external networks during compilation, preventing unexpected dependencies or malicious external calls.
- Ephemerality: Build environments are destroyed after each build, ensuring no persistent state can be compromised.
Examples include Google Cloud Build with cloud-build-slsa-builder or Tekton Chains with chains-tekton-builder.
SLSA 4: Two-person Review and Reproducible Builds
SLSA 4 adds rigorous human and technical controls:
- Two-person Review: All changes to source code and build configurations require review by at least two authorized individuals.
- Reproducible Builds: The ability to rebuild an artifact from the same source code and build environment, yielding an identical binary. This requires meticulous dependency management and deterministic build tools.
5. Introducing Sigstore: A New Standard for Code Signing
While SLSA defines what a secure supply chain looks like, Sigstore provides the how. Sigstore is an open-source project that simplifies cryptographically signing software artifacts, making it easy for developers to sign and for consumers to verify. It aims to make code signing accessible and ubiquitous, effectively bringing the security of package managers like apt and yum to all software projects.
Traditional code signing is often complex, involving expensive certificates, key management challenges, and the risk of private key compromise. Sigstore addresses these issues through three core components:
- Cosign: A CLI tool for signing and verifying container images, blobs, and other artifacts.
- Rekor: A transparency log that publicly records all signing operations, providing an immutable, auditable record.
- Fulcio: A root Certificate Authority (CA) that issues short-lived, ephemeral certificates to developers based on their existing OIDC identities (e.g., GitHub, Google).
Together, these components create a seamless, secure, and verifiable signing workflow without the burden of traditional PKI.
6. Cosign: Signing and Verifying Artifacts with Ease
Cosign is the primary tool developers interact with in the Sigstore ecosystem. It allows you to sign virtually any artifact, from container images to raw files (blobs) and Software Bill of Materials (SBOMs), using either a local key or, more commonly, keyless signing via Fulcio.
Keyless Signing a Container Image
With Cosign, you can sign a container image without managing private keys directly. It leverages Fulcio to issue a short-lived certificate tied to your OIDC identity.
First, ensure Cosign is installed:
# Install via Homebrew on macOS
brew install cosign
# Install via Go
go install github.com/sigstore/cosign/cmd/cosign@latestThen, sign an image:
cosign sign --yes <YOUR_REGISTRY>/<YOUR_IMAGE>:<TAG>Explanation:
cosign sign: Initiates the signing process.--yes: Skips interactive prompts (useful in CI/CD).<YOUR_REGISTRY>/<YOUR_IMAGE>:<TAG>: The full path to your container image.
When you run this, Cosign will prompt you to authenticate with your OIDC provider (e.g., GitHub, Google). Upon successful authentication, Fulcio issues a temporary certificate, which Cosign uses to sign the image. The signature and certificate are then pushed to the container registry alongside your image and an entry is added to Rekor.
Verifying a Container Image
Verifying an image is just as simple:
cosign verify <YOUR_REGISTRY>/<YOUR_IMAGE>:<TAG>Explanation:
Cosign will fetch the signature and certificate associated with the image, verify the signature against the certificate, and then verify the certificate's validity against the Rekor transparency log and Fulcio's root of trust. If all checks pass, it confirms the image's integrity and who signed it.
Signing and Verifying Arbitrary Blobs (Files)
Cosign isn't just for containers. You can sign any file:
# Create a sample file
echo "This is a test file to be signed." > my_artifact.txt
# Sign the file (keyless)
cosign sign-blob --yes my_artifact.txt --output-signature my_artifact.sig
# Verify the file
cosign verify-blob --signature my_artifact.sig my_artifact.txtExplanation:
cosign sign-blob: Signs a local file.--output-signature: Specifies where to save the detached signature.cosign verify-blob: Verifies a file against its detached signature.
7. Rekor: The Transparency Log for Software Artifacts
Rekor is a public, immutable, append-only transparency log. Every signing operation performed with Cosign (using Fulcio) is recorded in Rekor. This serves several critical purposes:
- Non-Repudiation: Once a signature is recorded in Rekor, it cannot be denied by the signer. This provides strong accountability.
- Public Auditability: Anyone can query Rekor to verify if an artifact has been signed and by whom. This prevents attackers from secretly distributing malicious versions.
- Tamper Detection: If a signature or certificate is altered, Rekor will detect the discrepancy during verification.
- Supply Chain Visibility: Rekor provides a public, searchable ledger of all signed software, enhancing transparency across the open-source ecosystem.
Rekor entries include the artifact's digest, the signer's identity (from Fulcio certificate), and a timestamp. This publicly verifiable record is a cornerstone of trust in the Sigstore ecosystem.
8. Fulcio: OIDC-based Certificate Authority for Short-lived Certificates
Fulcio acts as a Certificate Authority (CA) within Sigstore. Its innovation lies in issuing short-lived X.509 certificates to users based on their existing OpenID Connect (OIDC) identities. This means:
- No Private Key Management: Developers don't need to generate, store, or protect long-lived private keys. Their identity is verified via OIDC (e.g., logging into GitHub, Google, Microsoft).
- Ephemeral Certificates: Certificates are valid for a very short period (e.g., 10 minutes). This significantly reduces the window of opportunity for an attacker to compromise a private key and use it to sign malicious software.
- Identity Binding: The certificate directly binds the signature to a verifiable OIDC identity (e.g.,
github.com/your-usernameoryour-email@example.com), providing strong attribution.
This system dramatically lowers the barrier to entry for secure code signing, making it practical for every developer and every CI/CD pipeline to sign their artifacts.
9. Integrating SLSA and Sigstore in Your CI/CD Pipeline
Combining SLSA and Sigstore provides a powerful solution for end-to-end supply chain security. A common approach is to use GitHub Actions for CI/CD, leveraging slsa-github-generator for provenance and Cosign for signing.
Let's look at a simplified GitHub Actions workflow for building a container image, generating SLSA provenance, and signing it with Cosign:
name: Build, Sign, and SLSA Provenance
on:
push:
branches: [ "main" ]
workflow_dispatch:
env:
IMAGE_NAME: my-app
REGISTRY: ghcr.io/${{ github.repository_owner }}
permissions:
contents: read # For checkout
packages: write # For pushing image to GHCR
id-token: write # For Sigstore/Fulcio OIDC authentication
jobs:
build-and-sign:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Docker BuildX
uses: docker/setup-buildx-action@v3
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- name: Build and push Docker image
id: build-image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
# --- SLSA Provenance Generation and Signing ---
- name: Generate SLSA provenance and sign with Sigstore
uses: slsa-framework/slsa-github-generator/.github/actions/generator@v2.2.0
with:
# The artifact to generate provenance for (the container image)
image: ${{ steps.meta.outputs.tags }}
# The trigger for the workflow (e.g., workflow_dispatch, push)
workflow-identity-token: ${{ secrets.ACTIONS_ID_TOKEN }}
# Ensure the SLSA provenance is signed by Cosign/Fulcio
cosign-keyless: trueExplanation of the Workflow:
- Permissions: Crucially,
id-token: writeis required for Sigstore's OIDC authentication with Fulcio.packages: writeis needed to push the image to GitHub Container Registry (GHCR). - Build and Push: Standard steps to build a Docker image and push it to GHCR.
- SLSA Generator: The
slsa-framework/slsa-github-generatoraction is used. This action automatically:- Generates SLSA-compliant provenance for the specified
image. - Uses Cosign (via
cosign-keyless: true) to sign this provenance using the workflow's OIDC identity. - Pushes the signature and the provenance to the OCI registry alongside the image.
- Generates SLSA-compliant provenance for the specified
This workflow helps achieve SLSA 2+ by providing signed provenance generated in a trusted environment (GitHub Actions) and recorded in Rekor via Cosign.
10. Generating and Verifying SLSA Provenance with Sigstore
The slsa-github-generator doesn't just generate provenance; it also ensures it's signed using Sigstore. This means that when you verify your artifact, you can also verify its associated provenance.
After the workflow above runs, you can verify the image and its SLSA provenance using Cosign:
# Verify the image itself
cosign verify --certificate-identity "https://github.com/<ORG>/<REPO>/.github/workflows/<WORKFLOW_NAME>.yml@refs/heads/main" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
<YOUR_REGISTRY>/<YOUR_IMAGE>:<TAG>
# Verify the SLSA provenance associated with the image
cosign verify-attestation --type slsaprovenance \
--certificate-identity "https://github.com/<ORG>/<REPO>/.github/workflows/<WORKFLOW_NAME>.yml@refs/heads/main" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
<YOUR_REGISTRY>/<YOUR_IMAGE>:<TAG>Explanation:
--certificate-identity: Specifies the OIDC identity that signed the artifact/attestation. For GitHub Actions, this typically follows the patternhttps://github.com/<ORG>/<REPO>/.github/workflows/<WORKFLOW_NAME>.yml@<REF>. You'll need to adapt this to your specific workflow path and branch.--certificate-oidc-issuer: The OIDC issuer URL for your CI/CD platform (e.g.,https://token.actions.githubusercontent.comfor GitHub Actions).verify-attestation --type slsaprovenance: Specifically checks for SLSA provenance attestations.
This verification step ensures that the artifact was built by the expected workflow, in the expected environment, and that its provenance has not been tampered with. This is a critical control point for deployment gates, allowing you to prevent the deployment of untrusted or compromised software.
11. Best Practices for a Secure Supply Chain
To maximize the benefits of SLSA and Sigstore, consider these best practices:
- Automate Everything: Manual processes are prone to errors and bypasses. Automate provenance generation, signing, and verification within your CI/CD pipelines.
- Enforce Verification at Deployment: Implement policies in your deployment systems (e.g., Kubernetes admission controllers like Kyverno or OPA Gatekeeper) to only allow artifacts with valid Sigstore signatures and SLSA provenance.
- Adopt SLSA Incrementally: Don't aim for SLSA 4 overnight. Start with SLSA 1/2 and gradually improve your build processes to meet higher levels.
- Leverage OIDC Identities: Embrace keyless signing with Fulcio. This eliminates the burden and risk of managing long-lived cryptographic keys.
- Scan Dependencies: Integrate vulnerability scanning (e.g., Trivy, Snyk) for all direct and transitive dependencies. While SLSA/Sigstore verify what was built, vulnerability scanning checks what's inside.
- Use SBOMs: Generate Software Bill of Materials (SBOMs) for all your artifacts. Sign these SBOMs with Cosign and include them in your provenance. This provides transparency into components.
- Least Privilege: Ensure your CI/CD pipelines and build systems operate with the minimum necessary permissions.
- Immutable Infrastructure for Builds: Use ephemeral, isolated build environments that are destroyed after each use to prevent persistent compromises.
- Regular Auditing: Periodically review your build configurations, access controls, and security policies.
12. Common Pitfalls and How to Avoid Them
Even with powerful tools like SLSA and Sigstore, certain mistakes can undermine your security efforts:
- Ignoring Verification: The most common pitfall is implementing signing but neglecting to enforce verification at critical stages (e.g., deployment). A signature is useless if it's not checked.
- Solution: Implement strict admission policies in your deployment environments.
- Misconfiguring OIDC Identities: Incorrectly configuring the
certificate-identityorcertificate-oidc-issuerduring verification can lead to false positives or negatives.- Solution: Double-check these values against your CI/CD provider's documentation and the identity used during signing.
- Over-reliance on a Single Control: SLSA and Sigstore are powerful but not a silver bullet. They should be part of a broader security strategy that includes dependency scanning, vulnerability management, and infrastructure security.
- Solution: Adopt a layered security approach.
- Neglecting Internal Dependencies: Focus often goes to external open-source dependencies, but internally developed libraries and services also form part of your supply chain and need the same level of scrutiny.
- Solution: Apply SLSA and Sigstore principles to all internal artifacts.
- Lack of Understanding of SLSA Levels: Trying to jump straight to SLSA 4 without understanding the foundational requirements of lower levels can lead to incomplete or ineffective implementations.
- Solution: Follow an incremental adoption strategy, ensuring each level's requirements are met before moving to the next.
Conclusion
The security of the software supply chain is no longer a niche concern but a critical imperative for every organization. SLSA and Sigstore represent a paradigm shift in how we approach this challenge, moving from reactive incident response to proactive integrity assurance.
By adopting SLSA, you establish a clear roadmap for enhancing the trustworthiness of your software artifacts through verifiable provenance and build integrity. Sigstore, with its intuitive Cosign CLI, public Rekor log, and OIDC-powered Fulcio CA, provides the practical tooling to achieve these goals without the traditional complexities of PKI. Together, they empower developers to sign, and consumers to verify, software artifacts with unprecedented ease and confidence.
Embracing these open-source initiatives is a significant step towards building a more resilient and trustworthy software ecosystem. Start integrating SLSA and Sigstore into your development and deployment workflows today, and fortify your software supply chain against the evolving threat landscape.

Written by
CodewithYohaFull-Stack Software Engineer with 5+ years of experience in Java, Spring Boot, and cloud architecture across AWS, Azure, and GCP. Writing production-grade engineering patterns for developers who ship real software.
