how to generate an SBOM with syft
Generates a Software Bill of Materials (SBOM) from a container image or filesystem directory using syft, the Anchore SBOM generator, in CycloneDX or SPDX format. Use when an agent or pipeline needs a dependency inventory for supply chain security, license audits, compliance (EO 14028), or CVE triage with Grype. Covers syft v1 scan syntax, output formats, and common failure modes.
TL;DR
Install syft, then run syft scan . -o spdx-json=sbom.spdx.json for a directory or syft scan myimage:latest -o cyclonedx-json=sbom.cdx.json for an image. syft v1 catalogs OS packages plus npm, pip, Go, Maven, and other ecosystems in one pass, no Docker daemon required.
Verbatim output (what a successful run looks like)
New version of syft is available: 1.42.3
✔ Vulnerability DB [no update available]
✔ Indexed image
✔ Cataloged contents [cfae98bc-cdf4-4479-90f2-f58ff35bc6e3]
├─ 25 packages
NAME VERSION TYPE
@babel/runtime 7.24.7 javascript
lodash 4.17.21 javascript
...Steps
1. Install syft
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
syft versionExpected: prints a version like syft 1.42.3. On macOS, brew install syft works too.
2. Scan a directory
syft scan . -o cyclonedx-json=sbom.cdx.jsonExpected: syft indexes the directory, catalogs packages, writes sbom.cdx.json. Use path/to/a/dir for any directory.
3. Scan a container image
syft scan alpine:latest -o spdx-json=sbom.spdx.jsonExpected: if no local Docker daemon is present, syft pulls the image from the registry itself and writes sbom.spdx.json. Prefix with docker: (e.g. docker:myimage:tag) to force scanning a local Docker daemon image.
4. Emit both formats in one run
syft scan . -o cyclonedx-json=sbom.cdx.json -o spdx-json=sbom.spdx.jsonExpected: both files are written. CycloneDX is the friendliest to downstream tooling; SPDX is what regulators and some enterprise auditors expect.
When to use this skill
- use when an agent or CI job needs a package inventory of a container image or source directory
- use when someone asks for an SBOM in a specific format (CycloneDX JSON, SPDX JSON, SPDX tag-value)
- use when preparing for license audits, EO 14028 compliance, or CVE triage feeding Grype
When NOT to use this skill
- not for signing the SBOM or generating attestations (needs cosign or similar)
- not for vulnerability scanning itself; feed the SBOM to Grype for that
- not for cdxgen, Trivy, or package-manager-native SBOM output (
npm sbom); those are different tools
Tool and version compatibility
- syft v1.x (tested against v1.42.3, the current CLI reference)
- syft v0.x accepted
syft [source]without thescansubcommand; v1 preferssyft scan - No Docker daemon required; syft pulls registry images directly
- Output formats: cyclonedx-json, cyclonedx-xml, spdx-json, spdx, spdx-tag-value, json (syft native), table
Variant phrasings
syft: command not found
This is the install step missing. Run the install.sh one-liner in step 1, or brew install syft on macOS, then re-run.
generate SPDX SBOM from a docker image
syft scan docker:myimage:tag -o spdx-json=sbom.spdx.json. The docker: prefix forces the local daemon image instead of a registry pull.
syft scan directory for cyclonedx
syft scan . -o cyclonedx-json=sbom.cdx.json. Append =filename to -o to write the file instead of printing to stdout.
Why it happens (root cause after the fix)
Regulators and auditors standardized on two SBOM formats, and Syft emits both from a single catalog pass: CycloneDX for machine consumption, SPDX for compliance. The v1 CLI kept the root command but made scan the documented subcommand; old one-liners without scan still parse but the reference now shows syft scan everywhere.
Edge cases
- Scanning the whole filesystem (
syft scan /) is slow and permission-noisy; scope to the app directory or image instead - syft catalogs installed packages, not transitive source deps of compiled binaries without package metadata; binary-only scans can miss things
-o spdx-jsondefaults to SPDX 2.3; pinspdx-json@2.2if the consumer requires the older spec- Grype consumes syft output directly:
syft scan myimage:latest -o cyclonedx-json | grypeworks via stdin for quick triage
Maintainer review
No maintainer verification is recorded for this version.
This records the version a maintainer checked. It does not assert that the version is the latest upstream release.