Security
Difficulty: Advanced
18 min read

Supply Chain Security: SBOM, SCA and CI/CD Hardening

Learn how to secure your software supply chain end to end: generate SBOMs with Syft, scan dependencies with Trivy and Grype, harden your GitHub Actions and GitLab CI pipelines, sign your artifacts with Cosign and reach the SLSA levels.

Back to tutorials
Real-world threat context
SolarWinds (2020), Codecov (2021), Log4Shell (2021), XZ Utils (2024): attacks targeting the software supply chain have become the most devastating attack vector. A single compromised component can affect thousands of organizations simultaneously.

Why the software supply chain is the priority target

In December 2020, attackers compromised the build systems of SolarWinds and inserted a backdoor into legitimate updates of the Orion suite. More than 18,000 organizations downloaded the poisoned update, including US government agencies. The attack went undetected for 9 months.

In December 2021, CVE-2021-44228 (Log4Shell) revealed a critical vulnerability in Log4j, a Java library used in hundreds of thousands of applications. The problem: most teams did not even know they were using Log4j — it was present as a transitive dependency, hidden several levels deep.

These two incidents illustrate the two main vectors of supply chain attacks:

  • Build chain compromise: an attacker tampers with the compilation process or the build tools
  • Vulnerabilities in dependencies: third-party libraries contain unknown or deliberately introduced flaws

This tutorial covers the four defensive pillars: inventory (SBOM), detection (SCA), pipeline hardening (CI/CD) and artifact verification (signing + provenance).

SBOM: Software Bill of Materials

An SBOM is the software equivalent of a food product's ingredient list. It exhaustively lists all the components of an application: direct libraries, transitive dependencies, exact versions, licenses and relationships between components.

CycloneDX vs SPDX: choosing your format

Two standards dominate the market:

  • SPDX (Software Package Data Exchange) — ISO 5962:2021 standard, maintained by the Linux Foundation. License-compliance oriented. XML, JSON or RDF format. Recommended for legal analysis and open source distribution.
  • CycloneDX — OWASP standard, security oriented. Supports SBOMs, HBOMs (hardware), MBOMs (ML models) and VEX documents. JSON, XML or Protocol Buffers format. Recommended for DevSecOps use cases.
Recommendation
Use CycloneDX for operational security (CVE tracking, VEX) and SPDX if your legal team needs license compliance analysis. Both formats are interoperable and Syft generates both.

Generating an SBOM with Syft

Syft (Anchore) is the reference tool for generating SBOMs from Docker images, source code directories or archives.

# Installing Syft
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin

# Check the installation
syft version

# Generate an SBOM from a Docker image (CycloneDX JSON format)
syft image:my-app:latest -o cyclonedx-json=sbom.cdx.json

# Generate an SBOM from an image with a full tag
syft registry:myregistry.io/my-app:v1.2.3 -o cyclonedx-json=sbom.cdx.json

# Generate from a directory (analyzes the source code)
syft dir:/path/to/project -o cyclonedx-json=sbom.cdx.json

# SPDX JSON format
syft image:my-app:latest -o spdx-json=sbom.spdx.json

# SPDX tag-value format (for legal toolchains)
syft image:my-app:latest -o spdx-tag-value=sbom.spdx

# Table display for quick inspection
syft image:my-app:latest -o table

# Include dev packages in the SBOM
syft dir:/project -o cyclonedx-json --scope all-layers

A CycloneDX JSON SBOM looks like this (simplified excerpt):

{
  "bomFormat": "CycloneDX",
  "specVersion": "1.6",
  "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
  "version": 1,
  "metadata": {
    "timestamp": "2026-02-20T10:00:00Z",
    "tools": [{"vendor": "anchore", "name": "syft", "version": "1.4.0"}],
    "component": {
      "type": "container",
      "name": "my-app",
      "version": "1.2.3"
    }
  },
  "components": [
    {
      "type": "library",
      "name": "log4j-core",
      "version": "2.17.1",
      "purl": "pkg:maven/org.apache.logging.log4j/[email protected]",
      "licenses": [{"expression": "Apache-2.0"}]
    }
  ]
}

Integrating the SBOM into your CI pipeline

The SBOM must be generated at every build and archived as an artifact. Here is a GitHub Actions example:

# .github/workflows/sbom.yml
name: SBOM Generation

on:
  push:
    branches: [main]
  release:
    types: [published]

jobs:
  sbom:
    runs-on: ubuntu-latest
    permissions:
      contents: write
      packages: read

    steps:
      - name: Checkout
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11  # v4.1.1

      - name: Build image
        run: docker build -t my-app:${{ github.sha }} .

      - name: Install Syft
        uses: anchore/sbom-action/download-syft@fd74a6fb98a204a1ad35bbfae0122c1a302ff88d  # v0.15.0

      - name: Generate SBOM
        uses: anchore/sbom-action@fd74a6fb98a204a1ad35bbfae0122c1a302ff88d  # v0.15.0
        with:
          image: my-app:${{ github.sha }}
          format: cyclonedx-json
          output-file: sbom-${{ github.sha }}.cdx.json
          artifact-name: sbom-${{ github.sha }}.cdx.json

      - name: Upload SBOM as release asset
        if: github.event_name == 'release'
        uses: actions/upload-release-asset@e8f9f06c4b078e705bd2ea027f0926603fc9b4d5  # v1.0.2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ github.event.release.upload_url }}
          asset_path: sbom-${{ github.sha }}.cdx.json
          asset_name: sbom.cdx.json
          asset_content_type: application/json

Premium Content

This advanced tutorial is reserved for premium members.

9,90€ / month
  • All advanced tutorials
  • New content every week
  • Progress tracking
  • Cancel anytime

Written by

Morgann Riu

Cybersecurity and Linux administration expert. I share my knowledge through free tutorials and training to help system administrators and developers secure their infrastructures.

Frequently asked questions

What is an SBOM and why is it mandatory?
An SBOM (Software Bill of Materials) is an exhaustive inventory of all the software components of an application: libraries, transitive dependencies, versions and licenses. It was made mandatory by the 2021 US Executive Order on cybersecurity for software sold to the US federal government, and is strongly recommended by ENISA in Europe. It lets you immediately answer the question "are we vulnerable?" when a new CVE like Log4Shell is published.
What is the difference between CycloneDX and SPDX?
SPDX (Software Package Data Exchange) is an ISO standard (ISO 5962:2021) primarily oriented toward license compliance, maintained by the Linux Foundation. CycloneDX is an OWASP standard specifically designed for security, supporting SBOMs but also HBOMs (hardware), MBOMs (machine learning) and VEX (Vulnerability Exploitability eXchange). For operational security, CycloneDX is preferable because it natively integrates vulnerability data. SPDX is preferable for license analysis and legal compliance.
What is the difference between Trivy, Grype and OWASP Dependency-Check?
Trivy (Aqua Security) is the most versatile scanner: Docker images, system files, Git repos, IaC configurations. It is fast, easy to integrate in CI and supports many formats. Grype (Anchore) focuses on images and file systems with excellent accuracy and the SARIF format for GitHub Security. OWASP Dependency-Check specifically analyzes source code dependencies (Maven, npm, NuGet, pip) and integrates the NVD database. In practice, Trivy covers 90% of needs, complemented by Dependency-Check for fine-grained analysis of application dependencies.
What is SLSA and how do you progress between the levels?
SLSA (Supply-chain Levels for Software Artifacts) is a security framework from Google structured in 4 levels. Level 1: the build is scripted and produces provenance (automatable in a few hours). Level 2: use of a hosted build service with signed provenance (GitHub Actions + slsa-github-generator). Level 3: the build service is hardened and the provenance proves strong isolation. Level 4: fully verifiable process with two-party review. Most open source projects aim for level 2-3 as a good security/effort balance.
How do you handle false positives in SCA scans?
False positives are inevitable. To handle them, use .trivyignore or .grype.yaml files to ignore specific CVEs with documented justification. Create VEX (Vulnerability Exploitability eXchange) documents in CycloneDX format that officially declare why a CVE is not exploitable in your context (component not called, mitigations in place). Define a clear policy: only CRITICAL CVEs without a workaround block the pipeline, HIGH ones require a tracking ticket within 30 days. Review exceptions quarterly.
How do you configure Dependabot for automatic security updates?
Add a .github/dependabot.yml file at the root of your repository. Configure each ecosystem there (npm, pip, docker, github-actions) with a frequency (daily/weekly), a branch prefix, and labels. Enable security updates in addition to version updates. For monorepos, declare each directory separately. Combine Dependabot with branch protection rules to require reviewers on Dependabot PRs and avoid automatic updates in production.

Share this tutorial

Did you enjoy this article?

Comments

Checklist Sécurité Linux

30 points essentiels pour sécuriser un serveur Linux. Recevez aussi les nouveaux tutoriels par email.

Pas de spam. Désabonnement en 1 clic.