DevOps

Enhance Software Supply Chain Security: SBOM & Sigstore

Master software supply chain security with this in-depth guide to SBOMs and Sigstore. Learn how to generate, sign, and verify software artifacts for ultimate trust.

Khader Vali July 26, 2026 18 min read

Mastering Software Supply Chain Security: SBOM and Sigstore Explained

Welcome to Khadervali.com! As a fellow engineer navigating the complexities of modern software development, you’ve undoubtedly felt the increasing pressure to secure your applications and infrastructure. In recent years, the spotlight has intensified on a critical, yet often overlooked, area: the software supply chain. We’ve witnessed a dramatic surge in sophisticated attacks targeting this very chain, from the infamous SolarWinds compromise to the widespread fallout of Log4Shell. These incidents aren’t just headlines; they’re stark reminders that the security of our software is only as strong as its weakest link – and that link is often found deep within our dependencies or build processes.

The traditional perimeter defense model is no longer sufficient. Our applications are no longer monolithic, self-contained units. They are intricate tapestries woven from countless open-source libraries, third-party components, cloud services, and internal modules, all built and deployed through complex CI/CD pipelines. This ecosystem, while enabling incredible innovation and speed, also introduces a vast attack surface that requires a new breed of security measures.

This article is your deep dive into two transformative technologies that are rapidly becoming indispensable in the fight for software supply chain security: Software Bill of Materials (SBOM) and Sigstore. We’ll explore why they’re crucial, how they work, and most importantly, how you can integrate them into your development lifecycle to build more resilient and trustworthy software. Think of this as a practical guide from one engineer to another, complete with real-world scenarios, architectural insights, and actionable code examples.

The Anatomy of a Software Supply Chain Attack: Understanding the Threat Landscape

Before we delve into solutions, let’s ensure we have a shared understanding of the problem. What exactly constitutes a software supply chain attack? It’s any malicious act that targets the development, build, or distribution process of software, aiming to compromise the final product before it reaches the end-user. The goal is often to inject malware, backdoors, or vulnerabilities that can then be propagated downstream, affecting potentially thousands or millions of users.

Common Attack Vectors and Real-World Scenarios:

  1. Compromised Open-Source Packages: Attackers inject malicious code into popular open-source libraries or create fake, similarly named packages (typosquatting). When developers unknowingly include these compromised packages, the malware enters their application.
    • Scenario: Imagine a seemingly innocuous JavaScript library, widely used, suddenly gets a malicious commit from a compromised maintainer account. Your next CI/CD build pulls this updated version, and now your web application is serving malware to your users.
  2. Malicious Updates: This is the classic “trojan horse” scenario, exemplified by the SolarWinds attack. Legitimate software vendors are compromised, and their update mechanisms are used to distribute malicious software to their customers.
    • Scenario: A highly trusted network monitoring software vendor’s build server is breached. Attackers inject a backdoor into the compiled binaries for a routine update. Thousands of organizations install this “update,” unknowingly granting attackers deep access to their networks.
  3. Vulnerable Build Systems and CI/CD Pipelines: If your build servers, artifact repositories, or CI/CD agents are compromised, attackers can tamper with compiled code, inject malicious dependencies, or alter deployment scripts.
    • Scenario: A misconfigured Jenkins instance with weak credentials is breached. An attacker gains control, modifies a build script to exfiltrate sensitive environment variables, and injects a cryptominer into the Docker images being built.
  4. Insider Threats: Malicious insiders or disgruntled employees can intentionally introduce vulnerabilities or backdoors into the codebase or build process.
    • Scenario: A developer, unhappy with their employer, subtly introduces a logic bomb into a critical component that will trigger on a specific date, causing system outages.
  5. Dependency Confusion: A clever technique where private packages with common names are replaced by public malicious packages. If a build system tries to resolve a dependency and finds a public package with the same name as an internal one, it might pull the public (malicious) version first.
    • Scenario: Your company uses a private NPM package named @mycorp/utils. An attacker publishes a malicious package with the exact same name to the public NPM registry. Due to package manager resolution rules, your CI/CD pipeline starts pulling the public, malicious version instead of your internal one.

These scenarios highlight a critical truth: you cannot secure what you cannot see or verify. This brings us to our first major solution: the Software Bill of Materials (SBOM).

Enhance Software Supply Chain Security: SBOM & Sigstore
Generated Image

Software Bill of Materials (SBOM): The Ingredient List for Your Software

Imagine buying a packaged food item without an ingredient list. You’d have no idea what you’re consuming, whether it contains allergens, or if it meets your dietary preferences. In the world of software, for too long, we’ve been operating in a similar blind spot. The Software Bill of Materials (SBOM) is designed to fix that.

What is an SBOM?

At its core, an SBOM is a formal, machine-readable inventory of all the components that make up a piece of software. It’s like the ingredient list for your application, detailing every dependency, library, and module, whether open-source or commercial, that has gone into its creation. It’s not just about direct dependencies; a comprehensive SBOM aims to capture transitive dependencies – the dependencies of your dependencies, and so on, often several layers deep.

The U.S. National Telecommunications and Information Administration (NTIA) defines an SBOM as a “nested inventory for software, a list of ingredients that make up software components.” This emphasizes the hierarchical nature, where a component might itself be composed of other components, each with its own entries in the SBOM.

Why SBOMs are Crucial for Modern Software Development

The value of an SBOM extends far beyond mere compliance; it’s a fundamental tool for risk management, transparency, and operational efficiency.

  1. Enhanced Visibility into Dependencies: In complex applications, it’s easy to lose track of hundreds, if not thousands, of direct and transitive dependencies. An SBOM provides a clear, centralized record, giving you unparalleled visibility into your software’s true composition.
  2. Proactive and Reactive Vulnerability Management:
    • Proactive: With an SBOM, you can scan against known vulnerability databases (e.g., NVD, OSV) to identify potential weaknesses in your software before deployment. This allows you to patch or replace vulnerable components early.
    • Reactive: When a new critical vulnerability (like Log4Shell) is announced, an SBOM allows you to quickly query your inventory across all your applications and identify exactly where the affected component is used. This dramatically reduces response time from weeks to hours or even minutes.
  3. Improved Compliance and Risk Management: Many regulatory frameworks and industry standards (e.g., Executive Order on Improving the Nation’s Cybersecurity, NIST SSDF) are increasingly mandating or recommending SBOMs. They are vital for demonstrating due diligence, managing licensing risks (identifying conflicting open-source licenses), and assessing third-party vendor risk.
  4. Increased Trust and Transparency: Providing an SBOM to your customers builds trust. It shows that you understand your software’s composition and are committed to its security. This transparency can be a significant competitive advantage.
  5. Faster Incident Response: As mentioned with Log4Shell, the ability to quickly identify affected software is paramount during a critical incident. An SBOM transforms a desperate search into a targeted query.

Key Information Contained in an SBOM

While specific formats vary, a robust SBOM typically includes the following information for each component:

  • Component Name: The official name of the library, module, or package (e.g., Apache Log4j).
  • Version: The specific version number (e.g., 2.14.1).
  • Supplier/Author: The entity responsible for creating or maintaining the component (e.g., Apache Software Foundation).
  • Unique Identifiers: Standardized identifiers for components (e.g., Package URL (PURL), Common Platform Enumeration (CPE)). These are crucial for unambiguous identification and vulnerability matching.
  • Checksums/Hashes: Cryptographic hashes (e.g., SHA256) of the component’s files. These allow verification of integrity and ensure the component hasn’t been tampered with.
  • License Information: The license under which the component is distributed (e.g., Apache-2.0, MIT). Essential for legal compliance.
  • Relationships: How components relate to each other (e.g., A DEPENDS_ON B, C CONTAINS D). This builds the dependency graph.
  • Vulnerabilities (Optional but Recommended): While not strictly part of the core SBOM definition, linking to known CVEs or providing vulnerability data is often integrated or derived from SBOMs.

Common SBOM Formats

To facilitate machine readability and interoperability, several standardized SBOM formats have emerged:

  1. SPDX (Software Package Data Exchange): An ISO/IEC standard (ISO/IEC 5962:2021) developed by the Linux Foundation. It’s comprehensive and flexible, capable of representing a wide range of data points about software components, licenses, and security information. It supports various serialization formats like JSON, XML, and tag-value.
  2. CycloneDX: An OWASP project, designed to be lightweight and security-focused. It’s particularly well-suited for use in CI/CD pipelines due to its compact nature and strong emphasis on security metadata. It also supports JSON and XML.
  3. SWID (Software Identification Tagging): An ISO standard (ISO/IEC 19770-2:2015) primarily used for identifying installed software assets and their properties. While it can function as an SBOM, its focus is more on post-installation inventory than build-time dependency tracking.

For most modern supply chain security initiatives, SPDX and CycloneDX are the dominant and recommended choices.

Generating SBOMs: Tools and Integration

The good news is that generating SBOMs doesn’t have to be a manual, tedious process. A robust ecosystem of tools can automate this, often integrating seamlessly into your existing CI/CD pipelines.

Popular tools include:

  • Syft: A powerful CLI tool from Anchore that generates SBOMs from container images, filesystems, and archives, supporting both SPDX and CycloneDX formats.
  • Trivy: While primarily a vulnerability scanner, Trivy also has excellent SBOM generation capabilities for container images, file systems, and Git repositories.
  • Dependency-Track: An intelligent component analysis platform that consumes SBOMs to provide continuous monitoring for vulnerabilities and license compliance.
  • Commercial Tools: Solutions like Snyk, Black Duck, Mend.io (formerly WhiteSource), and Sonatype Nexus Lifecycle offer comprehensive SBOM generation and management features, often integrated with their broader security offerings.

Code Example: Generating an SBOM with Syft

Let’s say you have a Docker image or a local directory with your application’s source code and dependencies. Generating a CycloneDX JSON SBOM is straightforward:

# Install Syft (if you haven't already)
# brew install syft (macOS)
# docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock anchore/syft:latest version

# To generate an SBOM for a Docker image:
syft my-app:latest -o cyclonedx-json > my-app-sbom.json

# To generate an SBOM for a local directory (e.g., your project root):
syft dir:. -o cyclonedx-json > my-project-sbom.json

# You can also specify the output format as spdx-json
# syft dir:. -o spdx-json > my-project-sbom.spdx.json

This command will output a detailed JSON file containing all identified components, their versions, licenses, and relationships. This file is your foundational ingredient list.

Consuming and Using SBOMs

Generating an SBOM is just the first step. The real value comes from consuming and acting upon the information it provides.

  1. Vulnerability Scanning: Feed your SBOMs into tools like Trivy or Dependency-Track. These tools can then cross-reference the components in your SBOM against various vulnerability databases to quickly identify known CVEs affecting your software.
  2. License Compliance Checks: Automate the detection of incompatible or problematic open-source licenses within your codebase, helping you avoid legal issues.
  3. Policy Enforcement: Implement policies that prevent deployment if an SBOM contains components with critical vulnerabilities, unauthorized licenses, or components from unapproved sources.
  4. Supply Chain Risk Assessment: Use SBOMs to evaluate the risk profile of third-party software you consume.

Real-World Scenario: Responding to a New CVE with an SBOM

Imagine a new critical vulnerability, CVE-2023-XXXX, is announced for a popular networking library, let’s call it libnet-utils. Without an SBOM, your security team might spend days or weeks trying to manually track down every instance of libnet-utils across your thousands of microservices, applications, and infrastructure components.

With SBOMs generated and stored for all your deployments:

  1. Your security team receives the CVE alert.
  2. They run a quick query against your central SBOM repository: “Find all SBOMs containing libnet-utils version <affected_versions>.”
  3. Within minutes, they have a precise list of every affected application, its version, and where it’s deployed.
  4. This allows for immediate, targeted patching and remediation efforts, drastically reducing your exposure window and potential damage.

SBOMs provide the much-needed visibility. But how do we ensure that the SBOM itself hasn’t been tampered with, or that the software artifact it describes is genuinely from the source we expect? This is where Sigstore comes in.

Enhance Software Supply Chain Security: SBOM & Sigstore
Generated Image

Sigstore: Cryptographic Signatures for the Masses

Even with a perfect SBOM, a fundamental question remains: how do you trust the software artifact itself? How do you know that the container image, binary, or script you’re about to run hasn’t been altered or replaced by an attacker? Traditionally, the answer has been cryptographic signing using tools like GPG or X.509 certificates.

However, general adoption of code signing has been notoriously low, especially in the open-source community. Why? The complexity of managing long-lived private keys, distributing public keys, and ensuring revocation mechanisms are often too cumbersome for individual developers or small projects. Sigstore aims to change this, making code signing as easy and ubiquitous as HTTPS with Let’s Encrypt.

The Problem Sigstore Solves

  • Burden of Key Management: Managing GPG keys, especially for multiple contributors or projects, is a headache. Revocation, key rotation, and secure storage are challenging.
  • Lack of Widespread Adoption: Due to the complexity, many open-source projects and even commercial entities don’t sign their artifacts, leaving users with no way to verify authenticity.
  • Trusting Unsigned Artifacts: Users are forced to trust artifacts based on their origin (e.g., “it came from GitHub, so it must be okay”), which is a weak security posture.
  • Auditing and Transparency: Without a public, immutable record of signing events, it’s difficult to audit who signed what and when.

What is Sigstore?

Sigstore is an open-source project that provides a non-profit software signing service, aiming to bring robust, transparent, and accessible code signing to all developers. It’s essentially a set of tools and services designed to make it easy for developers to sign software artifacts and for consumers to verify those signatures, all without the traditional complexities of key management.

Think of Sigstore as the “Let’s Encrypt for code signing.” Just as Let’s Encrypt provides free, automated SSL/TLS certificates to secure web traffic, Sigstore provides free, automated, and auditable code signing certificates and infrastructure to secure software artifacts.

Core Components of Sigstore

Sigstore consists of three primary components that work together:

  1. Fulcio (Root CA): This is a root Certificate Authority (CA) that issues short-lived, ephemeral signing certificates. Instead of managing long-lived private keys, developers authenticate to Fulcio using their existing OpenID Connect (OIDC) identities (e.g., Google, GitHub, Microsoft accounts). Fulcio then issues a signing certificate tied to that specific identity for a very short duration (e.g., 10 minutes). This eliminates the need for developers to manage private keys directly.
  2. Rekor (Transparency Log): Rekor is a public, immutable, append-only transparency log. Every signing event facilitated by Sigstore (i.e., every artifact signed using a Fulcio-issued certificate) is recorded in Rekor. This log provides a public, verifiable, and auditable record of all signed artifacts, their signatures, and the associated certificates. It’s similar to Certificate Transparency logs used for SSL/TLS certificates. If a signature is ever questioned, Rekor can provide irrefutable proof of its existence and associated metadata.
  3. Cosign (CLI Tool): Cosign is the primary command-line utility for interacting with Sigstore. It simplifies the process of signing and verifying various software artifacts, including container images, binaries, text files, and SBOMs. Cosign orchestrates the interactions with Fulcio for certificate issuance and Rekor for logging, making the entire signing process seamless for the developer.

How Sigstore Works: Architecture Description (in words)

Let’s trace the typical flow when a developer signs an artifact using Sigstore:

  1. Developer Initiates Signing: The developer, using the Cosign CLI tool, decides to sign an artifact (e.g., a Docker image).
  2. OIDC Authentication: Cosign prompts the developer to authenticate using an OIDC provider (e.g., GitHub). This opens a browser window for a standard OAuth 2.0 flow.
  3. Fulcio Certificate Issuance: Upon successful authentication, Cosign sends the OIDC identity token to Fulcio. Fulcio, acting as a Certificate Authority, verifies the identity and issues a short-lived X.509 signing certificate. This certificate contains the developer’s verified identity information. Importantly, no private key is stored or managed by the developer; Cosign generates an ephemeral key pair locally for the signing operation.
  4. Artifact Signing: Cosign uses the ephemeral private key (generated in step 3) and the Fulcio-issued certificate to cryptographically sign the artifact. The signature is then typically stored alongside the artifact in an OCI-compliant registry (like Docker Hub, Google Container Registry, Quay.io).
  5. Rekor Transparency Logging: Immediately after signing, Cosign uploads the artifact’s signature, the Fulcio-issued certificate, and the artifact’s digest to Rekor. Rekor records this event in its immutable public log and provides a “receipt” (a signed timestamp from Rekor) back to Cosign. This receipt provides proof that the signing event occurred and was publicly recorded at a specific time.
  6. Verification Process: When a consumer wants to verify an artifact:
    • They use Cosign to fetch the signature and certificate associated with the artifact from its registry.
    • Cosign then queries Rekor, presenting the signature and certificate.
    • Rekor confirms that the signature and certificate are indeed logged and provides the corresponding receipt.
    • Cosign then performs cryptographic verification:
      • It checks if the artifact’s digest matches the one recorded in the signature.
      • It verifies the signature itself using the public key from the Fulcio certificate.
      • It verifies the Fulcio certificate’s chain of trust up to the Sigstore root.
      • It also checks the Rekor receipt to ensure the signing event was logged and hasn’t been tampered with.

This entire process happens seamlessly, often with a single cosign sign or cosign verify command, abstracting away the underlying cryptographic complexities.

Sigstore in Action (Code Examples)

Let’s look at how to use Cosign for common tasks. First, ensure you have Cosign installed:

# Install Cosign (macOS with Homebrew)
brew install cosign

# Or download binaries from GitHub releases page:
# https://github.com/sigstore/cosign/releases

# Check version
cosign version

Signing a Container Image

This is one of Cosign’s primary use cases. It will prompt you for OIDC authentication via your browser.

# First, pull or build an image
docker pull alpine:latest
docker tag alpine:latest my-registry.example.com/my-alpine:latest
docker push my-registry.example.com/my-alpine:latest

# Sign the image
# --yes bypasses the interactive prompt for confirmation if using a terminal that doesn't support interactive.
cosign sign --yes my-registry.example.com/my-alpine:latest

After running this, Cosign will guide you through an OIDC login (e.g., GitHub, Google). Once authenticated, it signs the image and uploads the signature and certificate to the same OCI registry, typically as an OCI image manifest list entry alongside your image.

Verifying a Container Image

To verify that an image was signed by a trusted identity (e.g., your GitHub account):

# Verify the image. Cosign automatically fetches the signature from the registry
# and checks against Rekor.
cosign verify my-registry.example.com/my-alpine:latest

# You can also specify the identity to verify against (e.g., from a GitHub Actions workflow)
# cosign verify --certificate-identity "https://github.com/your-org/your-repo/.github/workflows/main.yml@refs/heads/main" --certificate-oidc-issuer "https://token.actions.githubusercontent.com" my-registry.example.com/my-alpine:latest

If the verification succeeds, you’ll see output confirming the signature and the identity of the signer. If it fails (e.g., the image was tampered with, or signed by an unknown entity), Cosign will return an error.

Signing a Generic File (Blob)

Cosign isn’t limited to container images. You can sign any arbitrary file, such as a binary, a script, or even an SBOM JSON file.

# Create a sample file
echo "Hello, Sigstore!" > my_script.sh

# Sign the file. This will again prompt for OIDC authentication.
# The signature and bundle are stored locally, not in a registry.
cosign sign-blob --yes --output-signature my_script.sig --output-certificate my_script.cert my_script.sh

This command creates two files: `my_script.sig` (the cryptographic signature) and `my_script.cert` (the Fulcio-issued certificate).

Verifying a Generic File (Blob)

# Verify the file against its signature and certificate
cosign verify-blob --signature my_script.sig --certificate my_script.cert my_script.sh

Cosign will verify the integrity of the file and the authenticity of the signature using the provided certificate and checking against Rekor.

Benefits of Sigstore

  • Eliminates Key Management Overhead: Developers no longer need to generate, store, and manage long-lived GPG keys. The ephemeral certificates simplify the process dramatically.
  • Increases Signing Adoption: By removing complexity, Sigstore encourages more projects and organizations to sign their artifacts, enhancing trust across the ecosystem.
  • Provides Transparency and Audibility: Rekor’s immutable log creates a public record of all signing events, making it impossible for signatures to be forged or denied without detection. This is crucial for forensic analysis and compliance.
  • Strengthens Trust in Software Artifacts: Consumers can verify that the software they’re using truly comes from the expected source and hasn’t been tampered with.
  • Supports Various Artifact Types
Written by

Khader Vali

Senior Software Engineer specializing in cloud architecture, real-time systems, and enterprise-scale applications.

Share this article

Related Articles

GitHub Actions: CI/CD from Basics to Matrix Builds

Jun 20, 2026 · 17 min read

Observability with Prometheus, Grafana & OpenTelemetry

Jul 03, 2026 · 15 min read

CI/CD Pipeline Architecture for Multi-Team Organizations

Aug 26, 2024 · 1 min read