Testland
Browse all skills & agents

syft-generation

Generates Software Bill of Materials (SBOMs) using Anchore Syft - supports container images / directories / archives across OCI / Docker / Singularity formats; output formats CycloneDX-JSON / SPDX-JSON / Syft-JSON / table / GitHub-JSON; pairs with `grype-scanning` for SBOM-driven vuln scanning. Use when the team needs SBOM artifacts for compliance (US EO 14028, EU CRA, FDA medical-device guidance) or as input to vuln scanners.

Install with skills.sh (any agent)

npx skills add testland/qa --skill syft-generation
View source

syft-generation

Overview

Per github.com/anchore/syft (opens in new window), Syft generates SBOMs from "container images, filesystems, archives" (OCI, Docker, Singularity). The SBOM is the input artifact for vuln scanning (grype-scanning) and for compliance delivery in SPDX or CycloneDX format.

SBOMs are mandated by US EO 14028 (software sold to federal agencies), the EU Cyber Resilience Act (products with digital elements, in effect 2024+), and FDA medical-device guidance; internal supply-chain audits also need a full dependency manifest.

When to use

  • The team ships software to customers requiring an SBOM (federal, EU regulated, medical device, etc.).
  • Internal compliance program requires SBOM as evidence artifact.
  • The vuln-scanning workflow needs an SBOM input (Grype, OSV-Scanner with --sbom).
  • Container-image build pipelines need accompanying SBOM for delivery alongside the image.

Step 1 - Install

Per sf-gh (opens in new window):

# curl install
curl -sSfL https://get.anchore.io/syft | sudo sh -s -- -b /usr/local/bin

# Homebrew
brew install syft

# Docker
docker run --rm -v "$PWD:/scan" anchore/syft scan dir:/scan -o cyclonedx-json

Other paths (consult sf-gh (opens in new window)): Scoop, Chocolatey, Nix.

Step 2 - Basic SBOM generation

Per sf-gh (opens in new window):

# Container image
syft alpine:latest

# Local directory
syft ./my-project

# Specific output format to stdout
syft <image> -o cyclonedx-json

# Multiple formats to files in one pass
syft <image> -o spdx-json=./spdx.json -o cyclonedx-json=./cdx.json

The default output is the table format (human-readable); use explicit -o for machine-readable formats in CI.

Step 3 - Output format catalog

Per sf-gh (opens in new window), the common formats are cyclonedx-json (CycloneDX 1.5+, broad support), spdx-json (SPDX 2.3, preferred by US federal procurement), and syft-json (richest metadata). For grype-scanning input use syft-json or cyclonedx-json; for compliance delivery the consumer dictates (SPDX-JSON US federal, CycloneDX-JSON most EU). The full format catalog is in references/formats.md.

Step 4 - Source types

Per sf-gh (opens in new window), the common sources are a local Docker image (syft alpine:latest), a remote registry (syft registry:docker.io/alpine:latest), an archive (syft oci-archive:./image.tar), and a directory (syft dir:./my-project). The full source-type syntax table is in references/formats.md.

Step 5 - Attestation pattern (cosign)

For supply-chain integrity, attach the SBOM to the container image via Sigstore cosign:

# Generate SBOM
syft my-image:1.0 -o cyclonedx-json=sbom.json

# Sign + attach to image (Sigstore)
cosign attest --predicate sbom.json --type cyclonedx my-image:1.0

# Verify
cosign verify-attestation --type cyclonedx my-image:1.0

The attestation lives alongside the image in the registry; downstream consumers can verify provenance + retrieve the SBOM.

Step 6 - False-positive triage analogue

Syft generates inventories, not findings - there's no FP triage per se. The analogue here is inventory accuracy: ensuring Syft correctly identifies all components.

MechanismUse
--exclude=PATH_PATTERNSkip directories from scan (vendor / generated)
--catalogers=CATALOGERRestrict to specific catalogers (e.g., npm, python)
--source-name=NAME / --source-version=VERSIONOverride SBOM-level metadata
--platform=linux/amd64Target specific platform for multi-arch images

Inventory accuracy validation:

# Compare two SBOMs (e.g., before vs after a build change)
syft image:1.0 -o syft-json=v1-sbom.json
syft image:1.1 -o syft-json=v1.1-sbom.json
diff <(jq -S . v1-sbom.json) <(jq -S . v1.1-sbom.json)

If Syft misses a component (false negative on inventory), the downstream vuln scan misses any CVEs against that component. Periodic accuracy validation against known dependencies catches this.

Step 7 - CI integration

jobs:
  sbom:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - uses: anchore/sbom-action@v0
        with:
          path: ./
          format: cyclonedx-json
          output-file: sbom.cyclonedx.json
      - uses: anchore/sbom-action@v0
        with:
          path: ./
          format: spdx-json
          output-file: sbom.spdx.json
      - uses: actions/upload-artifact@v4
        with:
          name: sboms
          path: sbom.*.json

The anchore/sbom-action GHA wraps Syft + handles GitHub dependency-graph submission automatically when format: github-json.

Step 8 - Composition with sister tools

Sister toolUse
grype-scanningSBOM-driven vuln scanning (grype sbom:./sbom.json)
cyclonedx-formatReference for CycloneDX schema + spec compliance
spdx-formatReference for SPDX schema + spec compliance
trivy-imageAlternative scanner (built-in SBOM gen + scan in one pass)
osv-scannerCross-plugin: also accepts SBOM input

Anti-patterns

Anti-patternWhy it failsFix
Generate SBOM only at release timeMisses build-time inventory differencesGenerate per CI build + attest
Use single format onlyDifferent consumers need different formatsGenerate both CycloneDX + SPDX (Step 2)
Skip platform targeting on multi-arch imagesMisses platform-specific deps--platform=linux/amd64 (Step 6)
Generate SBOM but don't attest / signProvenance unverifiable downstreamCosign attest pattern (Step 5)
Trust Syft inventory without validationMisses components → misses CVEsPeriodic accuracy check (Step 6)

Limitations

  • Syft can't scan what it can't see - encrypted archives, custom package formats may produce incomplete SBOMs.
  • Some language-specific catalogers have edge cases (e.g., npm workspaces, Python wheel quirks); validate against known deps.
  • SBOM generation alone doesn't prove the deps are vulnerability-free - pair with grype-scanning.
  • Multi-arch container scanning is per-platform; combine SBOMs manually or via tooling for unified view.

References

  • sf-gh (opens in new window) - repository, install, scan commands, formats
  • references/formats.md - full output format catalog + source-type syntax
  • anchore.com/syft - landing
  • ntia.gov/SBOM - NTIA SBOM minimum elements
  • whitehouse.gov/briefing-room/presidential-actions/2021/05/12/executive-order-on-improving-the-nations-cybersecurity/ - US EO 14028
  • grype-scanning, cyclonedx-format, spdx-format, trivy-image - sister tools

Syft output formats and source types

View source (opens in new window)

Syft output formats and source types

Full catalogs extracted from syft-generation. Per github.com/anchore/syft (opens in new window), Syft supports multiple SBOM output formats and scan-source types; the SKILL.md spine keeps the common ones inline and links here for the complete tables.

Output format catalog

FormatUse
cyclonedx-jsonCycloneDX 1.5+ JSON; broad ecosystem support
cyclonedx-xmlCycloneDX XML (older toolchains)
spdx-jsonSPDX 2.3 JSON; preferred by US Federal procurement
spdx-tag-valueSPDX tag-value format (legacy)
syft-jsonSyft-native JSON; richest metadata
tableHuman-readable terminal table (default)
github-jsonGitHub dependency-graph submission format

For grype-scanning input, use syft-json (richest metadata) or cyclonedx-json (broader compat). For compliance delivery, the consumer's requirement dictates: SPDX-JSON for US federal, CycloneDX-JSON for most EU contexts.

Source types

SourceSyntax
Local Docker daemonsyft alpine:latest
OCI / remote registrysyft registry:docker.io/alpine:latest
OCI archive (tar)syft oci-archive:./image.tar
Docker archive (tar)syft docker-archive:./image.tar
Local directorysyft dir:./my-project (or syft ./my-project)
Filesyft file:./pom.xml
Singularity imagesyft singularity:./image.sif

Related skills

cyclonedx-format

Reference for the CycloneDX v1.6 software bill of materials (SBOM) specification - OWASP-curated, security-focused format covering software components, services, dependencies, vulnerabilities, formulation, machine learning models, and SaaS BOMs; supports XML / JSON / Protobuf encodings; per-language generators for npm, pip, Maven, Gradle, Go, etc.; integrates with CI via generate + sign + attest workflow. Use when the user asks to generate or write a software bill of materials / SBOM in CycloneDX form, or when the team adopts CycloneDX as its primary SBOM format (preferred for security-focused use cases vs SPDX's licensing focus).

grype-scanning

Scans for vulnerabilities using Anchore Grype: `grype sbom:./sbom.json` / `grype {image}` / `grype dir:./` across OS-package + language-package ecosystems (Alpine / Debian / Ubuntu / RHEL / Amazon Linux / Ruby / Java / JavaScript / Python / .NET / Go / PHP / Rust). `.grype.yaml` per-CVE and per-package ignore rules with mandatory `expires:` dates and reachability justification (the Grype-native suppression path, distinct from standalone VEX document authoring in vex-author); EPSS + KEV + risk-score prioritization; OpenVEX assertion filtering; `--fail-on high/critical` CI gate. Use when the team wants Grype-native vuln scanning, or pairs with Syft (syft-generation) for an SBOM-driven workflow.

sbom-diff

Compares two CycloneDX or SPDX SBOMs to surface net-new, removed, and version-changed components between image or build versions; uses cyclonedx-cli diff for structured output and syft-based generation for the input SBOMs; gates CI on net-new component introduction; enables supply-chain alerting when unexpected dependencies appear across releases. Use when the team needs to detect dependency drift between container image builds, release candidates, or dependency-update branches.

spdx-format

Reference for the SPDX (Software Package Data Exchange) v2.3 + v3.0 SBOM specification - Linux Foundation-curated, license-focused format covering packages, files, snippets, relationships, license declarations, and (in 3.0) AI / dataset / build / security profiles; supports Tag-Value / JSON / YAML / RDF / Spreadsheet encodings; preferred by US Federal procurement (NIST guidance) and Linux distros. Use when the team's SBOM consumer requires SPDX format (federal procurement, Linux Foundation members, license-compliance focus).

trivy-image

Configures and runs Trivy for container image scanning: Aqua Security's all-in-one scanner combining vuln + secret + misconfiguration + license detection in one pass; `trivy image {image}` with --severity HIGH,CRITICAL filter; --format sarif/json (incl. scan-embedded CycloneDX; for standalone SBOM generation see syft-generation + cyclonedx-format); .trivyignore CVE suppression file; --ignore-unfixed for actionable filter; --scanners vuln/misconfig/license/secret toggle. Use when the team wants a single tool covering container image security across multiple dimensions, not for producing a standalone CycloneDX SBOM.

vex-author

Authors and validates OpenVEX documents - produces `not_affected`, `affected`, `fixed`, and `under_investigation` statements with justification codes using `vexctl create`; attaches VEX assertions to container images; outputs `.openvex.json` files consumed on a downstream VEX-filter / vulnerability-prioritization path. Use when a scanner flags a CVE that analysis confirms is not exploitable in your deployment, and a machine-readable `not_affected` assertion is needed to suppress false positives without discarding the finding from the audit trail.