Skip to main content
COSMICBYTEZLABS
NewsSecurityHOWTOsToolsTraining
StudyProjectsNewsletterHire MeAbout
Subscribe

Press Enter to search or Esc to close

News
Security
HOWTOs
Tools
Training
Study
Projects
Newsletter
Hire Me
About
RSS Feed
Reading List
Subscribe

Stay in the Loop

Get the latest security alerts, tutorials, and tech insights delivered to your inbox.

Subscribe NowFree forever. No spam.
COSMICBYTEZLABS

Your trusted source for IT intelligence, cybersecurity insights, and hands-on technical guides.

2815+ Articles
167+ Guides

CONTENT

  • Latest News
  • Security Alerts
  • HOWTOs
  • Checklists
  • Projects
  • Exam Prep

RESOURCES

  • Search
  • Browse Tags
  • Newsletter Archive
  • Reading List
  • RSS Feed

COMPANY

  • About Us
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CosmicBytez Labs. All rights reserved.

System Status: Operational
  1. Home
  2. HOWTOs
  3. Software Bill of Materials (SBOM) Generation with Syft and Grype
Software Bill of Materials (SBOM) Generation with Syft and Grype
HOWTOIntermediate

Software Bill of Materials (SBOM) Generation with Syft and Grype

Generate a complete inventory of every package, library, and dependency in your containers and codebases with Syft, then scan that inventory for known vulnerabilities with Grype — closing the supply-chain visibility gap before an incident forces you to.

Dylan H.

Tutorials

September 14, 2026
6 min read

Prerequisites

  • Docker installed and a container image (or local codebase) to inspect
  • Basic command-line familiarity
  • GitHub Actions access (optional, for the CI/CD integration section)

Introduction

When a critical vulnerability like Log4Shell or the xz-utils backdoor drops, the first question every security team asks is the same: "Are we affected?" If you can't answer that in minutes, you're stuck grepping through container layers and package-lock.json files while the clock runs.

A Software Bill of Materials (SBOM) solves this ahead of time. It's a structured, machine-readable inventory of every component that makes up a piece of software — direct dependencies, transitive dependencies, OS packages, language runtimes, and their exact versions. Regulators (US Executive Order 14028, the EU Cyber Resilience Act) and enterprise customers increasingly require them, but the real value is operational: an SBOM turns "which of our 40 services ship this vulnerable library" from a multi-day fire drill into a single query.

This guide covers two complementary open-source tools from Anchore:

  • Syft — generates SBOMs from container images, filesystems, or archives in formats like SPDX and CycloneDX
  • Grype — consumes an SBOM (or scans directly) and matches its components against known-vulnerability databases (NVD, GitHub Security Advisories, distro trackers)

Together they give you a two-stage pipeline: inventory, then assess — which is more auditable and reusable than a scanner that only reports vulnerabilities and discards the component list.

Prerequisites

  • A Linux, macOS, or WSL2 shell
  • Docker installed if you plan to scan container images
  • Outbound internet access (Grype needs to pull its vulnerability database on first run)
  • Optional: a GitHub repository with Actions enabled, for the CI section

Step 1: Install Syft and Grype

Both tools ship a single static binary and an official install script:

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

Package manager installs are also available (brew install syft grype on macOS, or the anchore/grype and anchore/syft Docker images if you'd rather not install anything locally).

Step 2: Generate an SBOM with Syft

Point Syft at a container image, a local directory, or an archive. Start with a container image:

syft nginx:1.27-alpine -o table

This prints a human-readable table of every package Syft found — Alpine apk packages, plus anything layered on top (npm, pip, gems, Go modules, JAR files, etc.), each with its detected version and package type.

For machine-readable output, generate SPDX or CycloneDX JSON — the two formats most tooling and compliance frameworks expect:

# CycloneDX (widely supported by vulnerability scanners)
syft nginx:1.27-alpine -o cyclonedx-json=nginx-sbom.cdx.json
 
# SPDX (preferred for licensing/compliance audits)
syft nginx:1.27-alpine -o spdx-json=nginx-sbom.spdx.json

You can also scan a local project directory instead of a built image, which is useful for catching issues before you even build a container:

syft dir:. -o cyclonedx-json=app-sbom.cdx.json

Step 3: Scan the SBOM for known vulnerabilities with Grype

Grype can scan an image directly, but feeding it a pre-generated SBOM is faster on repeat runs and keeps the "what's installed" and "what's vulnerable" steps decoupled — the SBOM doesn't change between scans, only the vulnerability database does.

# Scan the SBOM you just generated
grype sbom:nginx-sbom.cdx.json

Sample output:

NAME         INSTALLED  FIXED-IN  TYPE  VULNERABILITY   SEVERITY
libcrypto3   3.3.1-r0   3.3.2-r0  apk   CVE-2026-1234   High
libssl3      3.3.1-r0   3.3.2-r0  apk   CVE-2026-1234   High
busybox      1.36.1-r15 (none)    apk   CVE-2025-9821   Medium

To scan an image directly without a separate SBOM step:

grype nginx:1.27-alpine

Fail a build on high/critical findings — the exit code Grype needs for CI gating:

grype sbom:nginx-sbom.cdx.json --fail-on high

Step 4: Wire it into CI/CD

Add an SBOM-and-scan gate to a GitHub Actions workflow so every image build gets inventoried and checked before it ships:

name: SBOM & Vulnerability Scan
on:
  push:
    branches: [main]
 
jobs:
  sbom-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
 
      - name: Build image
        run: docker build -t myapp:${{ github.sha }} .
 
      - name: Generate SBOM
        uses: anchore/sbom-action@v0
        with:
          image: myapp:${{ github.sha }}
          format: cyclonedx-json
          output-file: sbom.cdx.json
 
      - name: Scan SBOM for vulnerabilities
        uses: anchore/scan-action@v6
        with:
          sbom: sbom.cdx.json
          fail-build: true
          severity-cutoff: high
 
      - name: Upload SBOM as build artifact
        uses: actions/upload-artifact@v4
        with:
          name: sbom
          path: sbom.cdx.json

Archiving the SBOM as a build artifact (or pushing it to an internal registry) means that six months from now, when the next Log4Shell-class CVE hits, you can grep every archived SBOM for the affected package instead of re-scanning every image from scratch.

Verification / Testing

Confirm the pipeline actually catches something real. Anchore maintains an intentionally vulnerable test image:

grype anchore/anchore-engine:v0.9.4 --fail-on critical; echo "exit code: $?"

You should see a non-zero exit code and a list of critical/high findings — this confirms --fail-on will correctly break a CI build. Then confirm the happy path with a minimal, well-maintained image:

grype alpine:latest --fail-on critical; echo "exit code: $?"

This should exit 0 with zero or near-zero critical findings, proving the gate doesn't false-positive on clean images.

Troubleshooting

  • Grype hangs on first run — it's downloading its vulnerability database (several hundred MB). Run grype db status to check, or pre-warm it with grype db update.
  • Syft finds far fewer packages than expected — some ecosystems require specific manifest files (package-lock.json, Pipfile.lock, go.sum) to resolve exact transitive versions. If those lockfiles aren't present in the image/directory, Syft can only report what it can see.
  • "stale database" warnings from Grype — the local vulnerability DB has a TTL (default 5 days). Run grype db update in CI as a pre-step, or schedule a daily refresh, so scans don't run against outdated CVE data.
  • CI gate blocks on a vulnerability with no available fix — use Grype's .grype.yaml ignore rules to suppress a specific CVE with an expiry date and a documented justification, rather than lowering severity-cutoff globally.
  • SPDX vs CycloneDX confusion — if a downstream tool or customer requirement specifies a format, check first; they are not interchangeable, and some scanners (including older Grype versions) only fully support one.

Summary

Syft and Grype split supply-chain security into two clean, composable steps: know what you're running (SBOM generation) and know if it's dangerous (vulnerability matching). Generating SBOMs at build time and archiving them costs almost nothing, but it converts every future "are we affected?" fire drill into a five-minute search instead of a multi-day audit. Start by wiring the CI gate from Step 4 into one repository, tune the --fail-on threshold to your risk tolerance, and expand from there once the false-positive rate settles down.

#devsecops#sbom#supply-chain-security#syft#grype#container-security#vulnerability-management

Related Articles

Container Supply Chain Security: SBOMs and Keyless Signing with Syft, Grype, and Cosign

Build a CI pipeline that generates SBOMs with Syft, scans them for vulnerabilities with Grype, and signs container images keylessly with Cosign — closing the loop between what you shipped and what you can prove you shipped.

9 min read

Chainguard Doubles Output to 1 Billion Build Manifests in Six Months

Chainguard's container image factory doubled its rebuild output from 500 million to over 1 billion manifests, driven by a new agentic pipeline.

3 min read

Container Security Scanning with Trivy: Images, IaC, and CI/CD

Learn how to use Trivy to scan container images, Dockerfiles, Kubernetes manifests, and Terraform for vulnerabilities and misconfigurations — then...

7 min read
Back to all HOWTOs