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.
80
100%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Medium
Suggest reviewing before use
Per github.com/anchore/syft, 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.
--sbom).Per sf-gh:
# 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-jsonOther paths (consult sf-gh): Scoop, Chocolatey, Nix.
Per sf-gh:
# 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.jsonThe default output is the table format (human-readable); use
explicit -o for machine-readable formats in CI.
Per sf-gh, 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.
Per sf-gh, 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.
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.0The attestation lives alongside the image in the registry; downstream consumers can verify provenance + retrieve the SBOM.
Syft generates inventories, not findings - there's no FP triage per se. The analogue here is inventory accuracy: ensuring Syft correctly identifies all components.
| Mechanism | Use |
|---|---|
--exclude=PATH_PATTERN | Skip directories from scan (vendor / generated) |
--catalogers=CATALOGER | Restrict to specific catalogers (e.g., npm, python) |
--source-name=NAME / --source-version=VERSION | Override SBOM-level metadata |
--platform=linux/amd64 | Target 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.
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.*.jsonThe anchore/sbom-action GHA wraps Syft + handles GitHub
dependency-graph submission automatically when format: github-json.
| Sister tool | Use |
|---|---|
grype-scanning | SBOM-driven vuln scanning (grype sbom:./sbom.json) |
cyclonedx-format | Reference for CycloneDX schema + spec compliance |
spdx-format | Reference for SPDX schema + spec compliance |
trivy-image | Alternative scanner (built-in SBOM gen + scan in one pass) |
osv-scanner | Cross-plugin: also accepts SBOM input |
| Anti-pattern | Why it fails | Fix |
|---|---|---|
| Generate SBOM only at release time | Misses build-time inventory differences | Generate per CI build + attest |
| Use single format only | Different consumers need different formats | Generate both CycloneDX + SPDX (Step 2) |
| Skip platform targeting on multi-arch images | Misses platform-specific deps | --platform=linux/amd64 (Step 6) |
| Generate SBOM but don't attest / sign | Provenance unverifiable downstream | Cosign attest pattern (Step 5) |
| Trust Syft inventory without validation | Misses components → misses CVEs | Periodic accuracy check (Step 6) |
grype-scanning.grype-scanning,
cyclonedx-format,
spdx-format,
trivy-image - sister tools