This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

SBOM Generation

Learn how to create a Software Bill of Materials (SBOMs) for container images, filesystems, and archives using Syft.

An SBOM, or Software Bill of Materials, is a detailed list of all the components, libraries, and modules that make up a piece of software.

For a developer, having an SBOM is crucial for tracking dependencies, quickly identifying known vulnerabilities within those components, and ensuring license compliance.

For a consumer or organization using the software, an SBOM provides transparency into the software’s supply chain, allowing them to assess potential security risks and understand what’s “under the hood.”  

Syft is an open-source command-line tool and Go library. Its primary function is to scan container images, file systems, and archives to automatically generate a Software Bill of Materials, making it easier to understand the composition of software.

1 - Getting Started

Use Syft to generate your first SBOM from container images, directories, or archives.

Syft is a CLI tool for generating a Software Bill of Materials (SBOM) from container images and filesystems.

Installation

Syft is provided as a single compiled executable. Run the command for your platform to download the latest release. The full list of official and community maintained packages can be found on the installation page.

curl -sSfL <https://get.anchore.io/syft> | sudo sh -s -- -b /usr/local/bin
brew install syft
nuget install Anchore.Syft

See the installation guide for more options including package managers and manual installation.

Display the contents of a public container image

Run syft against a small container image, which will be pulled from DockerHub. The output will be a simple human-readable table.

syft alpine:latest

The output will look similar to the following table.

NAME                    VERSION      TYPE
alpine-baselayout       3.6.8-r1     apk
alpine-baselayout-data  3.6.8-r1     apk
alpine-keys             2.5-r0       apk
alpine-release          3.21.3-r0    apk
apk-tools               2.14.6-r3    apk
busybox                 1.37.0-r12   apk
busybox-binsh           1.37.0-r12   apk
...

Create an industry-standard SBOM

This command will display the human-readable table and write SBOMs in both SPDX and CycloneDX formats, the two primary industry standards.

syft alpine:latest -o table -o spdx-json=alpine.spdx.json -o cyclonedx-json=alpine.cdx.json

The same table will be displayed, and two SBOM files will be created in the current directory.

Examine the SBOM file contents

We can use jq to extract specific package data from the SBOM files (note: by default Syft outputs JSON on a single line, but you can enable pretty-printing with the SYFT_FORMAT_PRETTY=true environment variable). Both formats structure package information differently:

SPDX format:

jq '.packages[].name' alpine.spdx.json

CycloneDX format:

jq '.components[].name' alpine.cdx.json

Both commands show the packages that Syft found in the container image:

"alpine-baselayout"
"alpine-baselayout-data"
"alpine-keys"
"alpine-release"
"apk-tools"
"busybox"
"busybox-binsh"
...

By default, Syft shows only software visible in the final container image (the “squashed” representation). To include software from all image layers, regardless of its presence in the final image, use --scope all-layers:

syft <image> --scope all-layers

FAQ

Does Syft need internet access?

Only for downloading container images. By default, scanning works offline.

What about private container registries?

Syft supports authentication for private registries. See Private Registries.

Can I use Syft in CI/CD pipelines?

Absolutely! Syft is designed for automation. Generate SBOMs during builds and scan them for vulnerabilities.

What data does Syft send externally?

Nothing. Syft runs entirely locally and doesn’t send any data to external services.

Next steps

Now that you’ve generated your first SBOM, here’s what you can do next:

  • Scan for vulnerabilities: Use Grype to find security issues in your SBOMs
  • Check licenses: Learn about License Scanning to understand dependency licenses
  • Customize output: Explore different Output Formats for various tools and workflows
  • Scan different sources: Discover all Supported Sources Syft can analyze
  • Query SBOM data: Master Working with Syft JSON for advanced data extraction

2 - Supported Sources

Explore the different sources Syft can analyze including container images, OCI registries, directories, files, and archives.

Syft can generate an SBOM from a variety of sources including container images, directories, files, and archives. In most cases, you can simply point Syft at what you want to analyze and it will automatically detect and catalog it correctly.

Catalog a container image from your local daemon or a remote registry:

syft alpine:latest

Catalog a directory (useful for analyzing source code or installed applications):

syft /path/to/project

Catalog a container image archive:

syft image.tar

To explicitly specify the source, use the --from flag:

--from ARG Description
docker Use images from the Docker daemon
podman Use images from the Podman daemon
containerd Use images from the Containerd daemon
docker-archive Use a tarball from disk for archives created from docker save
oci-archive Use a tarball from disk for OCI archives (from Skopeo or otherwise)
oci-dir Read directly from a path on disk for OCI layout directories (from Skopeo or otherwise)
singularity Read directly from a Singularity Image Format (SIF) container file on disk
dir Read directly from a path on disk (any directory)
file Read directly from a path on disk (any single file)
registry Pull image directly from a registry (bypass any container runtimes)

Source-Specific Behaviors

Container Image Sources

When working with container images, Syft applies the following defaults and behaviors:

  • Registry: If no registry is specified in the image reference (e.g. alpine:latest instead of docker.io/alpine:latest), Syft assumes docker.io
  • Platform: For unspecific image references (tags) or multi-arch images pointing to an index (not a manifest), Syft analyzes the linux/amd64 manifest by default. Use the --platform flag to target a different platform.

When you provide an image reference without specifying a source type (i.e. no --from flag), Syft attempts to resolve the image using the following sources in order:

  1. Docker daemon
  2. Podman daemon
  3. Containerd daemon
  4. Direct registry access

For example, when you run syft alpine:latest, Syft will first check your local Docker daemon for the image. If Docker isn’t available, it tries Podman, then Containerd, and finally attempts to pull directly from the registry.

You can override this default behavior with the default-image-pull-source configuration option to always prefer a specific source. See Configuration for more details.

Directory Sources

When you provide a directory path as the source, Syft recursively scans the directory tree to catalog installed software packages and files.

When you point Syft at a directory (especially system directories like /), it automatically skips certain filesystem types to improve scan performance and avoid indexing areas that don’t contain installed software packages.

Filesystems always skipped

  • proc / procfs - Virtual filesystem for process information
  • sysfs - Virtual filesystem for kernel and device information
  • devfs / devtmpfs / udev - Device filesystems

Filesystems conditionally skipped

tmpfs filesystems are only skipped when mounted at these specific locations:

  • /dev - Device files
  • /sys - System information
  • /run and /var/run - Runtime data and process IDs
  • /var/lock - Lock files

These paths are excluded because they contain virtual or temporary runtime data rather than installed software packages. Skipping them significantly improves scan performance and enables you to catalog entire system root directories without getting stuck scanning thousands of irrelevant entries.

Syft identifies these filesystems by reading your system’s mount table (/proc/self/mountinfo on Linux). When a directory matches one of these criteria, the entire directory tree under that mount point is skipped.

File types excluded

These file types are never indexed during directory scans:

  • Character devices
  • Block devices
  • Sockets
  • FIFOs (named pipes)
  • Irregular files

Regular files, directories, and symbolic links are always processed.

Archive Sources

Syft automatically detects and unpacks common archive formats, then catalogs their contents. If an archive is a container image archive (from docker save or skopeo copy), Syft treats it as a container image.

Supported archive formats:

Standard archives:

  • .zip
  • .tar (uncompressed)
  • .rar (read-only extraction)

Compressed tar variants:

  • .tar.gz / .tgz
  • .tar.bz2 / .tbz2
  • .tar.br / .tbr (brotli)
  • .tar.lz4 / .tlz4
  • .tar.sz / .tsz (snappy)
  • .tar.xz / .txz
  • .tar.zst / .tzst (zstandard)

Standalone compression formats (extracted if containing tar):

  • .gz (gzip)
  • .bz2 (bzip2)
  • .br (brotli)
  • .lz4
  • .sz (snappy)
  • .xz
  • .zst / .zstd (zstandard)

OCI Archives and Layout Sources

Syft automatically detects OCI archive and directory structures (including OCI layouts and SIF files) and catalogs them accordingly.

OCI archives and layouts are particularly useful for CI/CD pipelines, as they allow you to catalog images, scan for vulnerabilities, or perform other checks without publishing to a registry. This provides a powerful pattern for build-time gating.

Create OCI sources without a registry

OCI archive from an image:

skopeo copy \
  docker://alpine@sha256:eafc1edb577d2e9b458664a15f23ea1c370214193226069eb22921169fc7e43f \
  oci-archive:alpine.tar

OCI layout directory from an image:

skopeo copy \
  docker://alpine@sha256:eafc1edb577d2e9b458664a15f23ea1c370214193226069eb22921169fc7e43f \
  oci:alpine

Container image archive from an image:

docker save -o alpine.tar alpine:latest

Container Runtime Configuration

Image Availability and Authentication

When using container runtime sources (Docker, Podman, or Containerd):

  • Missing images: If an image doesn’t exist locally in the container runtime, Syft attempts to pull it from the registry via the runtime
  • Private images: You must be logged in to the registry via the container runtime (e.g., docker login) or have credentials configured for direct registry access. See Authentication with Private Registries for more details.

Environment Variables

Syft respects the following environment variables for each container runtime:

Source Environment Variables Description
Docker DOCKER_HOST Docker daemon socket/host address (supports ssh:// for remote connections)
DOCKER_TLS_VERIFY Enable TLS verification (auto-sets DOCKER_CERT_PATH if not set)
DOCKER_CERT_PATH Path to TLS certificates (defaults to ~/.docker if DOCKER_TLS_VERIFY is set)
DOCKER_CONFIG Override default Docker config directory
Podman CONTAINER_HOST Podman socket/host address (e.g., unix:///run/podman/podman.sock or ssh://user@host/path/to/socket)
CONTAINER_SSHKEY SSH identity file path for remote Podman connections
CONTAINER_PASSPHRASE Passphrase for the SSH key
Containerd CONTAINERD_ADDRESS Containerd socket address (overrides default /run/containerd/containerd.sock)
CONTAINERD_NAMESPACE Containerd namespace (defaults to default)

Podman Daemon Requirements

Unlike Docker Desktop, which typically auto-starts, Podman requires explicitly starting the service.

Syft attempts to connect to Podman using the following methods in order:

  1. Unix Socket (primary)

    • Checks CONTAINER_HOST environment variable first
    • Falls back to Podman config files
    • Finally tries default socket locations ($XDG_RUNTIME_DIR/podman/podman.sockand/run/podman/podman.sock`)
  2. SSH (fallback)

    • Configured via CONTAINER_HOST, CONTAINER_SSHKEY, and CONTAINER_PASSPHRASE environment variables
    • Used for remote Podman instances

Direct Registry Access

The registry source bypasses container runtimes entirely and pulls images directly from the registry.

Credentials are resolved in the following order:

  • Syft first attempts to use default Docker credentials from ~/.docker/config.json if they exist
  • If default credentials are not available, you can provide credentials via environment variables. See Authentication with Private Registries for more details.

3 - Output Formats

Choose from multiple SBOM output formats including SPDX, CycloneDX, and Syft’s native JSON format.

Syft supports multiple output formats to fit different workflows and requirements by using the -o (or --output) flag:

syft <image> -o <format>

Available formats

Syft-native formats

-o ARG Description
table A columnar summary (default)
json Native output for Syft—use this to get as much information out of Syft as possible! (see the JSON schema)
purls A line-separated list of Package URLs (PURLs) for all discovered packages
github-json A JSON report conforming to GitHub’s dependency snapshot format
template Lets you specify a custom output format via Go templates (see Templates for more detail)
text A row-oriented, human-and-machine-friendly output

CycloneDX

CycloneDX is an OWASP-maintained industry standard SBOM format.

-o ARG Description
cyclonedx-json A JSON report conforming to the CycloneDX specification
cyclonedx-xml An XML report conforming to the CycloneDX specification

SPDX

SPDX (Software Package Data Exchange) is an ISO/IEC 5962:2021 industry standard SBOM format.

-o ARG Description
spdx-json A JSON report conforming to the SPDX JSON Schema
spdx-tag-value A tag-value formatted report conforming to the SPDX specification

Format versions

Some output formats support multiple schema versions. Specify a version by appending @<version> to the format name:

syft <source> -o <format>@<version>

Examples:

# Use CycloneDX JSON version 1.4
syft <source> -o cyclonedx-json@1.4

# Use SPDX JSON version 2.2
syft <source> -o spdx-json@2.2

# Default to latest version if not specified
syft <source> -o cyclonedx-json

Formats with version support:

  • cyclonedx-json: 1.2, 1.3, 1.4, 1.5, 1.6
  • cyclonedx-xml: 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6
  • spdx-json: 2.2, 2.3
  • spdx-tag-value: 2.1, 2.2, 2.3

When no version is specified, Syft uses the latest supported version of the format.

Format examples

NAME     VERSION  TYPE
busybox  1.37.0   binary
{
  "artifacts": [
    {
      "id": "74d9294c42941b37",
      "name": "busybox",
      "version": "1.37.0",
      "type": "binary",
      "foundBy": "binary-classifier-cataloger",
      "locations": [
        {
          "path": "/bin/[",
          "layerID": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19",
          "accessPath": "/bin/busybox",
          "annotations": { "evidence": "primary" }
        }
      ],
      "licenses": [],
      "language": "",
      "cpes": [{ "cpe": "cpe:2.3:a:busybox:busybox:1.37.0:*:*:*:*:*:*:*", "source": "nvd-cpe-dictionary" }],
      "purl": "pkg:generic/busybox@1.37.0",
      "metadataType": "binary-signature",
      "metadata": {
        "matches": [
          {
            "classifier": "busybox-binary",
            "location": {
              "path": "/bin/[",
              "layerID": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19",
              "accessPath": "/bin/busybox",
              "annotations": { "evidence": "primary" }
            }
          }
        ]
      }
    }
  ],
  "artifactRelationships": [
    {
      "parent": "74d9294c42941b37",
      "child": "de0bf36b25443562",
      "type": "evident-by",
      "metadata": { "kind": "primary" }
    },
    {
      "parent": "cddc8af5547af9de5e6fb66b36d66ef7418561204e1255ae528d0b2c919d09a3",
      "child": "74d9294c42941b37",
      "type": "contains"
    }
  ],
  "files": [
    {
      "id": "de0bf36b25443562",
      "location": {
        "path": "/bin/[",
        "layerID": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19"
      },
      "metadata": {
        "mode": 755,
        "type": "RegularFile",
        "userID": 0,
        "groupID": 0,
        "mimeType": "application/x-sharedlib",
        "size": 1119784
      },
      "digests": [
        { "algorithm": "sha1", "value": "99f9c7cb06f6f8f074b5c16245f295e33844855a" },
        { "algorithm": "sha256", "value": "8a4212147744cedcf7f679c81921942c81eb3b8d356bbb2b08b51336b2fe8add" }
      ],
      "executable": {
        "format": "elf",
        "hasExports": true,
        "hasEntrypoint": true,
        "importedLibraries": ["libm.so.6", "libresolv.so.2", "libc.so.6"],
        "elfSecurityFeatures": {
          "symbolTableStripped": true,
          "stackCanary": false,
          "nx": true,
          "relRO": "partial",
          "pie": true,
          "dso": true,
          "safeStack": false
        }
      }
    },
    {
      "id": "b240ee11665506ce",
      "location": {
        "path": "/bin/getconf",
        "layerID": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19"
      },
      "executable": {
        "format": "elf",
        "hasExports": true,
        "hasEntrypoint": true,
        "importedLibraries": ["libc.so.6"],
        "elfSecurityFeatures": {
          "symbolTableStripped": true,
          "stackCanary": false,
          "nx": true,
          "relRO": "full",
          "pie": true,
          "dso": true,
          "safeStack": false
        }
      },
      "unknowns": ["unknowns-labeler: no package identified in executable file"]
    },
    {
      "id": "48a6e9fa63c5f6cc",
      "location": {
        "path": "/lib/ld-linux-aarch64.so.1",
        "layerID": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19"
      },
      "executable": {
        "format": "elf",
        "hasExports": true,
        "hasEntrypoint": true,
        "importedLibraries": [],
        "elfSecurityFeatures": {
          "symbolTableStripped": true,
          "stackCanary": true,
          "nx": true,
          "relRO": "full",
          "pie": false,
          "dso": true,
          "safeStack": false
        }
      },
      "unknowns": ["unknowns-labeler: no package identified in executable file"]
    },
    {
      "id": "a2dc8cb35e1e0485",
      "location": {
        "path": "/lib/libc.so.6",
        "layerID": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19"
      },
      "executable": {
        "format": "elf",
        "hasExports": true,
        "hasEntrypoint": true,
        "importedLibraries": ["ld-linux-aarch64.so.1"],
        "elfSecurityFeatures": {
          "symbolTableStripped": true,
          "stackCanary": true,
          "nx": true,
          "relRO": "full",
          "pie": false,
          "dso": true,
          "safeStack": false
        }
      },
      "unknowns": ["unknowns-labeler: no package identified in executable file"]
    },
    {
      "id": "8746a5a87ab9e597",
      "location": {
        "path": "/lib/libm.so.6",
        "layerID": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19"
      },
      "executable": {
        "format": "elf",
        "hasExports": true,
        "hasEntrypoint": false,
        "importedLibraries": ["libc.so.6", "ld-linux-aarch64.so.1"],
        "elfSecurityFeatures": {
          "symbolTableStripped": true,
          "stackCanary": true,
          "nx": true,
          "relRO": "full",
          "pie": false,
          "dso": true,
          "safeStack": false
        }
      },
      "unknowns": ["unknowns-labeler: no package identified in executable file"]
    },
    {
      "id": "75835d9334e3cd14",
      "location": {
        "path": "/lib/libnss_compat.so.2",
        "layerID": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19"
      },
      "executable": {
        "format": "elf",
        "hasExports": true,
        "hasEntrypoint": false,
        "importedLibraries": ["libc.so.6", "ld-linux-aarch64.so.1"],
        "elfSecurityFeatures": {
          "symbolTableStripped": true,
          "stackCanary": true,
          "nx": true,
          "relRO": "full",
          "pie": false,
          "dso": true,
          "safeStack": false
        }
      },
      "unknowns": ["unknowns-labeler: no package identified in executable file"]
    },
    {
      "id": "a75d014485c88e79",
      "location": {
        "path": "/lib/libnss_dns.so.2",
        "layerID": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19"
      },
      "executable": {
        "format": "elf",
        "hasExports": true,
        "hasEntrypoint": false,
        "importedLibraries": ["libc.so.6"],
        "elfSecurityFeatures": {
          "symbolTableStripped": true,
          "stackCanary": false,
          "nx": true,
          "relRO": "full",
          "pie": false,
          "dso": true,
          "safeStack": false
        }
      },
      "unknowns": ["unknowns-labeler: no package identified in executable file"]
    },
    {
      "id": "b5abc725c65d58cf",
      "location": {
        "path": "/lib/libnss_files.so.2",
        "layerID": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19"
      },
      "executable": {
        "format": "elf",
        "hasExports": true,
        "hasEntrypoint": false,
        "importedLibraries": ["libc.so.6"],
        "elfSecurityFeatures": {
          "symbolTableStripped": true,
          "stackCanary": false,
          "nx": true,
          "relRO": "full",
          "pie": false,
          "dso": true,
          "safeStack": false
        }
      },
      "unknowns": ["unknowns-labeler: no package identified in executable file"]
    },
    {
      "id": "8570ef9dff59aa56",
      "location": {
        "path": "/lib/libnss_hesiod.so.2",
        "layerID": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19"
      },
      "executable": {
        "format": "elf",
        "hasExports": true,
        "hasEntrypoint": false,
        "importedLibraries": ["libresolv.so.2", "libc.so.6", "ld-linux-aarch64.so.1"],
        "elfSecurityFeatures": {
          "symbolTableStripped": true,
          "stackCanary": true,
          "nx": true,
          "relRO": "full",
          "pie": false,
          "dso": true,
          "safeStack": false
        }
      },
      "unknowns": ["unknowns-labeler: no package identified in executable file"]
    },
    {
      "id": "585855f0b92c8232",
      "location": {
        "path": "/lib/libpthread.so.0",
        "layerID": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19"
      },
      "executable": {
        "format": "elf",
        "hasExports": true,
        "hasEntrypoint": false,
        "importedLibraries": ["libc.so.6"],
        "elfSecurityFeatures": {
          "symbolTableStripped": true,
          "stackCanary": false,
          "nx": true,
          "relRO": "full",
          "pie": false,
          "dso": true,
          "safeStack": false
        }
      },
      "unknowns": ["unknowns-labeler: no package identified in executable file"]
    },
    {
      "id": "ee8c205846a71e54",
      "location": {
        "path": "/lib/libresolv.so.2",
        "layerID": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19"
      },
      "executable": {
        "format": "elf",
        "hasExports": true,
        "hasEntrypoint": false,
        "importedLibraries": ["libc.so.6", "ld-linux-aarch64.so.1"],
        "elfSecurityFeatures": {
          "symbolTableStripped": true,
          "stackCanary": true,
          "nx": true,
          "relRO": "full",
          "pie": false,
          "dso": true,
          "safeStack": false
        }
      },
      "unknowns": ["unknowns-labeler: no package identified in executable file"]
    }
  ],
  "source": {
    "id": "cddc8af5547af9de5e6fb66b36d66ef7418561204e1255ae528d0b2c919d09a3",
    "name": "busybox",
    "version": "sha256:cddc8af5547af9de5e6fb66b36d66ef7418561204e1255ae528d0b2c919d09a3",
    "type": "image",
    "metadata": {
      "userInput": "busybox:latest",
      "imageID": "sha256:e8291c1a323abf610ebeb32699b8df3e8046823b5dfbf795d888c9c6a73aeff8",
      "manifestDigest": "sha256:cddc8af5547af9de5e6fb66b36d66ef7418561204e1255ae528d0b2c919d09a3",
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "tags": [],
      "imageSize": 4170750,
      "layers": [
        {
          "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
          "digest": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19",
          "size": 4170750
        }
      ],
      "manifest": "ewoJInNjaGVtYVZlcnNpb24iOiAyLAoJIm1lZGlhVHlwZSI6ICJhcHBsaWNhdGlvbi92bmQub2NpLmltYWdlLm1hbmlmZXN0LnYxK2pzb24iLAoJImNvbmZpZyI6IHsKCQkibWVkaWFUeXBlIjogImFwcGxpY2F0aW9uL3ZuZC5vY2kuaW1hZ2UuY29uZmlnLnYxK2pzb24iLAoJCSJkaWdlc3QiOiAic2hhMjU2OmU4MjkxYzFhMzIzYWJmNjEwZWJlYjMyNjk5YjhkZjNlODA0NjgyM2I1ZGZiZjc5NWQ4ODhjOWM2YTczYWVmZjgiLAoJCSJzaXplIjogNDc3Cgl9LAoJImxheWVycyI6IFsKCQl7CgkJCSJtZWRpYVR5cGUiOiAiYXBwbGljYXRpb24vdm5kLm9jaS5pbWFnZS5sYXllci52MS50YXIrZ3ppcCIsCgkJCSJkaWdlc3QiOiAic2hhMjU2OjQ5OWJjZjNjOGVhZDhlZjI1NzBmN2VlOGU0YWI1YTQ0ODk2NDdkNjdkZDFjMWI0MjVmZGJkNGE3NGY0YjQzODYiLAoJCQkic2l6ZSI6IDE5MDI3NjYKCQl9CgldLAoJImFubm90YXRpb25zIjogewoJCSJvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudXJsIjogImh0dHBzOi8vZ2l0aHViLmNvbS9kb2NrZXItbGlicmFyeS9idXN5Ym94IiwKCQkib3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlcnNpb24iOiAiMS4zNy4wLWdsaWJjIgoJfQp9Cg==",
      "config": "ewoJImNvbmZpZyI6IHsKCQkiQ21kIjogWwoJCQkic2giCgkJXSwKCQkiRW52IjogWwoJCQkiUEFUSD0vdXNyL2xvY2FsL3NiaW46L3Vzci9sb2NhbC9iaW46L3Vzci9zYmluOi91c3IvYmluOi9zYmluOi9iaW4iCgkJXQoJfSwKCSJjcmVhdGVkIjogIjIwMjQtMDktMjZUMjE6MzE6NDJaIiwKCSJoaXN0b3J5IjogWwoJCXsKCQkJImNyZWF0ZWQiOiAiMjAyNC0wOS0yNlQyMTozMTo0MloiLAoJCQkiY3JlYXRlZF9ieSI6ICJCdXN5Qm94IDEuMzcuMCAoZ2xpYmMpLCBEZWJpYW4gMTMiCgkJfQoJXSwKCSJyb290ZnMiOiB7CgkJInR5cGUiOiAibGF5ZXJzIiwKCQkiZGlmZl9pZHMiOiBbCgkJCSJzaGEyNTY6NmFiYTVlMGQzMmQ5MWUzZTkyMzg1NGRjYjMwNTg4ZGM0MTEyYmZhMWRhZTgyYjg5NTM1YWQzMWQzMjJhN2IxOSIKCQldCgl9LAoJImFyY2hpdGVjdHVyZSI6ICJhcm02NCIsCgkib3MiOiAibGludXgiLAoJInZhcmlhbnQiOiAidjgiCn0K",
      "repoDigests": [
        "index.docker.io/library/busybox@sha256:d82f458899c9696cb26a7c02d5568f81c8c8223f8661bb2a7988b269c8b9051e"
      ],
      "architecture": "arm64",
      "os": "linux"
    }
  },
  "distro": {
    "prettyName": "BusyBox v1.37.0",
    "name": "busybox",
    "id": "busybox",
    "idLike": ["busybox"],
    "version": "1.37.0",
    "versionID": "1.37.0"
  },
  "descriptor": {
    "name": "syft",
    "version": "1.33.0",
    "configuration": {
      "catalogers": {
        "requested": { "default": ["image", "file"] },
        "used": [
          "alpm-db-cataloger",
          "apk-db-cataloger",
          "binary-classifier-cataloger",
          "bitnami-cataloger",
          "cargo-auditable-binary-cataloger",
          "conan-info-cataloger",
          "dotnet-deps-binary-cataloger",
          "dotnet-packages-lock-cataloger",
          "dpkg-db-cataloger",
          "elf-binary-package-cataloger",
          "file-content-cataloger",
          "file-digest-cataloger",
          "file-executable-cataloger",
          "file-metadata-cataloger",
          "go-module-binary-cataloger",
          "graalvm-native-image-cataloger",
          "homebrew-cataloger",
          "java-archive-cataloger",
          "java-jvm-cataloger",
          "javascript-package-cataloger",
          "linux-kernel-cataloger",
          "lua-rock-cataloger",
          "nix-cataloger",
          "pe-binary-package-cataloger",
          "php-composer-installed-cataloger",
          "php-interpreter-cataloger",
          "php-pear-serialized-cataloger",
          "portage-cataloger",
          "python-installed-package-cataloger",
          "r-package-cataloger",
          "rpm-db-cataloger",
          "ruby-installed-gemspec-cataloger",
          "wordpress-plugins-cataloger"
        ]
      },
      "data-generation": { "generate-cpes": true },
      "files": {
        "content": { "globs": null, "skip-files-above-size": 0 },
        "hashers": ["sha-1", "sha-256"],
        "selection": "owned-by-package"
      },
      "licenses": { "coverage": 75, "include-content": "none" },
      "packages": {
        "binary": [
          "python-binary",
          "python-binary-lib",
          "pypy-binary-lib",
          "go-binary",
          "julia-binary",
          "helm",
          "redis-binary",
          "nodejs-binary",
          "go-binary-hint",
          "busybox-binary",
          "util-linux-binary",
          "haproxy-binary",
          "perl-binary",
          "php-composer-binary",
          "httpd-binary",
          "memcached-binary",
          "traefik-binary",
          "arangodb-binary",
          "postgresql-binary",
          "mysql-binary",
          "mysql-binary",
          "mysql-binary",
          "xtrabackup-binary",
          "mariadb-binary",
          "rust-standard-library-linux",
          "rust-standard-library-macos",
          "ruby-binary",
          "erlang-binary",
          "erlang-alpine-binary",
          "erlang-library",
          "swipl-binary",
          "dart-binary",
          "haskell-ghc-binary",
          "haskell-cabal-binary",
          "haskell-stack-binary",
          "consul-binary",
          "hashicorp-vault-binary",
          "nginx-binary",
          "bash-binary",
          "openssl-binary",
          "gcc-binary",
          "fluent-bit-binary",
          "wordpress-cli-binary",
          "curl-binary",
          "lighttpd-binary",
          "proftpd-binary",
          "zstd-binary",
          "xz-binary",
          "gzip-binary",
          "sqlcipher-binary",
          "jq-binary",
          "chrome-binary",
          "ffmpeg-binary",
          "java-binary",
          "java-jdb-binary"
        ],
        "dotnet": {
          "dep-packages-must-claim-dll": true,
          "dep-packages-must-have-dll": false,
          "propagate-dll-claims-to-parents": true,
          "relax-dll-claims-when-bundling-detected": true
        },
        "golang": {
          "local-mod-cache-dir": "/go/pkg/mod",
          "local-vendor-dir": "",
          "main-module-version": { "from-build-settings": true, "from-contents": false, "from-ld-flags": true },
          "proxies": ["https://proxy.golang.org", "direct"],
          "search-local-mod-cache-licenses": false,
          "search-local-vendor-licenses": false,
          "search-remote-licenses": false
        },
        "java-archive": {
          "include-indexed-archives": true,
          "include-unindexed-archives": false,
          "maven-base-url": "https://repo1.maven.org/maven2",
          "maven-localrepository-dir": "/.m2/repository",
          "max-parent-recursive-depth": 0,
          "resolve-transitive-dependencies": false,
          "use-maven-localrepository": false,
          "use-network": false
        },
        "javascript": {
          "include-dev-dependencies": false,
          "npm-base-url": "https://registry.npmjs.org",
          "search-remote-licenses": false
        },
        "linux-kernel": { "catalog-modules": true },
        "nix": { "capture-owned-files": false },
        "python": { "guess-unpinned-requirements": false }
      },
      "relationships": {
        "exclude-binary-packages-with-file-ownership-overlap": true,
        "package-file-ownership": true,
        "package-file-ownership-overlap": true
      },
      "search": { "scope": "squashed" }
    }
  },
  "schema": {
    "version": "16.0.39",
    "url": "https://raw.githubusercontent.com/anchore/syft/main/schema/json/schema-16.0.39.json"
  }
}
pkg:generic/busybox@1.37.0
{
  "$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json",
  "bomFormat": "CycloneDX",
  "specVersion": "1.6",
  "serialNumber": "urn:uuid:ad79379e-ec73-4989-b6b7-31c113221b72",
  "version": 1,
  "metadata": {
    "timestamp": "2025-10-09T14:08:19Z",
    "tools": { "components": [{ "type": "application", "author": "anchore", "name": "syft", "version": "1.33.0" }] },
    "component": {
      "bom-ref": "84d86520b9546322",
      "type": "container",
      "name": "busybox",
      "version": "sha256:cddc8af5547af9de5e6fb66b36d66ef7418561204e1255ae528d0b2c919d09a3"
    }
  },
  "components": [
    {
      "bom-ref": "pkg:generic/busybox@1.37.0?package-id=74d9294c42941b37",
      "type": "application",
      "name": "busybox",
      "version": "1.37.0",
      "cpe": "cpe:2.3:a:busybox:busybox:1.37.0:*:*:*:*:*:*:*",
      "purl": "pkg:generic/busybox@1.37.0",
      "properties": [
        { "name": "syft:package:foundBy", "value": "binary-classifier-cataloger" },
        { "name": "syft:package:type", "value": "binary" },
        { "name": "syft:package:metadataType", "value": "binary-signature" },
        {
          "name": "syft:location:0:layerID",
          "value": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19"
        },
        { "name": "syft:location:0:path", "value": "/bin/[" }
      ]
    },
    {
      "bom-ref": "os:busybox@1.37.0",
      "type": "operating-system",
      "name": "busybox",
      "version": "1.37.0",
      "description": "BusyBox v1.37.0",
      "swid": { "tagId": "busybox", "name": "busybox", "version": "1.37.0" },
      "properties": [
        { "name": "syft:distro:extendedSupport", "value": "false" },
        { "name": "syft:distro:id", "value": "busybox" },
        { "name": "syft:distro:idLike:0", "value": "busybox" },
        { "name": "syft:distro:prettyName", "value": "BusyBox v1.37.0" },
        { "name": "syft:distro:versionID", "value": "1.37.0" }
      ]
    },
    {
      "bom-ref": "de0bf36b25443562",
      "type": "file",
      "name": "/bin/[",
      "hashes": [
        { "alg": "SHA-1", "content": "99f9c7cb06f6f8f074b5c16245f295e33844855a" },
        { "alg": "SHA-256", "content": "8a4212147744cedcf7f679c81921942c81eb3b8d356bbb2b08b51336b2fe8add" }
      ]
    }
  ]
}
<?xml version="1.0" encoding="UTF-8"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.6" serialNumber="urn:uuid:34686a58-0f6f-42ef-93ea-db6ce62f4dec" version="1"><metadata><timestamp>2025-10-09T14:08:20Z</timestamp><tools><components><component type="application"><author>anchore</author><name>syft</name><version>1.33.0</version></component></components></tools><component bom-ref="84d86520b9546322" type="container"><name>busybox</name><version>sha256:cddc8af5547af9de5e6fb66b36d66ef7418561204e1255ae528d0b2c919d09a3</version></component></metadata><components><component bom-ref="pkg:generic/busybox@1.37.0?package-id=74d9294c42941b37" type="application"><name>busybox</name><version>1.37.0</version><cpe>cpe:2.3:a:busybox:busybox:1.37.0:*:*:*:*:*:*:*</cpe><purl>pkg:generic/busybox@1.37.0</purl><properties><property name="syft:package:foundBy">binary-classifier-cataloger</property><property name="syft:package:type">binary</property><property name="syft:package:metadataType">binary-signature</property><property name="syft:location:0:layerID">sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19</property><property name="syft:location:0:path">/bin/[</property></properties></component><component bom-ref="os:busybox@1.37.0" type="operating-system"><name>busybox</name><version>1.37.0</version><description>BusyBox v1.37.0</description><swid tagId="busybox" name="busybox" version="1.37.0"></swid><properties><property name="syft:distro:extendedSupport">false</property><property name="syft:distro:id">busybox</property><property name="syft:distro:idLike:0">busybox</property><property name="syft:distro:prettyName">BusyBox v1.37.0</property><property name="syft:distro:versionID">1.37.0</property></properties></component><component bom-ref="de0bf36b25443562" type="file"><name>/bin/[</name><hashes><hash alg="SHA-1">99f9c7cb06f6f8f074b5c16245f295e33844855a</hash><hash alg="SHA-256">8a4212147744cedcf7f679c81921942c81eb3b8d356bbb2b08b51336b2fe8add</hash></hashes></component></components></bom>
{
  "spdxVersion": "SPDX-2.3",
  "dataLicense": "CC0-1.0",
  "SPDXID": "SPDXRef-DOCUMENT",
  "name": "busybox",
  "documentNamespace": "https://anchore.com/syft/image/busybox-528e282e-94ed-49cc-9050-e1cd5bf3c766",
  "creationInfo": {
    "licenseListVersion": "3.27",
    "creators": ["Organization: Anchore, Inc", "Tool: syft-1.33.0"],
    "created": "2025-10-09T14:08:20Z"
  },
  "packages": [
    {
      "name": "busybox",
      "SPDXID": "SPDXRef-Package-binary-busybox-74d9294c42941b37",
      "versionInfo": "1.37.0",
      "supplier": "NOASSERTION",
      "downloadLocation": "NOASSERTION",
      "filesAnalyzed": false,
      "sourceInfo": "acquired package info from the following paths: /bin/[",
      "licenseConcluded": "NOASSERTION",
      "licenseDeclared": "NOASSERTION",
      "copyrightText": "NOASSERTION",
      "externalRefs": [
        {
          "referenceCategory": "SECURITY",
          "referenceType": "cpe23Type",
          "referenceLocator": "cpe:2.3:a:busybox:busybox:1.37.0:*:*:*:*:*:*:*"
        },
        {
          "referenceCategory": "PACKAGE-MANAGER",
          "referenceType": "purl",
          "referenceLocator": "pkg:generic/busybox@1.37.0"
        }
      ]
    },
    {
      "name": "busybox",
      "SPDXID": "SPDXRef-DocumentRoot-Image-busybox",
      "versionInfo": "sha256:cddc8af5547af9de5e6fb66b36d66ef7418561204e1255ae528d0b2c919d09a3",
      "supplier": "NOASSERTION",
      "downloadLocation": "NOASSERTION",
      "filesAnalyzed": false,
      "checksums": [
        { "algorithm": "SHA256", "checksumValue": "cddc8af5547af9de5e6fb66b36d66ef7418561204e1255ae528d0b2c919d09a3" }
      ],
      "licenseConcluded": "NOASSERTION",
      "licenseDeclared": "NOASSERTION",
      "copyrightText": "NOASSERTION",
      "externalRefs": [
        {
          "referenceCategory": "PACKAGE-MANAGER",
          "referenceType": "purl",
          "referenceLocator": "pkg:oci/busybox@sha256%3Acddc8af5547af9de5e6fb66b36d66ef7418561204e1255ae528d0b2c919d09a3?arch=arm64&tag=latest"
        }
      ],
      "primaryPackagePurpose": "CONTAINER"
    }
  ],
  "files": [
    {
      "fileName": "bin/[",
      "SPDXID": "SPDXRef-File-bin---de0bf36b25443562",
      "fileTypes": ["APPLICATION", "BINARY"],
      "checksums": [
        { "algorithm": "SHA1", "checksumValue": "99f9c7cb06f6f8f074b5c16245f295e33844855a" },
        { "algorithm": "SHA256", "checksumValue": "8a4212147744cedcf7f679c81921942c81eb3b8d356bbb2b08b51336b2fe8add" }
      ],
      "licenseConcluded": "NOASSERTION",
      "licenseInfoInFiles": ["NOASSERTION"],
      "copyrightText": "NOASSERTION",
      "comment": "layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19"
    },
    {
      "fileName": "bin/getconf",
      "SPDXID": "SPDXRef-File-bin-getconf-b240ee11665506ce",
      "checksums": [{ "algorithm": "SHA1", "checksumValue": "0000000000000000000000000000000000000000" }],
      "licenseConcluded": "NOASSERTION",
      "licenseInfoInFiles": ["NOASSERTION"],
      "copyrightText": "NOASSERTION",
      "comment": "layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19"
    },
    {
      "fileName": "lib/ld-linux-aarch64.so.1",
      "SPDXID": "SPDXRef-File-lib-ld-linux-aarch64.so.1-48a6e9fa63c5f6cc",
      "checksums": [{ "algorithm": "SHA1", "checksumValue": "0000000000000000000000000000000000000000" }],
      "licenseConcluded": "NOASSERTION",
      "licenseInfoInFiles": ["NOASSERTION"],
      "copyrightText": "NOASSERTION",
      "comment": "layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19"
    },
    {
      "fileName": "lib/libc.so.6",
      "SPDXID": "SPDXRef-File-lib-libc.so.6-a2dc8cb35e1e0485",
      "checksums": [{ "algorithm": "SHA1", "checksumValue": "0000000000000000000000000000000000000000" }],
      "licenseConcluded": "NOASSERTION",
      "licenseInfoInFiles": ["NOASSERTION"],
      "copyrightText": "NOASSERTION",
      "comment": "layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19"
    },
    {
      "fileName": "lib/libm.so.6",
      "SPDXID": "SPDXRef-File-lib-libm.so.6-8746a5a87ab9e597",
      "checksums": [{ "algorithm": "SHA1", "checksumValue": "0000000000000000000000000000000000000000" }],
      "licenseConcluded": "NOASSERTION",
      "licenseInfoInFiles": ["NOASSERTION"],
      "copyrightText": "NOASSERTION",
      "comment": "layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19"
    },
    {
      "fileName": "lib/libnss_compat.so.2",
      "SPDXID": "SPDXRef-File-lib-libnss-compat.so.2-75835d9334e3cd14",
      "checksums": [{ "algorithm": "SHA1", "checksumValue": "0000000000000000000000000000000000000000" }],
      "licenseConcluded": "NOASSERTION",
      "licenseInfoInFiles": ["NOASSERTION"],
      "copyrightText": "NOASSERTION",
      "comment": "layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19"
    },
    {
      "fileName": "lib/libnss_dns.so.2",
      "SPDXID": "SPDXRef-File-lib-libnss-dns.so.2-a75d014485c88e79",
      "checksums": [{ "algorithm": "SHA1", "checksumValue": "0000000000000000000000000000000000000000" }],
      "licenseConcluded": "NOASSERTION",
      "licenseInfoInFiles": ["NOASSERTION"],
      "copyrightText": "NOASSERTION",
      "comment": "layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19"
    },
    {
      "fileName": "lib/libnss_files.so.2",
      "SPDXID": "SPDXRef-File-lib-libnss-files.so.2-b5abc725c65d58cf",
      "checksums": [{ "algorithm": "SHA1", "checksumValue": "0000000000000000000000000000000000000000" }],
      "licenseConcluded": "NOASSERTION",
      "licenseInfoInFiles": ["NOASSERTION"],
      "copyrightText": "NOASSERTION",
      "comment": "layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19"
    },
    {
      "fileName": "lib/libnss_hesiod.so.2",
      "SPDXID": "SPDXRef-File-lib-libnss-hesiod.so.2-8570ef9dff59aa56",
      "checksums": [{ "algorithm": "SHA1", "checksumValue": "0000000000000000000000000000000000000000" }],
      "licenseConcluded": "NOASSERTION",
      "licenseInfoInFiles": ["NOASSERTION"],
      "copyrightText": "NOASSERTION",
      "comment": "layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19"
    },
    {
      "fileName": "lib/libpthread.so.0",
      "SPDXID": "SPDXRef-File-lib-libpthread.so.0-585855f0b92c8232",
      "checksums": [{ "algorithm": "SHA1", "checksumValue": "0000000000000000000000000000000000000000" }],
      "licenseConcluded": "NOASSERTION",
      "licenseInfoInFiles": ["NOASSERTION"],
      "copyrightText": "NOASSERTION",
      "comment": "layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19"
    },
    {
      "fileName": "lib/libresolv.so.2",
      "SPDXID": "SPDXRef-File-lib-libresolv.so.2-ee8c205846a71e54",
      "checksums": [{ "algorithm": "SHA1", "checksumValue": "0000000000000000000000000000000000000000" }],
      "licenseConcluded": "NOASSERTION",
      "licenseInfoInFiles": ["NOASSERTION"],
      "copyrightText": "NOASSERTION",
      "comment": "layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19"
    }
  ],
  "relationships": [
    {
      "spdxElementId": "SPDXRef-Package-binary-busybox-74d9294c42941b37",
      "relatedSpdxElement": "SPDXRef-File-bin---de0bf36b25443562",
      "relationshipType": "OTHER",
      "comment": "evident-by: indicates the package's existence is evident by the given file"
    },
    {
      "spdxElementId": "SPDXRef-DocumentRoot-Image-busybox",
      "relatedSpdxElement": "SPDXRef-Package-binary-busybox-74d9294c42941b37",
      "relationshipType": "CONTAINS"
    },
    {
      "spdxElementId": "SPDXRef-DOCUMENT",
      "relatedSpdxElement": "SPDXRef-DocumentRoot-Image-busybox",
      "relationshipType": "DESCRIBES"
    }
  ]
}
SPDXVersion: SPDX-2.3
DataLicense: CC0-1.0
SPDXID: SPDXRef-DOCUMENT
DocumentName: busybox
DocumentNamespace: https://anchore.com/syft/image/busybox-9e6cffe6-80e8-4cb9-ba5d-a1145b45d8d8
LicenseListVersion: 3.27
Creator: Organization: Anchore, Inc
Creator: Tool: syft-1.33.0
Created: 2025-10-09T14:08:21Z

##### Unpackaged files

FileName: bin/[
SPDXID: SPDXRef-File-bin---de0bf36b25443562
FileType: APPLICATION
FileType: BINARY
FileChecksum: SHA1: 99f9c7cb06f6f8f074b5c16245f295e33844855a
FileChecksum: SHA256: 8a4212147744cedcf7f679c81921942c81eb3b8d356bbb2b08b51336b2fe8add
LicenseConcluded: NOASSERTION
LicenseInfoInFile: NOASSERTION
FileCopyrightText: NOASSERTION
FileComment: layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19

FileName: bin/getconf
SPDXID: SPDXRef-File-bin-getconf-b240ee11665506ce
FileChecksum: SHA1: 0000000000000000000000000000000000000000
LicenseConcluded: NOASSERTION
LicenseInfoInFile: NOASSERTION
FileCopyrightText: NOASSERTION
FileComment: layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19

FileName: lib/ld-linux-aarch64.so.1
SPDXID: SPDXRef-File-lib-ld-linux-aarch64.so.1-48a6e9fa63c5f6cc
FileChecksum: SHA1: 0000000000000000000000000000000000000000
LicenseConcluded: NOASSERTION
LicenseInfoInFile: NOASSERTION
FileCopyrightText: NOASSERTION
FileComment: layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19

FileName: lib/libc.so.6
SPDXID: SPDXRef-File-lib-libc.so.6-a2dc8cb35e1e0485
FileChecksum: SHA1: 0000000000000000000000000000000000000000
LicenseConcluded: NOASSERTION
LicenseInfoInFile: NOASSERTION
FileCopyrightText: NOASSERTION
FileComment: layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19

FileName: lib/libm.so.6
SPDXID: SPDXRef-File-lib-libm.so.6-8746a5a87ab9e597
FileChecksum: SHA1: 0000000000000000000000000000000000000000
LicenseConcluded: NOASSERTION
LicenseInfoInFile: NOASSERTION
FileCopyrightText: NOASSERTION
FileComment: layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19

FileName: lib/libnss_compat.so.2
SPDXID: SPDXRef-File-lib-libnss-compat.so.2-75835d9334e3cd14
FileChecksum: SHA1: 0000000000000000000000000000000000000000
LicenseConcluded: NOASSERTION
LicenseInfoInFile: NOASSERTION
FileCopyrightText: NOASSERTION
FileComment: layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19

FileName: lib/libnss_dns.so.2
SPDXID: SPDXRef-File-lib-libnss-dns.so.2-a75d014485c88e79
FileChecksum: SHA1: 0000000000000000000000000000000000000000
LicenseConcluded: NOASSERTION
LicenseInfoInFile: NOASSERTION
FileCopyrightText: NOASSERTION
FileComment: layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19

FileName: lib/libnss_files.so.2
SPDXID: SPDXRef-File-lib-libnss-files.so.2-b5abc725c65d58cf
FileChecksum: SHA1: 0000000000000000000000000000000000000000
LicenseConcluded: NOASSERTION
LicenseInfoInFile: NOASSERTION
FileCopyrightText: NOASSERTION
FileComment: layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19

FileName: lib/libnss_hesiod.so.2
SPDXID: SPDXRef-File-lib-libnss-hesiod.so.2-8570ef9dff59aa56
FileChecksum: SHA1: 0000000000000000000000000000000000000000
LicenseConcluded: NOASSERTION
LicenseInfoInFile: NOASSERTION
FileCopyrightText: NOASSERTION
FileComment: layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19

FileName: lib/libpthread.so.0
SPDXID: SPDXRef-File-lib-libpthread.so.0-585855f0b92c8232
FileChecksum: SHA1: 0000000000000000000000000000000000000000
LicenseConcluded: NOASSERTION
LicenseInfoInFile: NOASSERTION
FileCopyrightText: NOASSERTION
FileComment: layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19

FileName: lib/libresolv.so.2
SPDXID: SPDXRef-File-lib-libresolv.so.2-ee8c205846a71e54
FileChecksum: SHA1: 0000000000000000000000000000000000000000
LicenseConcluded: NOASSERTION
LicenseInfoInFile: NOASSERTION
FileCopyrightText: NOASSERTION
FileComment: layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19

##### Package: busybox

PackageName: busybox
SPDXID: SPDXRef-DocumentRoot-Image-busybox
PackageVersion: sha256:cddc8af5547af9de5e6fb66b36d66ef7418561204e1255ae528d0b2c919d09a3
PackageSupplier: NOASSERTION
PackageDownloadLocation: NOASSERTION
PrimaryPackagePurpose: CONTAINER
FilesAnalyzed: false
PackageChecksum: SHA256: cddc8af5547af9de5e6fb66b36d66ef7418561204e1255ae528d0b2c919d09a3
PackageLicenseConcluded: NOASSERTION
PackageLicenseDeclared: NOASSERTION
PackageCopyrightText: NOASSERTION
ExternalRef: PACKAGE-MANAGER purl pkg:oci/busybox@sha256%3Acddc8af5547af9de5e6fb66b36d66ef7418561204e1255ae528d0b2c919d09a3?arch=arm64&tag=latest

##### Package: busybox

PackageName: busybox
SPDXID: SPDXRef-Package-binary-busybox-74d9294c42941b37
PackageVersion: 1.37.0
PackageSupplier: NOASSERTION
PackageDownloadLocation: NOASSERTION
FilesAnalyzed: false
PackageSourceInfo: acquired package info from the following paths: /bin/[
PackageLicenseConcluded: NOASSERTION
PackageLicenseDeclared: NOASSERTION
PackageCopyrightText: NOASSERTION
ExternalRef: SECURITY cpe23Type cpe:2.3:a:busybox:busybox:1.37.0:*:*:*:*:*:*:*
ExternalRef: PACKAGE-MANAGER purl pkg:generic/busybox@1.37.0

##### Relationships

Relationship: SPDXRef-Package-binary-busybox-74d9294c42941b37 OTHER SPDXRef-File-bin---de0bf36b25443562
RelationshipComment: evident-by: indicates the package's existence is evident by the given file
Relationship: SPDXRef-DocumentRoot-Image-busybox CONTAINS SPDXRef-Package-binary-busybox-74d9294c42941b37
Relationship: SPDXRef-DOCUMENT DESCRIBES SPDXRef-DocumentRoot-Image-busybox
{
  "version": 0,
  "job": {},
  "detector": {
    "name": "syft",
    "url": "https://github.com/anchore/syft",
    "version": "1.33.0"
  },
  "metadata": {
    "syft:distro": "pkg:generic/busybox@1.37.0?like=busybox"
  },
  "manifests": {
    "busybox:latest:/bin/busybox": {
      "name": "busybox:latest:/bin/busybox",
      "file": {
        "source_location": "busybox:latest:/bin/busybox"
      },
      "metadata": {
        "syft:filesystem": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19"
      },
      "resolved": {
        "pkg:generic/busybox@1.37.0": {
          "package_url": "pkg:generic/busybox@1.37.0",
          "relationship": "direct",
          "scope": "runtime"
        }
      }
    }
  },
  "scanned": "2025-10-09T14:08:21Z"
}

Writing output to files

Direct Syft output to a file instead of stdout by appending =<file> to the format option:

# Write JSON to a file
syft <source> -o json=sbom.json

# Write to stdout (default behavior)
syft <source> -o json

Multiple outputs

Generate multiple SBOM formats in a single run by specifying multiple -o flags:

syft <source> \
  -o json=sbom.json \
  -o spdx-json=sbom.spdx.json

You can both display to terminal and write to file:

syft <source> \
  -o table \           # report to stdout
  -o json=sbom.json    # write to file

Next steps

4 - Working with Syft JSON

Learn how to work with Syft’s native JSON format including querying with jq, extracting metadata, and understanding the SBOM structure.

Syft’s native JSON format provides the most comprehensive view of discovered software components, capturing all package metadata, file details, relationships, and source information.

Since Syft can convert from its native JSON format to standard SBOM formats, capturing your SBOM in Syft JSON format lets you generate any SBOM format as needed for compliance requirements.

Data Shapes

A Syft JSON output contains these main sections:

{
  "artifacts": [], // Package nodes discovered
  "artifactRelationships": [], // Edges between packages and files
  "files": [], // File nodes discovered
  "source": {}, // What was scanned (the image, directory, etc.)
  "distro": {}, // Linux distribution discovered
  "descriptor": {}, // Syft version and configuration that captured this SBOM
  "schema": {} // Schema version
}

Package (artifacts)

A software package discovered by Syft (library, application, OS package, etc.).

{
  "id": "74d9294c42941b37", // Unique identifier for this package that is content addressable
  "name": "openssl",
  "version": "1.1.1k",
  "type": "apk", // Package ecosystem (apk, deb, npm, etc.)
  "foundBy": "apk-cataloger",
  "locations": [
    // Paths used to populate information on this package object
    {
      "path": "/lib/apk/db/installed", // Always the real-path
      "layerID": "sha256:...",
      "accessPath": "/lib/apk/db/installed", // How Syft accessed the file (may be a symlink)
      "annotations": {
        "evidence": "primary" // Qualifies the kind of evidence extracted from this location (primary, supporting)
      }
    }
  ],
  "licenses": [
    {
      "value": "Apache-2.0", // Raw value discovered
      "spdxExpression": "Apache-2.0", // Normalized SPDX expression of the discovered value
      "type": "declared", // "declared", "concluded", or "observed"
      "urls": ["https://..."],
      "locations": [] // Where license was found
    }
  ],
  "language": "c",
  "cpes": [
    {
      "cpe": "cpe:2.3:a:openssl:openssl:1.1.1k:*:*:*:*:*:*:*",
      "source": "nvd-dictionary" // Where the CPE was derived from (nvd-dictionary or syft-generated)
    }
  ],
  "purl": "pkg:apk/alpine/openssl@1.1.1k",
  "metadata": {} // Ecosystem-specific fields (varies by type)
}

File

A file found on disk or referenced in package manager metadata.

{
  "id": "def456",
  "location": {
    "path": "/usr/bin/example",
    "layerID": "sha256:..." // For container images
  },
  "metadata": {
    "mode": 493, // File permissions in octal
    "type": "RegularFile",
    "mimeType": "application/x-executable",
    "size": 12345 // Size in bytes
  },
  "digests": [
    {
      "algorithm": "sha256",
      "value": "abc123..."
    }
  ],
  "licenses": [
    {
      "value": "Apache-2.0", // Raw value discovered
      "spdxExpression": "Apache-2.0", // Normalized SPDX expression of the discovered value
      "type": "declared", // "declared", "concluded", or "observed"
      "evidence": {
        "confidence": 100,
        "offset": 1234, // Byte offset in file
        "extent": 567 // Length of match
      }
    }
  ],
  "executable": {
    "format": "elf", // "elf", "pe", or "macho"
    "hasExports": true,
    "hasEntrypoint": true,
    "importedLibraries": [
      // Shared library dependencies
      "libc.so.6",
      "libssl.so.1.1"
    ],
    "elfSecurityFeatures": {
      // ELF binaries only
      "symbolTableStripped": false,
      "stackCanary": true, // Stack protection
      "nx": true, // No-Execute bit
      "relRO": "full", // Relocation Read-Only
      "pie": true // Position Independent Executable
    }
  }
}

Relationship

Connects any two nodes (package, file, or source) with a typed relationship.

{
  "parent": "package-id", // Package, file, or source ID
  "child": "file-id",
  "type": "contains" // contains, dependency-of, etc.
}

Source

Information about what was scanned (container image, directory, file, etc.).

{
  "id": "sha256:...",
  "name": "alpine:3.9.2", // User input
  "version": "sha256:...",
  "type": "image", // image, directory, file
  "metadata": {
    "imageID": "sha256:...",
    "manifestDigest": "sha256:...",
    "mediaType": "application/vnd.docker...",
    "tags": ["alpine:3.9.2"],
    "repoDigests": []
  }
}

Distribution

Linux distribution details from /etc/os-release or similar sources.

{
  "name": "alpine",
  "version": "3.9.2",
  "idLike": ["alpine"] // Related distributions
}

Location

Describes where a package or file was found.

{
  "path": "/lib/apk/db/installed",
  "layerID": "sha256:...",
  "accessPath": "/var/lib/apk/installed",
  "annotations": {
    "evidence": "primary"
  }
}

The path field always contains the real path after resolving symlinks, while accessPath shows how Syft accessed the file (which may be through a symlink).

The evidence annotation indicates whether this location was used to discover the package (primary) or contains only auxiliary information (supporting).

Descriptor

Syft version and configuration used to generate this SBOM.

{
  "name": "syft",
  "version": "1.0.0",
  "configuration": {} // Syft configuration used
}

The Syft JSON schema is versioned and available in the Syft repository:

JQ Recipes

jq is a command-line tool for querying and manipulating JSON. The following examples demonstrate practical queries for working with Syft JSON output.

Find packages by name pattern:

Uses regex pattern matching to find security-critical packages

.artifacts[] |
  select(.name | test("^(openssl|ssl|crypto)")) |  # Regex pattern match on package name
  {
    name,
    version,
    type  # Package type (apk, deb, rpm, etc.)
  }
syft alpine:3.9.2 -o json | \
  jq '.artifacts[] |
  select(.name | test("^(openssl|ssl|crypto)")) |
  {
    name,
    version,
    type
  }'
{
  "name": "ssl_client",
  "version": "1.29.3-r10",
  "type": "apk"
}

Location of all JARs:

Shows Java packages with their primary installation paths

.artifacts[] |
  select(.type == "java-archive") |  # Filter for JAR packages
  {
    package: "\(.name)@\(.version)",
    path: (.locations[] | select(.annotations.evidence == "primary") | .path)  # Primary installation path
  }
syft openjdk:11-jre-slim -o json | \
  jq '.artifacts[] |
  select(.type == "java-archive") |
  {
    package: "\(.name)@\(.version)",
    path: (.locations[] | select(.annotations.evidence == "primary") | .path)
  }'
{
  "package": "jrt-fs@11.0.16",
  "path": "/usr/local/openjdk-11/lib/jrt-fs.jar"
}

All executable files:

Lists all binary files with their format and entry point status

.files[] |
  select(.executable != null) |  # Filter for executable files
  {
    path: .location.path,
    format: .executable.format,  # ELF, Mach-O, PE, etc.
    importedLibraries: .executable.importedLibraries  # Shared library dependencies
  }
syft alpine:3.9.2 -o json | \
  jq '.files[] |
  select(.executable != null) |
  {
    path: .location.path,
    format: .executable.format,
    importedLibraries: .executable.importedLibraries
  }'
{
  "path": "/bin/busybox",
  "format": "elf",
  "importedLibraries": [
    "libc.musl-aarch64.so.1"
  ]
}
{
  "path": "/lib/ld-musl-aarch64.so.1",
  "format": "elf",
  "importedLibraries": []
}
{
  "path": "/lib/libcrypto.so.1.1",
  "format": "elf",
  "importedLibraries": [
    "libc.musl-aarch64.so.1"
  ]
}
{
  "path": "/lib/libssl.so.1.1",
  "format": "elf",
  "importedLibraries": [
    "libcrypto.so.1.1",
    "libc.musl-aarch64.so.1"
  ]
}
{
  "path": "/lib/libz.so.1.2.11",
  "format": "elf",
  "importedLibraries": [
    "libc.musl-aarch64.so.1"
  ]
}
{
  "path": "/sbin/apk",
  "format": "elf",
  "importedLibraries": [
    "libssl.so.1.1",
    "libcrypto.so.1.1",
    "libz.so.1",
    "libc.musl-aarch64.so.1"
  ]
}
{
  "path": "/sbin/mkmntdirs",
  "format": "elf",
  "importedLibraries": [
    "libc.musl-aarch64.so.1"
  ]
}
{
  "path": "/usr/bin/getconf",
  "format": "elf",
  "importedLibraries": [
    "libc.musl-aarch64.so.1"
  ]
}
{
  "path": "/usr/bin/getent",
  "format": "elf",
  "importedLibraries": [
    "libc.musl-aarch64.so.1"
  ]
}
{
  "path": "/usr/bin/iconv",
  "format": "elf",
  "importedLibraries": [
    "libc.musl-aarch64.so.1"
  ]
}
{
  "path": "/usr/bin/scanelf",
  "format": "elf",
  "importedLibraries": [
    "libc.musl-aarch64.so.1"
  ]
}
{
  "path": "/usr/bin/ssl_client",
  "format": "elf",
  "importedLibraries": [
    "libtls-standalone.so.1",
    "libc.musl-aarch64.so.1"
  ]
}
{
  "path": "/usr/lib/engines-1.1/afalg.so",
  "format": "elf",
  "importedLibraries": [
    "libcrypto.so.1.1",
    "libc.musl-aarch64.so.1"
  ]
}
{
  "path": "/usr/lib/engines-1.1/capi.so",
  "format": "elf",
  "importedLibraries": [
    "libc.musl-aarch64.so.1"
  ]
}
{
  "path": "/usr/lib/engines-1.1/padlock.so",
  "format": "elf",
  "importedLibraries": [
    "libc.musl-aarch64.so.1"
  ]
}
{
  "path": "/usr/lib/libtls-standalone.so.1.0.0",
  "format": "elf",
  "importedLibraries": [
    "libssl.so.1.1",
    "libcrypto.so.1.1",
    "libc.musl-aarch64.so.1"
  ]
}

Binaries not owned by packages:

Uses set operations on relationships to identify untracked binaries that might indicate supply chain issues

. as $root |
  [.files[] | select(.executable != null) | .id] as $binaries |  # All binary IDs
  [.artifactRelationships[] | select(.type == "contains") | .child] as $owned |  # Package-owned files
  ($binaries - $owned) as $unowned |  # Set subtraction to find unowned binaries
  $root.files[] |
  select(.id as $id | $unowned | index($id)) |  # Filter to unowned binaries
  {
    path: .location.path,
    sha256: .digests[] | select(.algorithm == "sha256") | .value  # For integrity verification
  }
syft httpd:2.4.65 -o json | \
  jq '. as $root |
  [.files[] | select(.executable != null) | .id] as $binaries |
  [.artifactRelationships[] | select(.type == "contains") | .child] as $owned |
  ($binaries - $owned) as $unowned |
  $root.files[] |
  select(.id as $id | $unowned | index($id)) |
  {
    path: .location.path,
    sha256: .digests[] | select(.algorithm == "sha256") | .value
  }'
# .syft.yaml
file:
  metadata:
    selection: all
{
  "path": "/usr/local/apache2/bin/ab",
  "sha256": "1aa76de1f9eb534fe22d35a01ccbf7ede03e250f6f5d0a00553e687187565d3a"
}
{
  "path": "/usr/local/apache2/bin/checkgid",
  "sha256": "af3372d60eee3f8132d2bdd10fb8670db8a9965b2e056c267131586184ba11fb"
}
{
  "path": "/usr/local/apache2/bin/fcgistarter",
  "sha256": "eea2fa75671e7e647692cd0352405ef8a0b17167a05770b9552602a3c720bfdb"
}
{
  "path": "/usr/local/apache2/bin/htcacheclean",
  "sha256": "94e0fd5f0f5cf6231080177072846a4e99846f1f534224911e3bed17ce27ec38"
}
{
  "path": "/usr/local/apache2/bin/htdbm",
  "sha256": "e2a41d96c92cb16c98972a043ac380c06f19b5bddbafe0b2d2082ed174f8cfe3"
}
{
  "path": "/usr/local/apache2/bin/htdigest",
  "sha256": "0881598a4fd15455297c186fa301fdb1656ff26d0f77626d54a15421095e047f"
}
{
  "path": "/usr/local/apache2/bin/htpasswd",
  "sha256": "871ef0aa4ae0914747a471bf3917405548abf768dd6c94e3e0177c8e87334d9e"
}
{
  "path": "/usr/local/apache2/bin/httpd",
  "sha256": "4ee82f26958e62065b51ca56ab4c55b32988f27a8402ed518b05d48ed2342142"
}
{
  "path": "/usr/local/apache2/bin/httxt2dbm",
  "sha256": "1d5eb8e5d910760aa859c45e79b541362a84499f08fb79b8773bf9b8faf7bbdb"
}
{
  "path": "/usr/local/apache2/bin/logresolve",
  "sha256": "de8ed1fa5184170fca09980025f40c55d9fbf14b47c73b2575bc90ac1c9bf20e"
}
{
  "path": "/usr/local/apache2/bin/rotatelogs",
  "sha256": "f5ed895712cddcec7f542dee08a1ff74fd00ae3a9b0d92ede429e04ec2b9b8ae"
}
{
  "path": "/usr/local/apache2/bin/suexec",
  "sha256": "264efc529c09a60fed57fcde9e7a2c36f8bb414ae0e1afc9bb85595113ab4ec2"
}
{
  "path": "/usr/local/apache2/modules/mod_access_compat.so",
  "sha256": "0d6322b7d7d3d6c459751f8b271f733fa05a8b56eecd75f608100a5dbf464fc2"
}
{
  "path": "/usr/local/apache2/modules/mod_actions.so",
  "sha256": "6dc5dea7137ec0ae139c545b26efd860c6de7bcc19d2e31db213399c86bf2ead"
}
{
  "path": "/usr/local/apache2/modules/mod_alias.so",
  "sha256": "bb422c4486600ec349ac9b89acaa3793265d69498c30370e678a362900daea04"
}
{
  "path": "/usr/local/apache2/modules/mod_allowmethods.so",
  "sha256": "99a9db80c8f18fe3defb315731af3bceef321a98bd52f518f068ca2632596cee"
}
{
  "path": "/usr/local/apache2/modules/mod_asis.so",
  "sha256": "039014ad5ad3f357e811b570bd9977a772e74f191856981a503e57263b88cc44"
}
{
  "path": "/usr/local/apache2/modules/mod_auth_basic.so",
  "sha256": "1f9534187df98194fa60259c3d9feca05f1b2564d49b37b49da040232e7a327b"
}
{
  "path": "/usr/local/apache2/modules/mod_auth_digest.so",
  "sha256": "ad77d0457b773c9d13097adf47bebcd95297466fc9fb6886b7bff85e2acdd99d"
}
{
  "path": "/usr/local/apache2/modules/mod_auth_form.so",
  "sha256": "ceb56183d83c22ff08853982b0f35f122185cf69d3bcfd948eeb1df32dd12bbb"
}
{
  "path": "/usr/local/apache2/modules/mod_authn_anon.so",
  "sha256": "44308e1d5a65ab64232d27f24a827aa1afdb2fef580dd1a8454788431ebd639f"
}
{
  "path": "/usr/local/apache2/modules/mod_authn_core.so",
  "sha256": "9cbf85b1a20da26483ca4a57186161a2876ca296dd1174ed5a5af9f5301fe5e8"
}
{
  "path": "/usr/local/apache2/modules/mod_authn_dbd.so",
  "sha256": "08dc7b848a67131a091563046e3fc6914e86f248740bd2f23905f2f6df3ce541"
}
{
  "path": "/usr/local/apache2/modules/mod_authn_dbm.so",
  "sha256": "1e5900c8b41ca227b59ba54738154e04841cef2045d8040747e4b7887526a763"
}
{
  "path": "/usr/local/apache2/modules/mod_authn_file.so",
  "sha256": "74f83d5717276ae6a37f4a2d0c54f8d23e57ae1c3f73bb2b332c77860b7421ed"
}
{
  "path": "/usr/local/apache2/modules/mod_authn_socache.so",
  "sha256": "2f51212b62c5bbda54ddec0c1a07f523e96c2b56d987fefa43e0cc42dbf6f5d0"
}
{
  "path": "/usr/local/apache2/modules/mod_authnz_fcgi.so",
  "sha256": "4fa0fa7d3d4b742b3f73a781d2e8d4625d477c76aa0698aa0d499f87e6985554"
}
{
  "path": "/usr/local/apache2/modules/mod_authnz_ldap.so",
  "sha256": "dccffc453f46d201ecb1003b372a6ca417ac40a33036500a2215697b2e5ac0af"
}
{
  "path": "/usr/local/apache2/modules/mod_authz_core.so",
  "sha256": "e2b825ec9e2992b1cc157aef12c4ecd75960604658c3b7aa4a370088e89455b5"
}
{
  "path": "/usr/local/apache2/modules/mod_authz_dbd.so",
  "sha256": "61b427078b5d11b3fd8693cbfa22cb5871dc9784b08d3182b73ad3e99b8579d9"
}
{
  "path": "/usr/local/apache2/modules/mod_authz_dbm.so",
  "sha256": "1d99ed703743d9dd2185a0d7e9e351fa38066b3234ae997e87efa6dc1e4513eb"
}
{
  "path": "/usr/local/apache2/modules/mod_authz_groupfile.so",
  "sha256": "3e9adb775d41a8b01802ff610dda01f8e62a0d282ea0522d297a252207453c4d"
}
{
  "path": "/usr/local/apache2/modules/mod_authz_host.so",
  "sha256": "c0fcd53dc9596fd6bc280c55d14b61c72dc12470bf5c1bc86e369217af05cb2c"
}
{
  "path": "/usr/local/apache2/modules/mod_authz_owner.so",
  "sha256": "e8923ef5f11e03c37b4579e18d396758ee085bae4dadc0519374ca63da86c932"
}
{
  "path": "/usr/local/apache2/modules/mod_authz_user.so",
  "sha256": "3c5674a1e7af6b7d09e8c66f973a3138fed0dde4dfaee98fc132c89730cd9156"
}
{
  "path": "/usr/local/apache2/modules/mod_autoindex.so",
  "sha256": "2d992f31f40be2c0ec34a29981191c3bfb9e4448a2099f11a4876ba4d394dc2f"
}
{
  "path": "/usr/local/apache2/modules/mod_brotli.so",
  "sha256": "73bfe5aeff2040a7b56a0bf822bc4069ce3e9954186f81322060697f5cf0546f"
}
{
  "path": "/usr/local/apache2/modules/mod_bucketeer.so",
  "sha256": "9f146159e928405d2a007dba3690566a45e5793cde87871a30dbfd1dc9114db1"
}
{
  "path": "/usr/local/apache2/modules/mod_buffer.so",
  "sha256": "710bd1b238a7814963b2857eb92c891bafeff61d9e40f807d68ded700c8c37f2"
}
{
  "path": "/usr/local/apache2/modules/mod_cache.so",
  "sha256": "976222e2c7ddb317d8804383801b310be33c6b3542f6972edd12c38ddc527e38"
}
{
  "path": "/usr/local/apache2/modules/mod_cache_disk.so",
  "sha256": "c5359004a563b9b01bf0416cbe856bb50de642bf06649383ffcae26490dc69c8"
}
{
  "path": "/usr/local/apache2/modules/mod_cache_socache.so",
  "sha256": "94abdf3779a9f7d258b1720021e1e3f10c630e625f5aa13c683c3c811b8dac10"
}
{
  "path": "/usr/local/apache2/modules/mod_case_filter.so",
  "sha256": "79a0a336c1bacd06c0fc5ca14cfc97223c92f0f5b0c88ec95f7e163e8cdf917d"
}
{
  "path": "/usr/local/apache2/modules/mod_case_filter_in.so",
  "sha256": "aa5e1c9452e1be3789a8a867a98dab700e4a579c0ea1ff7180adf4e41b8495e3"
}
{
  "path": "/usr/local/apache2/modules/mod_cern_meta.so",
  "sha256": "1a6da74d768c01b1a96f5c0f0e74686d5b0f51c3d7f1149fa1124cdf10ba842a"
}
{
  "path": "/usr/local/apache2/modules/mod_cgi.so",
  "sha256": "f2716c663f4f7db8cd78f456e5bd098a62c1b8fde86253ed4617edfe9cdb93b2"
}
{
  "path": "/usr/local/apache2/modules/mod_cgid.so",
  "sha256": "d5a19aeeb7b9063bac25e4a172ea7578e83bb32da4fe21ecd858409115de166c"
}
{
  "path": "/usr/local/apache2/modules/mod_charset_lite.so",
  "sha256": "9c4a1b27532c5f47eea7cfc61f65a7cf2f132286e556175ec28e313024641c9d"
}
{
  "path": "/usr/local/apache2/modules/mod_data.so",
  "sha256": "4dcae9a704c7d9861497e57b15423b9ce3fc7dda6544096ecfff64e4223f3684"
}
{
  "path": "/usr/local/apache2/modules/mod_dav.so",
  "sha256": "1a33728b16ad05b12fbecf637168608cb10f258ef7a355bd37cef8ce2ed86fd7"
}
...

Binary file digests:

Useful for verifying binary integrity and detecting tampering

.files[] |
  select(.executable != null) |  # Filter for executable files
  {
    path: .location.path,
    digests: [.digests[] | {algorithm, value}]  # All available hash algorithms
  }
syft alpine:3.9.2 -o json | \
  jq '.files[] |
  select(.executable != null) |
  {
    path: .location.path,
    digests: [.digests[] | {algorithm, value}]
  }'
{
  "path": "/bin/busybox",
  "digests": [
    {
      "algorithm": "sha1",
      "value": "7423801dfb28659fcaaaa5e8d41051d470b19008"
    },
    {
      "algorithm": "sha256",
      "value": "2c1276c3c02ccec8a0e1737d3144cdf03db883f479c86fbd9c7ea4fd9b35eac5"
    }
  ]
}
{
  "path": "/lib/ld-musl-aarch64.so.1",
  "digests": [
    {
      "algorithm": "sha1",
      "value": "0b83c1eb91d633379e0c17349e7dae821fa36dbb"
    },
    {
      "algorithm": "sha256",
      "value": "0132814479f1acc1e264ef59f73fd91563235897e8dc1bd52765f974cde382ca"
    }
  ]
}
{
  "path": "/lib/libcrypto.so.1.1",
  "digests": [
    {
      "algorithm": "sha1",
      "value": "e9d1540e5bbd9e77b388ab0e6e2f52603eb032a4"
    },
    {
      "algorithm": "sha256",
      "value": "6c597c8ad195eeb7a9130ad832dfa4cbf140f42baf96304711b2dbd43ba8e617"
    }
  ]
}
{
  "path": "/lib/libssl.so.1.1",
  "digests": [
    {
      "algorithm": "sha1",
      "value": "a8d5036010b52a80402b900c626fe862ab06bd8b"
    },
    {
      "algorithm": "sha256",
      "value": "fb72f4615fb4574bd6eeabfdb86be47012618b9076d75aeb1510941c585cae64"
    }
  ]
}
{
  "path": "/lib/libz.so.1.2.11",
  "digests": [
    {
      "algorithm": "sha1",
      "value": "83378fc7a19ff908a7e92a9fd0ca39eee90d0a3c"
    },
    {
      "algorithm": "sha256",
      "value": "19e790eb36a09eba397b5af16852f3bea21a242026bbba3da7b16442b8ba305b"
    }
  ]
}
{
  "path": "/sbin/apk",
  "digests": [
    {
      "algorithm": "sha1",
      "value": "adac7738917adecff81d4a6f9f0c7971b173859a"
    },
    {
      "algorithm": "sha256",
      "value": "22d7d85bd24923f1f274ce765d16602191097829e22ac632748302817ce515d8"
    }
  ]
}
{
  "path": "/sbin/mkmntdirs",
  "digests": [
    {
      "algorithm": "sha1",
      "value": "fff9b110ad6c659a39681e7be3b2a036fbbcca7b"
    },
    {
      "algorithm": "sha256",
      "value": "a14a5a28525220224367616ef46d4713ef7bd00d22baa761e058e8bdd4c0af1b"
    }
  ]
}
{
  "path": "/usr/bin/getconf",
  "digests": [
    {
      "algorithm": "sha1",
      "value": "06ed40070e1c2ad6d4171095eff4a6bdf9c8489b"
    },
    {
      "algorithm": "sha256",
      "value": "82bcde66ead19bc3b9ff850f66c2dbf5eaff36d481f1ec154100f73f6265d2ef"
    }
  ]
}
{
  "path": "/usr/bin/getent",
  "digests": [
    {
      "algorithm": "sha1",
      "value": "c318a3a780fc27ed7dba57827a825191fa7ee8bd"
    },
    {
      "algorithm": "sha256",
      "value": "53ffb508150e91838d795831e8ecc71f2bc3a7db036c6d7f9512c3973418bb5e"
    }
  ]
}
{
  "path": "/usr/bin/iconv",
  "digests": [
    {
      "algorithm": "sha1",
      "value": "eb98f04742e41cfc3ed44109b0e059d13e5523ea"
    },
    {
      "algorithm": "sha256",
      "value": "1c99d1f4edcb8da6db1da60958051c413de45a4c15cd3b7f7285ed87f9a250ff"
    }
  ]
}
{
  "path": "/usr/bin/scanelf",
  "digests": [
    {
      "algorithm": "sha1",
      "value": "cb085d106f35862e44e17849026927bd05845bff"
    },
    {
      "algorithm": "sha256",
      "value": "908da485ad2edea35242f8989c7beb9536414782abc94357c72b7d840bb1fda2"
    }
  ]
}
{
  "path": "/usr/bin/ssl_client",
  "digests": [
    {
      "algorithm": "sha1",
      "value": "7e17cb64c3fce832e5fa52a3b2ed1e1ccd26acd0"
    },
    {
      "algorithm": "sha256",
      "value": "67ab7f3a1ba35630f439d1ca4f73c7d95f8b7aa0e6f6db6ea1743f136f074ab4"
    }
  ]
}
{
  "path": "/usr/lib/engines-1.1/afalg.so",
  "digests": [
    {
      "algorithm": "sha1",
      "value": "6bd2c385e3884109c581659a8b184592c86e7cee"
    },
    {
      "algorithm": "sha256",
      "value": "ea7c2f48bc741fd828d79a304dbf713e20e001c0187f3f534d959886af87f4af"
    }
  ]
}
{
  "path": "/usr/lib/engines-1.1/capi.so",
  "digests": [
    {
      "algorithm": "sha1",
      "value": "41bb990b6f8e2013487980fd430455cc3b59905f"
    },
    {
      "algorithm": "sha256",
      "value": "b461ed43f0f244007d872e84760a446023b69b178c970acf10ed2666198942c6"
    }
  ]
}
{
  "path": "/usr/lib/engines-1.1/padlock.so",
  "digests": [
    {
      "algorithm": "sha1",
      "value": "82d8308700f481884fd77c882e0e9406fb17b317"
    },
    {
      "algorithm": "sha256",
      "value": "0ccb04f040afb0216da1cea2c1db7a0b91d990ce061e232782aedbd498483649"
    }
  ]
}
{
  "path": "/usr/lib/libtls-standalone.so.1.0.0",
  "digests": [
    {
      "algorithm": "sha1",
...

Binaries with security features:

Analyzes ELF security hardening features extracted during SBOM generation

.files[] |
  select(.executable != null and .executable.format == "elf") |  # ELF binaries only
  {
    path: .location.path,
    pie: .executable.elfSecurityFeatures.pie,  # Position Independent Executable
    stackCanary: .executable.elfSecurityFeatures.stackCanary,  # Stack protection
    nx: .executable.elfSecurityFeatures.nx  # No-Execute bit
  }
syft alpine:3.9.2 -o json | \
  jq '.files[] |
  select(.executable != null and .executable.format == "elf") |
  {
    path: .location.path,
    pie: .executable.elfSecurityFeatures.pie,
    stackCanary: .executable.elfSecurityFeatures.stackCanary,
    nx: .executable.elfSecurityFeatures.nx
  }'
{
  "path": "/bin/busybox",
  "pie": true,
  "stackCanary": true,
  "nx": true
}
{
  "path": "/lib/ld-musl-aarch64.so.1",
  "pie": false,
  "stackCanary": true,
  "nx": true
}
{
  "path": "/lib/libcrypto.so.1.1",
  "pie": false,
  "stackCanary": true,
  "nx": true
}
{
  "path": "/lib/libssl.so.1.1",
  "pie": false,
  "stackCanary": true,
  "nx": true
}
{
  "path": "/lib/libz.so.1.2.11",
  "pie": false,
  "stackCanary": true,
  "nx": true
}
{
  "path": "/sbin/apk",
  "pie": true,
  "stackCanary": true,
  "nx": true
}
{
  "path": "/sbin/mkmntdirs",
  "pie": true,
  "stackCanary": false,
  "nx": true
}
{
  "path": "/usr/bin/getconf",
  "pie": true,
  "stackCanary": false,
  "nx": true
}
{
  "path": "/usr/bin/getent",
  "pie": true,
  "stackCanary": true,
  "nx": true
}
{
  "path": "/usr/bin/iconv",
  "pie": true,
  "stackCanary": true,
  "nx": true
}
{
  "path": "/usr/bin/scanelf",
  "pie": true,
  "stackCanary": true,
  "nx": true
}
{
  "path": "/usr/bin/ssl_client",
  "pie": true,
  "stackCanary": true,
  "nx": true
}
{
  "path": "/usr/lib/engines-1.1/afalg.so",
  "pie": false,
  "stackCanary": true,
  "nx": true
}
{
  "path": "/usr/lib/engines-1.1/capi.so",
  "pie": false,
  "stackCanary": false,
  "nx": true
}
{
  "path": "/usr/lib/engines-1.1/padlock.so",
  "pie": false,
  "stackCanary": false,
  "nx": true
}
{
  "path": "/usr/lib/libtls-standalone.so.1.0.0",
  "pie": false,
  "stackCanary": true,
  "nx": true
}

Binaries importing specific libraries:

Identifies which binaries depend on specific shared libraries for security audits

.files[] |
  select(.executable != null and .executable.importedLibraries != null) |
  select(.executable.importedLibraries[] | contains("libcrypto")) |  # Find binaries using libcrypto
  {
    path: .location.path,
    imports: .executable.importedLibraries  # Shared library dependencies
  }
syft alpine:3.9.2 -o json | \
  jq '.files[] |
  select(.executable != null and .executable.importedLibraries != null) |
  select(.executable.importedLibraries[] | contains("libcrypto")) |
  {
    path: .location.path,
    imports: .executable.importedLibraries
  }'
{
  "path": "/lib/libssl.so.1.1",
  "imports": [
    "libcrypto.so.1.1",
    "libc.musl-aarch64.so.1"
  ]
}
{
  "path": "/sbin/apk",
  "imports": [
    "libssl.so.1.1",
    "libcrypto.so.1.1",
    "libz.so.1",
    "libc.musl-aarch64.so.1"
  ]
}
{
  "path": "/usr/lib/engines-1.1/afalg.so",
  "imports": [
    "libcrypto.so.1.1",
    "libc.musl-aarch64.so.1"
  ]
}
{
  "path": "/usr/lib/libtls-standalone.so.1.0.0",
  "imports": [
    "libssl.so.1.1",
    "libcrypto.so.1.1",
    "libc.musl-aarch64.so.1"
  ]
}

Extract Package URLs (PURLs):

Extracts Package URLs for cross-tool SBOM correlation and vulnerability matching

.artifacts[] |
  select(.purl != null and .purl != "") |  # Filter packages with PURLs
  {
    name,
    version,
    purl  # Package URL for cross-tool compatibility
  }
syft alpine:3.9.2 -o json | \
  jq '.artifacts[] |
  select(.purl != null and .purl != "") |
  {
    name,
    version,
    purl
  }'
{
  "name": "alpine-baselayout",
  "version": "3.1.0-r3",
  "purl": "pkg:apk/alpine/alpine-baselayout@3.1.0-r3?arch=aarch64&distro=alpine-3.9.2"
}
{
  "name": "alpine-keys",
  "version": "2.1-r1",
  "purl": "pkg:apk/alpine/alpine-keys@2.1-r1?arch=aarch64&distro=alpine-3.9.2"
}
{
  "name": "apk-tools",
  "version": "2.10.3-r1",
  "purl": "pkg:apk/alpine/apk-tools@2.10.3-r1?arch=aarch64&distro=alpine-3.9.2"
}
{
  "name": "busybox",
  "version": "1.29.3-r10",
  "purl": "pkg:apk/alpine/busybox@1.29.3-r10?arch=aarch64&distro=alpine-3.9.2"
}
{
  "name": "ca-certificates-cacert",
  "version": "20190108-r0",
  "purl": "pkg:apk/alpine/ca-certificates-cacert@20190108-r0?arch=aarch64&distro=alpine-3.9.2&upstream=ca-certificates"
}
{
  "name": "libc-utils",
  "version": "0.7.1-r0",
  "purl": "pkg:apk/alpine/libc-utils@0.7.1-r0?arch=aarch64&distro=alpine-3.9.2&upstream=libc-dev"
}
{
  "name": "libcrypto1.1",
  "version": "1.1.1a-r1",
  "purl": "pkg:apk/alpine/libcrypto1.1@1.1.1a-r1?arch=aarch64&distro=alpine-3.9.2&upstream=openssl"
}
{
  "name": "libssl1.1",
  "version": "1.1.1a-r1",
  "purl": "pkg:apk/alpine/libssl1.1@1.1.1a-r1?arch=aarch64&distro=alpine-3.9.2&upstream=openssl"
}
{
  "name": "libtls-standalone",
  "version": "2.7.4-r6",
  "purl": "pkg:apk/alpine/libtls-standalone@2.7.4-r6?arch=aarch64&distro=alpine-3.9.2"
}
{
  "name": "musl",
  "version": "1.1.20-r3",
  "purl": "pkg:apk/alpine/musl@1.1.20-r3?arch=aarch64&distro=alpine-3.9.2"
}
{
  "name": "musl-utils",
  "version": "1.1.20-r3",
  "purl": "pkg:apk/alpine/musl-utils@1.1.20-r3?arch=aarch64&distro=alpine-3.9.2&upstream=musl"
}
{
  "name": "scanelf",
  "version": "1.2.3-r0",
  "purl": "pkg:apk/alpine/scanelf@1.2.3-r0?arch=aarch64&distro=alpine-3.9.2&upstream=pax-utils"
}
{
  "name": "ssl_client",
  "version": "1.29.3-r10",
  "purl": "pkg:apk/alpine/ssl_client@1.29.3-r10?arch=aarch64&distro=alpine-3.9.2&upstream=busybox"
}
{
  "name": "zlib",
  "version": "1.2.11-r1",
  "purl": "pkg:apk/alpine/zlib@1.2.11-r1?arch=aarch64&distro=alpine-3.9.2"
}

Group packages by language:

Groups and counts packages by programming language

[.artifacts[] | select(.language != null and .language != "")] |
  group_by(.language) |  # Group by programming language
  map({
    language: .[0].language,
    count: length  # Count packages per language
  }) |
  sort_by(.count) |
  reverse  # Highest count first
syft node:18-alpine -o json | \
  jq '[.artifacts[] | select(.language != null and .language != "")] |
  group_by(.language) |
  map({
    language: .[0].language,
    count: length
  }) |
  sort_by(.count) |
  reverse'
[
  {
    "language": "javascript",
    "count": 204
  }
]

Count packages by type:

Provides a summary count of packages per ecosystem

[.artifacts[]] |
  group_by(.type) |  # Group packages by ecosystem type
  map({
    type: .[0].type,
    count: length  # Count packages in each group
  }) |
  sort_by(.count) |
  reverse  # Highest count first
syft node:18-alpine -o json | \
  jq '[.artifacts[]] |
  group_by(.type) |
  map({
    type: .[0].type,
    count: length
  }) |
  sort_by(.count) |
  reverse'
[
  {
    "type": "npm",
    "count": 204
  },
  {
    "type": "apk",
    "count": 17
  },
  {
    "type": "binary",
    "count": 1
  }
]

Package locations:

Maps packages to their filesystem locations

.artifacts[] |
  {
    name,
    version,
    type,
    locations: [.locations[] | .path]  # All filesystem locations
  }
syft alpine:3.9.2 -o json | \
  jq '.artifacts[] |
  {
    name,
    version,
    type,
    locations: [.locations[] | .path]
  }'
{
  "name": "alpine-baselayout",
  "version": "3.1.0-r3",
  "type": "apk",
  "locations": [
    "/lib/apk/db/installed"
  ]
}
{
  "name": "alpine-keys",
  "version": "2.1-r1",
  "type": "apk",
  "locations": [
    "/lib/apk/db/installed"
  ]
}
{
  "name": "apk-tools",
  "version": "2.10.3-r1",
  "type": "apk",
  "locations": [
    "/lib/apk/db/installed"
  ]
}
{
  "name": "busybox",
  "version": "1.29.3-r10",
  "type": "apk",
  "locations": [
    "/lib/apk/db/installed"
  ]
}
{
  "name": "ca-certificates-cacert",
  "version": "20190108-r0",
  "type": "apk",
  "locations": [
    "/lib/apk/db/installed"
  ]
}
{
  "name": "libc-utils",
  "version": "0.7.1-r0",
  "type": "apk",
  "locations": [
    "/lib/apk/db/installed"
  ]
}
{
  "name": "libcrypto1.1",
  "version": "1.1.1a-r1",
  "type": "apk",
  "locations": [
    "/lib/apk/db/installed"
  ]
}
{
  "name": "libssl1.1",
  "version": "1.1.1a-r1",
  "type": "apk",
  "locations": [
    "/lib/apk/db/installed"
  ]
}
{
  "name": "libtls-standalone",
  "version": "2.7.4-r6",
  "type": "apk",
  "locations": [
    "/lib/apk/db/installed"
  ]
}
{
  "name": "musl",
  "version": "1.1.20-r3",
  "type": "apk",
  "locations": [
    "/lib/apk/db/installed"
  ]
}
{
  "name": "musl-utils",
  "version": "1.1.20-r3",
  "type": "apk",
  "locations": [
    "/lib/apk/db/installed"
  ]
}
{
  "name": "scanelf",
  "version": "1.2.3-r0",
  "type": "apk",
  "locations": [
    "/lib/apk/db/installed"
  ]
}
{
  "name": "ssl_client",
  "version": "1.29.3-r10",
  "type": "apk",
  "locations": [
    "/lib/apk/db/installed"
  ]
}
{
  "name": "zlib",
  "version": "1.2.11-r1",
  "type": "apk",
  "locations": [
    "/lib/apk/db/installed"
  ]
}

Files by MIME type:

Filters files by MIME type, useful for finding specific file types

.files[] |
  select(.metadata.mimeType == "application/x-sharedlib") |  # Filter by MIME type
  {
    path: .location.path,
    mimeType: .metadata.mimeType,
    size: .metadata.size  # File size in bytes
  }
syft alpine:3.9.2 -o json | \
  jq '.files[] |
  select(.metadata.mimeType == "application/x-sharedlib") |
  {
    path: .location.path,
    mimeType: .metadata.mimeType,
    size: .metadata.size
  }'
{
  "path": "/bin/busybox",
  "mimeType": "application/x-sharedlib",
  "size": 841320
}
{
  "path": "/lib/ld-musl-aarch64.so.1",
  "mimeType": "application/x-sharedlib",
  "size": 616960
}
{
  "path": "/lib/libcrypto.so.1.1",
  "mimeType": "application/x-sharedlib",
  "size": 2321984
}
{
  "path": "/lib/libssl.so.1.1",
  "mimeType": "application/x-sharedlib",
  "size": 515376
}
{
  "path": "/lib/libz.so.1.2.11",
  "mimeType": "application/x-sharedlib",
  "size": 91888
}
{
  "path": "/sbin/apk",
  "mimeType": "application/x-sharedlib",
  "size": 218928
}
{
  "path": "/sbin/mkmntdirs",
  "mimeType": "application/x-sharedlib",
  "size": 5712
}
{
  "path": "/usr/bin/getconf",
  "mimeType": "application/x-sharedlib",
  "size": 33544
}
{
  "path": "/usr/bin/getent",
  "mimeType": "application/x-sharedlib",
  "size": 48704
}
{
  "path": "/usr/bin/iconv",
  "mimeType": "application/x-sharedlib",
  "size": 21968
}
{
  "path": "/usr/bin/scanelf",
  "mimeType": "application/x-sharedlib",
  "size": 79592
}
{
  "path": "/usr/bin/ssl_client",
  "mimeType": "application/x-sharedlib",
  "size": 9808
}
{
  "path": "/usr/lib/engines-1.1/afalg.so",
  "mimeType": "application/x-sharedlib",
  "size": 18568
}
{
  "path": "/usr/lib/engines-1.1/capi.so",
  "mimeType": "application/x-sharedlib",
  "size": 5672
}
{
  "path": "/usr/lib/engines-1.1/padlock.so",
  "mimeType": "application/x-sharedlib",
  "size": 5672
}
{
  "path": "/usr/lib/libtls-standalone.so.1.0.0",
  "mimeType": "application/x-sharedlib",
  "size": 96032
}

Dependency relationships:

Traverses package dependency graph using relationships

. as $root |
  .artifactRelationships[] |
  select(.type == "dependency-of") |  # Filter for dependency relationships
  .parent as $parent |
  .child as $child |
  {
    parent: ($root.artifacts[] | select(.id == $parent).name),  # Parent package name
    child: ($root.artifacts[] | select(.id == $child).name)  # Dependency name
  }
syft node:18-alpine -o json | \
  jq '. as $root |
  .artifactRelationships[] |
  select(.type == "dependency-of") |
  .parent as $parent |
  .child as $child |
  {
    parent: ($root.artifacts[] | select(.id == $parent).name),
    child: ($root.artifacts[] | select(.id == $child).name)
  }'
{
  "parent": "ca-certificates-bundle",
  "child": "apk-tools"
}
{
  "parent": "alpine-keys",
  "child": "alpine-release"
}
{
  "parent": "alpine-baselayout-data",
  "child": "alpine-baselayout"
}
{
  "parent": "musl",
  "child": "ssl_client"
}
{
  "parent": "musl",
  "child": "libgcc"
}
{
  "parent": "musl",
  "child": "libstdc++"
}
{
  "parent": "musl",
  "child": "musl-utils"
}
{
  "parent": "musl",
  "child": "libssl3"
}
{
  "parent": "musl",
  "child": "busybox"
}
{
  "parent": "musl",
  "child": "apk-tools"
}
{
  "parent": "musl",
  "child": "scanelf"
}
{
  "parent": "musl",
  "child": "libcrypto3"
}
{
  "parent": "musl",
  "child": "zlib"
}
{
  "parent": "libgcc",
  "child": "libstdc++"
}
{
  "parent": "libssl3",
  "child": "ssl_client"
}
{
  "parent": "libssl3",
  "child": "apk-tools"
}
{
  "parent": "busybox",
  "child": "busybox-binsh"
}
{
  "parent": "scanelf",
  "child": "musl-utils"
}
{
  "parent": "busybox-binsh",
  "child": "alpine-baselayout"
}
{
  "parent": "libcrypto3",
  "child": "ssl_client"
}
{
  "parent": "libcrypto3",
  "child": "libssl3"
}
{
  "parent": "libcrypto3",
  "child": "apk-tools"
}
{
  "parent": "zlib",
  "child": "apk-tools"
}

Files without packages:

Finds orphaned files not associated with any package

. as $root |
  [.files[].id] as $allFiles |  # All file IDs
  [.artifactRelationships[] | select(.type == "contains") | .child] as $ownedFiles |  # Package-owned files
  ($allFiles - $ownedFiles) as $orphans |  # Set subtraction for unowned files
  $root.files[] |
  select(.id as $id | $orphans | index($id)) |  # Filter to orphaned files
  .location.path
syft alpine:3.9.2 -o json | \
  jq '. as $root |
  [.files[].id] as $allFiles |
  [.artifactRelationships[] | select(.type == "contains") | .child] as $ownedFiles |
  ($allFiles - $ownedFiles) as $orphans |
  $root.files[] |
  select(.id as $id | $orphans | index($id)) |
  .location.path'
"/lib/apk/db/installed"

Largest files:

Identifies the top 10 largest files by size

[.files[] |
  {
    path: .location.path,
    size: .metadata.size,
    mimeType: .metadata.mimeType
  }] |
  sort_by(.size) |
  reverse |  # Largest first
  .[0:10]  # Top 10 files
syft alpine:3.9.2 -o json | \
  jq '[.files[] |
  {
    path: .location.path,
    size: .metadata.size,
    mimeType: .metadata.mimeType
  }] |
  sort_by(.size) |
  reverse |
  .[0:10]'
[
  {
    "path": "/lib/libcrypto.so.1.1",
    "size": 2321984,
    "mimeType": "application/x-sharedlib"
  },
  {
    "path": "/bin/busybox",
    "size": 841320,
    "mimeType": "application/x-sharedlib"
  },
  {
    "path": "/lib/ld-musl-aarch64.so.1",
    "size": 616960,
    "mimeType": "application/x-sharedlib"
  },
  {
    "path": "/lib/libssl.so.1.1",
    "size": 515376,
    "mimeType": "application/x-sharedlib"
  },
  {
    "path": "/etc/ssl/cert.pem",
    "size": 232598,
    "mimeType": "text/plain"
  },
  {
    "path": "/sbin/apk",
    "size": 218928,
    "mimeType": "application/x-sharedlib"
  },
  {
    "path": "/usr/lib/libtls-standalone.so.1.0.0",
    "size": 96032,
    "mimeType": "application/x-sharedlib"
  },
  {
    "path": "/lib/libz.so.1.2.11",
    "size": 91888,
    "mimeType": "application/x-sharedlib"
  },
  {
    "path": "/usr/bin/scanelf",
    "size": 79592,
    "mimeType": "application/x-sharedlib"
  },
  {
    "path": "/usr/bin/getent",
    "size": 48704,
    "mimeType": "application/x-sharedlib"
  }
]

Extract CPEs:

Lists Common Platform Enumeration identifiers for vulnerability scanning

.artifacts[] |
  select(.cpes != null and (.cpes | length) > 0) |  # Filter packages with CPEs
  {
    name,
    version,
    cpes: [.cpes[].cpe]  # Extract CPE strings
  }
syft alpine:3.9.2 -o json | \
  jq '.artifacts[] |
  select(.cpes != null and (.cpes | length) > 0) |
  {
    name,
    version,
    cpes: [.cpes[].cpe]
  }'
{
  "name": "alpine-baselayout",
  "version": "3.1.0-r3",
  "cpes": [
    "cpe:2.3:a:alpine-baselayout:alpine-baselayout:3.1.0-r3:*:*:*:*:*:*:*",
    "cpe:2.3:a:alpine-baselayout:alpine_baselayout:3.1.0-r3:*:*:*:*:*:*:*",
    "cpe:2.3:a:alpine_baselayout:alpine-baselayout:3.1.0-r3:*:*:*:*:*:*:*",
    "cpe:2.3:a:alpine_baselayout:alpine_baselayout:3.1.0-r3:*:*:*:*:*:*:*",
    "cpe:2.3:a:alpine:alpine-baselayout:3.1.0-r3:*:*:*:*:*:*:*",
    "cpe:2.3:a:alpine:alpine_baselayout:3.1.0-r3:*:*:*:*:*:*:*"
  ]
}
{
  "name": "alpine-keys",
  "version": "2.1-r1",
  "cpes": [
    "cpe:2.3:a:alpine-keys:alpine-keys:2.1-r1:*:*:*:*:*:*:*",
    "cpe:2.3:a:alpine-keys:alpine_keys:2.1-r1:*:*:*:*:*:*:*",
    "cpe:2.3:a:alpine_keys:alpine-keys:2.1-r1:*:*:*:*:*:*:*",
    "cpe:2.3:a:alpine_keys:alpine_keys:2.1-r1:*:*:*:*:*:*:*",
    "cpe:2.3:a:alpine:alpine-keys:2.1-r1:*:*:*:*:*:*:*",
    "cpe:2.3:a:alpine:alpine_keys:2.1-r1:*:*:*:*:*:*:*"
  ]
}
{
  "name": "apk-tools",
  "version": "2.10.3-r1",
  "cpes": [
    "cpe:2.3:a:apk-tools:apk-tools:2.10.3-r1:*:*:*:*:*:*:*",
    "cpe:2.3:a:apk-tools:apk_tools:2.10.3-r1:*:*:*:*:*:*:*",
    "cpe:2.3:a:apk_tools:apk-tools:2.10.3-r1:*:*:*:*:*:*:*",
    "cpe:2.3:a:apk_tools:apk_tools:2.10.3-r1:*:*:*:*:*:*:*",
    "cpe:2.3:a:apk:apk-tools:2.10.3-r1:*:*:*:*:*:*:*",
    "cpe:2.3:a:apk:apk_tools:2.10.3-r1:*:*:*:*:*:*:*"
  ]
}
{
  "name": "busybox",
  "version": "1.29.3-r10",
  "cpes": [
    "cpe:2.3:a:busybox:busybox:1.29.3-r10:*:*:*:*:*:*:*"
  ]
}
{
  "name": "ca-certificates-cacert",
  "version": "20190108-r0",
  "cpes": [
    "cpe:2.3:a:ca-certificates-cacert:ca-certificates-cacert:20190108-r0:*:*:*:*:*:*:*",
    "cpe:2.3:a:ca-certificates-cacert:ca_certificates_cacert:20190108-r0:*:*:*:*:*:*:*",
    "cpe:2.3:a:ca_certificates_cacert:ca-certificates-cacert:20190108-r0:*:*:*:*:*:*:*",
    "cpe:2.3:a:ca_certificates_cacert:ca_certificates_cacert:20190108-r0:*:*:*:*:*:*:*",
    "cpe:2.3:a:ca-certificates:ca-certificates-cacert:20190108-r0:*:*:*:*:*:*:*",
    "cpe:2.3:a:ca-certificates:ca_certificates_cacert:20190108-r0:*:*:*:*:*:*:*",
    "cpe:2.3:a:ca_certificates:ca-certificates-cacert:20190108-r0:*:*:*:*:*:*:*",
    "cpe:2.3:a:ca_certificates:ca_certificates_cacert:20190108-r0:*:*:*:*:*:*:*",
    "cpe:2.3:a:mozilla:ca-certificates-cacert:20190108-r0:*:*:*:*:*:*:*",
    "cpe:2.3:a:mozilla:ca_certificates_cacert:20190108-r0:*:*:*:*:*:*:*",
    "cpe:2.3:a:ca:ca-certificates-cacert:20190108-r0:*:*:*:*:*:*:*",
    "cpe:2.3:a:ca:ca_certificates_cacert:20190108-r0:*:*:*:*:*:*:*"
  ]
}
{
  "name": "libc-utils",
  "version": "0.7.1-r0",
  "cpes": [
    "cpe:2.3:a:libc-utils:libc-utils:0.7.1-r0:*:*:*:*:*:*:*",
    "cpe:2.3:a:libc-utils:libc_utils:0.7.1-r0:*:*:*:*:*:*:*",
    "cpe:2.3:a:libc_utils:libc-utils:0.7.1-r0:*:*:*:*:*:*:*",
    "cpe:2.3:a:libc_utils:libc_utils:0.7.1-r0:*:*:*:*:*:*:*",
    "cpe:2.3:a:libc:libc-utils:0.7.1-r0:*:*:*:*:*:*:*",
    "cpe:2.3:a:libc:libc_utils:0.7.1-r0:*:*:*:*:*:*:*"
  ]
}
{
  "name": "libcrypto1.1",
  "version": "1.1.1a-r1",
  "cpes": [
    "cpe:2.3:a:libcrypto1.1:libcrypto1.1:1.1.1a-r1:*:*:*:*:*:*:*",
    "cpe:2.3:a:libcrypto1.1:libcrypto:1.1.1a-r1:*:*:*:*:*:*:*",
    "cpe:2.3:a:libcrypto:libcrypto1.1:1.1.1a-r1:*:*:*:*:*:*:*",
    "cpe:2.3:a:libcrypto:libcrypto:1.1.1a-r1:*:*:*:*:*:*:*"
  ]
}
{
  "name": "libssl1.1",
  "version": "1.1.1a-r1",
  "cpes": [
    "cpe:2.3:a:libssl1.1:libssl1.1:1.1.1a-r1:*:*:*:*:*:*:*",
    "cpe:2.3:a:libssl1.1:libssl:1.1.1a-r1:*:*:*:*:*:*:*",
    "cpe:2.3:a:libssl:libssl1.1:1.1.1a-r1:*:*:*:*:*:*:*",
    "cpe:2.3:a:libssl:libssl:1.1.1a-r1:*:*:*:*:*:*:*"
  ]
}
{
  "name": "libtls-standalone",
  "version": "2.7.4-r6",
  "cpes": [
    "cpe:2.3:a:libtls-standalone:libtls-standalone:2.7.4-r6:*:*:*:*:*:*:*",
    "cpe:2.3:a:libtls-standalone:libtls_standalone:2.7.4-r6:*:*:*:*:*:*:*",
    "cpe:2.3:a:libtls_standalone:libtls-standalone:2.7.4-r6:*:*:*:*:*:*:*",
    "cpe:2.3:a:libtls_standalone:libtls_standalone:2.7.4-r6:*:*:*:*:*:*:*",
    "cpe:2.3:a:libtls:libtls-standalone:2.7.4-r6:*:*:*:*:*:*:*",
    "cpe:2.3:a:libtls:libtls_standalone:2.7.4-r6:*:*:*:*:*:*:*"
  ]
}
{
  "name": "musl",
  "version": "1.1.20-r3",
  "cpes": [
    "cpe:2.3:a:musl-libc:musl:1.1.20-r3:*:*:*:*:*:*:*",
    "cpe:2.3:a:musl_libc:musl:1.1.20-r3:*:*:*:*:*:*:*",
    "cpe:2.3:a:musl:musl:1.1.20-r3:*:*:*:*:*:*:*"
  ]
}
{
  "name": "musl-utils",
  "version": "1.1.20-r3",
  "cpes": [
    "cpe:2.3:a:musl-utils:musl-utils:1.1.20-r3:*:*:*:*:*:*:*",
    "cpe:2.3:a:musl-utils:musl_utils:1.1.20-r3:*:*:*:*:*:*:*",
    "cpe:2.3:a:musl_utils:musl-utils:1.1.20-r3:*:*:*:*:*:*:*",
    "cpe:2.3:a:musl_utils:musl_utils:1.1.20-r3:*:*:*:*:*:*:*",
    "cpe:2.3:a:musl:musl-utils:1.1.20-r3:*:*:*:*:*:*:*",
    "cpe:2.3:a:musl:musl_utils:1.1.20-r3:*:*:*:*:*:*:*"
  ]
}
{
  "name": "scanelf",
  "version": "1.2.3-r0",
  "cpes": [
    "cpe:2.3:a:scanelf:scanelf:1.2.3-r0:*:*:*:*:*:*:*"
  ]
}
{
  "name": "ssl_client",
  "version": "1.29.3-r10",
  "cpes": [
    "cpe:2.3:a:ssl-client:ssl-client:1.29.3-r10:*:*:*:*:*:*:*",
    "cpe:2.3:a:ssl-client:ssl_client:1.29.3-r10:*:*:*:*:*:*:*",
    "cpe:2.3:a:ssl_client:ssl-client:1.29.3-r10:*:*:*:*:*:*:*",
    "cpe:2.3:a:ssl_client:ssl_client:1.29.3-r10:*:*:*:*:*:*:*",
    "cpe:2.3:a:ssl:ssl-client:1.29.3-r10:*:*:*:*:*:*:*",
    "cpe:2.3:a:ssl:ssl_client:1.29.3-r10:*:*:*:*:*:*:*"
  ]
}
{
  "name": "zlib",
  "version": "1.2.11-r1",
  "cpes": [
    "cpe:2.3:a:zlib:zlib:1.2.11-r1:*:*:*:*:*:*:*"
  ]
}

Packages without licenses:

Identifies packages missing license information for compliance audits

.artifacts[] |
  select(.licenses == null or (.licenses | length) == 0) |  # Packages without license info
  {
    name,
    version,
    type,
    locations: [.locations[].path]  # Where package is installed
  }
syft httpd:2.4.65 -o json | \
  jq '.artifacts[] |
  select(.licenses == null or (.licenses | length) == 0) |
  {
    name,
    version,
    type,
    locations: [.locations[].path]
  }'
{
  "name": "httpd",
  "version": "2.4.65",
  "type": "binary",
  "locations": ["/usr/local/apache2/bin/httpd"]
}

Packages with CPE identifiers:

Lists packages with CPE identifiers indicating potential CVE matches

.artifacts[] |
  select(.cpes != null and (.cpes | length) > 0) |  # Packages with CPE identifiers
  {
    name,
    version,
    type,
    cpeCount: (.cpes | length)  # Number of CPE matches
  }
syft alpine:3.9.2 -o json | \
  jq '.artifacts[] |
  select(.cpes != null and (.cpes | length) > 0) |
  {
    name,
    version,
    type,
    cpeCount: (.cpes | length)
  }'
{
  "name": "alpine-baselayout",
  "version": "3.1.0-r3",
  "type": "apk",
  "cpeCount": 6
}
{
  "name": "alpine-keys",
  "version": "2.1-r1",
  "type": "apk",
  "cpeCount": 6
}
{
  "name": "apk-tools",
  "version": "2.10.3-r1",
  "type": "apk",
  "cpeCount": 6
}
{
  "name": "busybox",
  "version": "1.29.3-r10",
  "type": "apk",
  "cpeCount": 1
}
{
  "name": "ca-certificates-cacert",
  "version": "20190108-r0",
  "type": "apk",
  "cpeCount": 12
}
{
  "name": "libc-utils",
  "version": "0.7.1-r0",
  "type": "apk",
  "cpeCount": 6
}
{
  "name": "libcrypto1.1",
  "version": "1.1.1a-r1",
  "type": "apk",
  "cpeCount": 4
}
{
  "name": "libssl1.1",
  "version": "1.1.1a-r1",
  "type": "apk",
  "cpeCount": 4
}
{
  "name": "libtls-standalone",
  "version": "2.7.4-r6",
  "type": "apk",
  "cpeCount": 6
}
{
  "name": "musl",
  "version": "1.1.20-r3",
  "type": "apk",
  "cpeCount": 3
}
{
  "name": "musl-utils",
  "version": "1.1.20-r3",
  "type": "apk",
  "cpeCount": 6
}
{
  "name": "scanelf",
  "version": "1.2.3-r0",
  "type": "apk",
  "cpeCount": 1
}
{
  "name": "ssl_client",
  "version": "1.29.3-r10",
  "type": "apk",
  "cpeCount": 6
}
{
  "name": "zlib",
  "version": "1.2.11-r1",
  "type": "apk",
  "cpeCount": 1
}

Next steps

5 - Package Catalogers

Configure which package catalogers Syft uses to discover software components including language-specific and file-based catalogers.

Catalogers are Syft’s detection modules that identify software packages in your projects. Each cataloger specializes in finding specific types of packages—for example, python-package-cataloger finds Python dependencies declared in requirements.txt, while python-installed-package-cataloger finds Python packages that have already been installed.

Syft includes dozens of catalogers covering languages like Python, Java, Go, JavaScript, Ruby, Rust, and more, as well as OS packages (APK, RPM, DEB) and binary formats.

Default Behavior

Syft uses different cataloger sets depending on what you’re scanning:

Scan Type Default Catalogers What They Find Example
Container Image Image-specific catalogers Installed packages only Python packages in site-packages
Directory Directory-specific catalogers Installed packages + declared dependencies Python packages in site-packages AND requirements.txt

This behavior ensures accurate results across different contexts. When you scan an image, Syft assumes installation steps have completed –this way you are getting results for software that is positively present. When you scan a directory (like a source code repository), Syft looks for both what’s installed and what’s declared as a dependency –this way you are getting results for not only what’s installed but also what you intend to install.

Why use different catalogers for different sources?

Most of the time, files that hint at the intent to install software do not have enough information in them to determine the exact version of the package that would be installed. For example, a requirements.txt file might specify a package without a version, or with a version range. By looking at installed packages in an image, after any build tooling has been invoked, Syft can provide more accurate version information.

Example: Python Package Detection

Scanning an image:

$ syft <container-image> --select-catalogers python
# Uses: python-installed-package-cataloger
# Finds: Packages in site-packages directories

Scanning a directory:

$ syft <source-directory> --select-catalogers python
# Uses: python-installed-package-cataloger, python-package-cataloger
# Finds: Packages in site-packages + requirements.txt, setup.py, Pipfile, etc.

Viewing Active Catalogers

The most reliable way to see which catalogers Syft used is to check the SBOM itself. Every SBOM captures both the catalogers that were requested and those that actually ran:

syft busybox:latest -o json | jq '.descriptor.configuration.catalogers'

Output:

{
  "requested": {
    "default": [
      "image",
      "file"
    ]
  },
  "used": [
    "alpm-db-cataloger",
    "apk-db-cataloger",
    "binary-classifier-cataloger",
    "bitnami-cataloger",
    "cargo-auditable-binary-cataloger",
    "conan-info-cataloger",
    "dotnet-deps-binary-cataloger",
    "dotnet-packages-lock-cataloger",
    "dpkg-db-cataloger",
    "elf-binary-package-cataloger",
    ...
  ]
}

This shows what catalogers were attempted, not just what found packages. The requested field shows your cataloger selection strategy, while used lists every cataloger that ran.

You can also see cataloger activity in real-time using verbose logging, though this is less comprehensive and not as direct.

Exploring Available Catalogers

Use the syft cataloger list command to see all available catalogers, their tags, and test selection expressions.

List all catalogers

syft cataloger list

Output shows file and package catalogers with their tags:

┌───────────────────────────┬───────────────────────┐
│ FILE CATALOGER            │ TAGS                  │
├───────────────────────────┼───────────────────────┤
│ file-content-cataloger    │ content, file         │
│ file-digest-cataloger     │ digest, file          │
│ file-executable-cataloger │ binary-metadata, file │
│ file-metadata-cataloger   │ file, file-metadata   │
└───────────────────────────┴───────────────────────┘
┌────────────────────────────────────┬────────────────────────────────────────────────────────┐
│ PACKAGE CATALOGER                  │ TAGS                                                   │
├────────────────────────────────────┼────────────────────────────────────────────────────────┤
│ python-installed-package-cataloger │ directory, image, installed, language, package, python │
│ python-package-cataloger           │ declared, directory, language, package, python         │
│ java-archive-cataloger             │ directory, image, installed, java, language, maven     │
│ go-module-binary-cataloger         │ binary, directory, go, golang, image, installed        │
│ ...                                │                                                        │
└────────────────────────────────────┴────────────────────────────────────────────────────────┘

Test cataloger selection

Preview which catalogers a selection expression would use:

$ syft cataloger list --select-catalogers python
Default selections: 1
'all'
Selection expressions: 1
'python' (intersect)

┌────────────────────────────────────┬────────────────────────────────────────────────────────┐
│ PACKAGE CATALOGER                  │ TAGS                                                   │
├────────────────────────────────────┼────────────────────────────────────────────────────────┤
│ python-installed-package-cataloger │ directory, image, installed, language, package, python │
│ python-package-cataloger           │ declared, directory, language, package, python         │
└────────────────────────────────────┴────────────────────────────────────────────────────────┘

This shows exactly which catalogers your selection expression will use, helping you verify your configuration before running a scan.

Output formats

Get cataloger information in different formats:

# Table format (default)
$ syft cataloger list

# JSON format (useful for automation)
$ syft cataloger list -o json

Cataloger References

You can refer to catalogers in two ways:

  • By name: The exact cataloger identifier (e.g., java-pom-cataloger, go-module-binary-cataloger)
  • By tag: A group label for related catalogers (e.g., java, python, image, directory)

Common tags include:

  • Language tags: python, java, go, javascript, ruby, rust, etc.
  • Scan type tags: image, directory
  • Installation state tags: installed, declared
  • Ecosystem tags: maven, npm, cargo, composer, etc.

Customizing Cataloger Selection

Syft provides two flags for controlling catalogers:

--select-catalogers: Modify Defaults

Use this flag to adjust the default cataloger set. This is the recommended approach for most use cases.

Syntax:

Operation Syntax Example Description
Filter <tag> --select-catalogers java Use only Java catalogers from the defaults
Add +<name> --select-catalogers +sbom-cataloger Add a specific cataloger to defaults
Remove -<name-or-tag> --select-catalogers -rpm Remove catalogers by name or tag
Combine <tag>,+<name>,-<tag> --select-catalogers java,+sbom-cataloger,-maven Multiple operations together

Selection Logic:

  1. Start with default catalogers (image or directory based)
  2. If tags provided (without + or -), filter to only those tagged catalogers
  3. Remove any catalogers matching -<name-or-tag>
  4. Add any catalogers specified with +<name>

--override-default-catalogers: Replace Defaults

Use this flag to completely replace Syft’s default cataloger selection. This bypasses the automatic image vs. directory behavior.

Syntax:

--override-default-catalogers <comma-separated-names-or-tags>

When to use:

  • You need catalogers from both image and directory sets
  • You want to use catalogers that aren’t in the default set
  • You need precise control regardless of scan type

Examples by Use Case

Filtering to Specific Languages

Scan for only Python packages using defaults for your scan type:

syft <target> --select-catalogers python

Scan for only Java and Go packages:

syft <target> --select-catalogers java,go

Adding Catalogers

Use defaults and also include the SBOM cataloger (which finds embedded SBOMs):

syft <target> --select-catalogers +sbom-cataloger

Scan with defaults plus both SBOM and binary catalogers:

syft <target> --select-catalogers +sbom-cataloger,+binary-cataloger

Removing Catalogers

Use defaults but exclude all RPM-related catalogers:

syft <target> --select-catalogers -rpm

Scan with defaults but remove Java JAR cataloger specifically:

syft <target> --select-catalogers -java-archive-cataloger

Combining Operations

Scan for Go packages, always include SBOM cataloger, but exclude binary analysis:

$ syft <container-image> --select-catalogers go,+sbom-cataloger,-binary
# Result: go-module-binary-cataloger, sbom-cataloger
# (binary cataloger excluded even though it's in go tag)

Filter to Java, add POM cataloger, remove Gradle:

syft <directory> --select-catalogers java,+java-pom-cataloger,-gradle

Complete Override Examples

Use only binary analysis catalogers regardless of scan type:

$ syft <target> --override-default-catalogers binary
# Result: binary-cataloger, cargo-auditable-binary-cataloger,
#         dotnet-portable-executable-cataloger, go-module-binary-cataloger

Use exactly two specific catalogers:

syft <target> --override-default-catalogers go-module-binary-cataloger,go-module-file-cataloger

Use all directory catalogers even when scanning an image:

syft <container-image> --override-default-catalogers directory

Troubleshooting

My language isn’t being detected

Check which catalogers ran and whether they found packages:

# See which catalogers were used
$ syft <target> -o json | jq '.descriptor.configuration.catalogers.used'

# See which catalogers found packages
$ syft <target> -o json | jq '.artifacts[].foundBy'

# See packages found by a specific cataloger
$ syft <target> -o json | jq '.artifacts[] | select(.foundBy == "python-package-cataloger") | .name'

If your expected cataloger isn’t in the used list:

  1. Verify the cataloger exists for your scan type: Use syft cataloger list --select-catalogers <tag> to preview
  2. Check your selection expressions: You may have excluded it with - or not included it in your filter
  3. Check file locations: Some catalogers look for specific paths (e.g., site-packages for Python)

If the cataloger ran but found nothing, check that:

  • Package files exist in the scanned source
  • Files are properly formatted
  • Files are in the expected locations for that cataloger

How do I know if I’m using image or directory defaults?

Check the SBOM’s cataloger configuration:

syft <target> -o json | jq '.descriptor.configuration.catalogers.requested'

This shows the selection strategy used:

  • "default": ["image", "file"] indicates image defaults
  • "default": ["directory", "file"] indicates directory defaults

What’s the difference between a name and a tag?

  • Name: The unique identifier for a single cataloger (e.g., python-package-cataloger)
  • Tag: A label that groups multiple catalogers (e.g., python includes both python-package-cataloger and python-installed-package-cataloger)

Use tags when you want to downselect from the default catalogers, and names when you need to target a specific cataloger.

Why use –select-catalogers vs –override-default-catalogers?

  • --select-catalogers: Respects Syft’s automatic image/directory behavior, safer for most use cases
  • --override-default-catalogers: Ignores scan type, gives complete control, requires more knowledge

When in doubt, use --select-catalogers.

Technical Reference

For reference, here’s the formal logic Syft uses for cataloger selection:

image_catalogers = all_catalogers AND catalogers_tagged("image")

directory_catalogers = all_catalogers AND catalogers_tagged("directory")

default_catalogers = image_catalogers OR directory_catalogers

sub_selected_catalogers = default_catalogers INTERSECT catalogers_tagged(TAG) [ UNION sub_selected_catalogers ... ]

base_catalogers = default_catalogers OR sub_selected_catalogers

final_set = (base_catalogers SUBTRACT removed_catalogers) UNION added_catalogers

This logic applies when using --select-catalogers. The --override-default-catalogers flag bypasses the default cataloger selection entirely and starts with the specified catalogers instead.

6 - File Selection

Control which files and directories Syft includes or excludes when generating SBOMs.

By default, Syft catalogs file details and digests for files owned by discovered packages. You can change this behavior using the SYFT_FILE_METADATA_SELECTION environment variable or the file.metadata.selection configuration option.

Available options:

  • all: capture all files from the search space
  • owned-by-package: capture only files owned by packages (default)
  • none: disable file information capture

Excluding file paths

You can exclude specific files and paths from scanning using glob patterns with the --exclude parameter. Use multiple --exclude flags to specify multiple patterns.

# Exclude a specific directory
syft <source> --exclude /etc

# Exclude files by pattern
syft <source> --exclude './out/**/*.json'

# Combine multiple exclusions
syft <source> --exclude './out/**/*.json' --exclude /etc --exclude '**/*.log'

Exclusion behavior by source type

How Syft interprets exclusion patterns depends on whether you’re scanning an image or a directory.

Image scanning

When scanning container images, Syft scans the entire filesystem. Use absolute paths for exclusions:

# Exclude system directories
syft alpine:latest --exclude /etc --exclude /var

# Exclude files by pattern across entire filesystem
syft alpine:latest --exclude '/usr/**/*.txt'

Directory scanning

When scanning directories, Syft resolves exclusion patterns relative to the specified directory. All exclusion patterns must begin with ./, */, or **/.

# Scanning /usr/foo
syft /usr/foo --exclude ./package.json        # Excludes /usr/foo/package.json
syft /usr/foo --exclude '**/package.json'     # Excludes all package.json files under /usr/foo
syft /usr/foo --exclude './out/**'            # Excludes everything under /usr/foo/out

Path prefix requirements for directory scans:

Pattern Meaning Example
./ Relative to scan directory root ./config.json
*/ One level of directories */temp
**/ Any depth of directories **/node_modules

Common exclusion patterns

# Exclude all JSON files
syft <source> --exclude '**/*.json'

# Exclude build output directories
syft <source> --exclude '**/dist/**' --exclude '**/build/**'

# Exclude dependency directories
syft <source> --exclude '**/node_modules/**' --exclude '**/vendor/**'

# Exclude test files
syft <source> --exclude '**/*_test.go' --exclude '**/test/**'

7 - Using Templates

Create custom SBOM output formats using Go templates with available data fields to build tailored reports for specific tooling or compliance requirements.

Syft lets you define custom output formats using Go templates. This is useful for generating custom reports, integrating with specific tools, or extracting only the data you need.

How to use templates

Set the output format to template and specify the template file path:

syft <image> -o template -t ./path/to/custom.tmpl

You can also configure the template path in your configuration file:

#.syft.yaml
format:
  template:
    path: "/path/to/template.tmpl"

Available fields

Templates receive the same data structure as the syft-json output format. The Syft JSON schema is the source of truth for all available fields and their structure.

To see what data is available:

# View the full JSON structure
syft <image> -o json

# Explore specific fields
syft <image> -o json | jq '.artifacts[0]'

Key fields commonly used in templates:

  • .artifacts - Array of discovered packages
  • .files - Array of discovered files
  • .source - Information about what was scanned
  • .distro - Detected Linux distribution (if applicable)
  • .descriptor - Syft version and configuration

Common package (artifact) fields:

  • .name, .version, .type - Basic package info
  • .licenses - License information (array)
  • .purl - Package URL
  • .cpes - Common Platform Enumerations
  • .locations - Where the package was found

Template functions

Syft templates support:

Function Arguments Description
getLastIndex collection Returns the last index of a slice (length - 1), useful for comma-separated lists
hasField obj, field Checks if a field exists on an object, returns boolean

Examples

The following examples show template source code and the rendered output when run against alpine:3.9.2:

CSV output

"Package","Version","Type","Found by"
{{- range .artifacts}}
"{{.name}}","{{.version}}","{{.type}}","{{.foundBy}}"
{{- end}}
"Package","Version","Type","Found by"
"alpine-baselayout","3.1.0-r3","apk","apk-db-cataloger"
"alpine-keys","2.1-r1","apk","apk-db-cataloger"
"apk-tools","2.10.3-r1","apk","apk-db-cataloger"
"busybox","1.29.3-r10","apk","apk-db-cataloger"
"ca-certificates-cacert","20190108-r0","apk","apk-db-cataloger"
"libc-utils","0.7.1-r0","apk","apk-db-cataloger"
"libcrypto1.1","1.1.1a-r1","apk","apk-db-cataloger"
"libssl1.1","1.1.1a-r1","apk","apk-db-cataloger"
"libtls-standalone","2.7.4-r6","apk","apk-db-cataloger"
"musl","1.1.20-r3","apk","apk-db-cataloger"
"musl-utils","1.1.20-r3","apk","apk-db-cataloger"
"scanelf","1.2.3-r0","apk","apk-db-cataloger"
"ssl_client","1.29.3-r10","apk","apk-db-cataloger"
"zlib","1.2.11-r1","apk","apk-db-cataloger"

Filter by package type

{{range .artifacts}}
{{- if eq .type "apk"}}
{{.name}}@{{.version}}{{end}}
{{- end}}
alpine-baselayout@3.1.0-r3
alpine-keys@2.1-r1
apk-tools@2.10.3-r1
busybox@1.29.3-r10
ca-certificates-cacert@20190108-r0
libc-utils@0.7.1-r0
libcrypto1.1@1.1.1a-r1
libssl1.1@1.1.1a-r1
libtls-standalone@2.7.4-r6
musl@1.1.20-r3
musl-utils@1.1.20-r3
scanelf@1.2.3-r0
ssl_client@1.29.3-r10
zlib@1.2.11-r1

Markdown report

# SBOM Report: {{.source.metadata.userInput}}

Scanned: {{.source.name}}:{{.source.version}} ({{.source.type}})
{{- if .distro}}
Distribution: {{.distro.prettyName}}
{{- end}}

## Packages ({{len .artifacts}})

| Package | Version | Type |
|---------|---------|------|
{{- range .artifacts}}
| {{.name}} | {{.version}} | {{.type}} |
{{- end}}
# SBOM Report: alpine:3.9.2

Scanned: alpine:3.9.2 (image)
Distribution: Alpine Linux v3.9

## Packages (14)

| Package                | Version     | Type |
| ---------------------- | ----------- | ---- |
| alpine-baselayout      | 3.1.0-r3    | apk  |
| alpine-keys            | 2.1-r1      | apk  |
| apk-tools              | 2.10.3-r1   | apk  |
| busybox                | 1.29.3-r10  | apk  |
| ca-certificates-cacert | 20190108-r0 | apk  |
| libc-utils             | 0.7.1-r0    | apk  |
| libcrypto1.1           | 1.1.1a-r1   | apk  |
| libssl1.1              | 1.1.1a-r1   | apk  |
| libtls-standalone      | 2.7.4-r6    | apk  |
| musl                   | 1.1.20-r3   | apk  |
| musl-utils             | 1.1.20-r3   | apk  |
| scanelf                | 1.2.3-r0    | apk  |
| ssl_client             | 1.29.3-r10  | apk  |
| zlib                   | 1.2.11-r1   | apk  |

License compliance

{{range .artifacts}}
{{- if .licenses}}
{{.name}}: {{range .licenses}}{{.value}} {{end}}{{end}}
{{- end}}
alpine-baselayout: GPL-2.0
alpine-keys: MIT
apk-tools: GPL2
busybox: GPL-2.0
ca-certificates-cacert: GPL-2.0-or-later MPL-2.0
libc-utils: BSD
libcrypto1.1: OpenSSL
libssl1.1: OpenSSL
libtls-standalone: ISC
musl: MIT
musl-utils: BSD GPL2+ MIT
scanelf: GPL-2.0
ssl_client: GPL-2.0
zlib: zlib

Custom JSON subset

{
  "scanned": "{{.source.metadata.userInput}}",
  "packages": [
    {{- $last := sub (len .artifacts) 1}}
    {{- range $i, $pkg := .artifacts}}
    {"name": "{{$pkg.name}}", "version": "{{$pkg.version}}"}{{if ne $i $last}},{{end}}
    {{- end}}
  ]
}
{
  "scanned": "alpine:3.9.2",
  "packages": [
    { "name": "alpine-baselayout", "version": "3.1.0-r3" },
    { "name": "alpine-keys", "version": "2.1-r1" },
    { "name": "apk-tools", "version": "2.10.3-r1" },
    { "name": "busybox", "version": "1.29.3-r10" },
    { "name": "ca-certificates-cacert", "version": "20190108-r0" },
    { "name": "libc-utils", "version": "0.7.1-r0" },
    { "name": "libcrypto1.1", "version": "1.1.1a-r1" },
    { "name": "libssl1.1", "version": "1.1.1a-r1" },
    { "name": "libtls-standalone", "version": "2.7.4-r6" },
    { "name": "musl", "version": "1.1.20-r3" },
    { "name": "musl-utils", "version": "1.1.20-r3" },
    { "name": "scanelf", "version": "1.2.3-r0" },
    { "name": "ssl_client", "version": "1.29.3-r10" },
    { "name": "zlib", "version": "1.2.11-r1" }
  ]
}

Executable file digests

{{range .files -}}
{{- if .executable}}
{{.location.path}}: {{range .digests}}{{if eq .algorithm "sha256"}}{{.value}}{{end}}{{end}}
{{end}}
{{- end}}
/bin/busybox: 2c1276c3c02ccec8a0e1737d3144cdf03db883f479c86fbd9c7ea4fd9b35eac5

/lib/ld-musl-aarch64.so.1: 0132814479f1acc1e264ef59f73fd91563235897e8dc1bd52765f974cde382ca

/lib/libcrypto.so.1.1: 6c597c8ad195eeb7a9130ad832dfa4cbf140f42baf96304711b2dbd43ba8e617

/lib/libssl.so.1.1: fb72f4615fb4574bd6eeabfdb86be47012618b9076d75aeb1510941c585cae64

/lib/libz.so.1.2.11: 19e790eb36a09eba397b5af16852f3bea21a242026bbba3da7b16442b8ba305b

/sbin/apk: 22d7d85bd24923f1f274ce765d16602191097829e22ac632748302817ce515d8

/sbin/mkmntdirs: a14a5a28525220224367616ef46d4713ef7bd00d22baa761e058e8bdd4c0af1b

/usr/bin/getconf: 82bcde66ead19bc3b9ff850f66c2dbf5eaff36d481f1ec154100f73f6265d2ef

/usr/bin/getent: 53ffb508150e91838d795831e8ecc71f2bc3a7db036c6d7f9512c3973418bb5e

/usr/bin/iconv: 1c99d1f4edcb8da6db1da60958051c413de45a4c15cd3b7f7285ed87f9a250ff

/usr/bin/scanelf: 908da485ad2edea35242f8989c7beb9536414782abc94357c72b7d840bb1fda2

/usr/bin/ssl_client: 67ab7f3a1ba35630f439d1ca4f73c7d95f8b7aa0e6f6db6ea1743f136f074ab4

/usr/lib/engines-1.1/afalg.so: ea7c2f48bc741fd828d79a304dbf713e20e001c0187f3f534d959886af87f4af

/usr/lib/engines-1.1/capi.so: b461ed43f0f244007d872e84760a446023b69b178c970acf10ed2666198942c6

/usr/lib/engines-1.1/padlock.so: 0ccb04f040afb0216da1cea2c1db7a0b91d990ce061e232782aedbd498483649

/usr/lib/libtls-standalone.so.1.0.0: 7f4c2ff4010e30a69f588ab4f213fdf9ce61a524a0eecd3f5af31dc760e8006c

Find binaries importing a library

{{range .files -}}
{{- if .executable}}
{{- $path := .location.path}}
{{- range .executable.importedLibraries}}
{{- if eq . "libcrypto.so.1.1"}}
{{$path}}
{{break}}
{{- end}}
{{- end}}
{{- end}}
{{- end}}
/lib/libssl.so.1.1

/sbin/apk

/usr/lib/engines-1.1/afalg.so

/usr/lib/libtls-standalone.so.1.0.0

Troubleshooting

“can’t evaluate field” errors: The field doesn’t exist or is misspelled. Check field names with syft <image> -o json | jq.

Empty output: Verify your field paths are correct. Use syft <image> -o json to see the actual data structure.

Template syntax errors: Refer to the Go template documentation for syntax help.

Additional resources

8 - Format Conversion

Convert existing SBOMs between different formats including SPDX and CycloneDX using Syft’s experimental conversion capabilities.

The ability to convert existing SBOMs means you can create SBOMs in different formats quickly, without the need to regenerate the SBOM from scratch, which may take significantly more time.

syft convert <ORIGINAL-SBOM-FILE> -o <NEW-SBOM-FORMAT>[=<NEW-SBOM-FILE>]

We support formats with wide community usage AND good encode/decode support by Syft. The supported formats are:

  • Syft JSON (-o json)
  • SPDX JSON (-o spdx-json)
  • SPDX tag-value (-o spdx-tag-value)
  • CycloneDX JSON (-o cyclonedx-json)
  • CycloneDX XML (-o cyclonedx-xml)

Conversion example:

syft alpine:latest -o syft-json=sbom.syft.json # generate a syft SBOM
syft convert sbom.syft.json -o cyclonedx-json=sbom.cdx.json  # convert it to CycloneDX

Best practices

Use Syft JSON as the source format

Generate and keep Syft JSON as your primary SBOM. Convert from it to other formats as needed:

# Generate Syft JSON (native format with complete data)
syft <source> -o json=sbom.json

# Convert to other formats
syft convert sbom.json -o spdx-json=sbom.spdx.json
syft convert sbom.json -o cyclonedx-json=sbom.cdx.json

Converting between non-Syft formats loses data. Syft JSON contains all information Syft extracted, while other formats use different schemas that can’t represent the same fields.

What gets preserved

Conversions from Syft JSON to SPDX or CycloneDX preserve all standard SBOM fields. Converted output matches directly-generated output (only timestamps and IDs differ).

Avoid chaining conversions (e.g., SPDX → CycloneDX). Each step may lose format-specific data.

Reliably preserved across conversions:

  • Package names, versions, and PURLs
  • License information
  • CPEs and external references
  • Package relationships

May be lost in conversions:

  • Tool configuration and cataloger information
  • Source metadata (image manifests, layers, container config)
  • File location details and layer attribution
  • Package-manager-specific metadata (git commits, checksums, provides/dependencies)
  • Distribution details

When to convert vs regenerate

Convert from Syft JSON when:

  • You need multiple formats for different tools
  • The original source is unavailable
  • Scanning takes significant time

Regenerate from source when:

  • You need complete format-specific data
  • Conversion output is missing critical information

9 - Attestation

Generate cryptographically signed SBOM attestations using in-toto and Sigstore to create, verify, and attach attestations to container images for supply chain security.

Overview

An attestation is cryptographic proof that you created a specific SBOM for a container image. When you publish an image, consumers need to trust that the SBOM accurately describes the image contents. Attestations solve this by letting you sign SBOMs and attach them to images, enabling consumers to verify authenticity.

Syft supports two approaches:

  • Keyless attestation: Uses your identity (GitHub, Google, Microsoft) as trust root via Sigstore. Best for CI/CD and teams.
  • Local key attestation: Uses cryptographic key pairs you manage. Best for air-gapped environments or specific security requirements.

Prerequisites

Before creating attestations, ensure you have:

  • Syft installed
  • Cosign ≥ v1.12.0 installed (installation guide)
  • Write access to the OCI registry where you’ll publish attestations
  • Registry authentication configured (e.g., docker login for Docker Hub)

For local key attestations, you’ll also need a key pair. Generate one with:

cosign generate-key-pair

This creates cosign.key (private key) and cosign.pub (public key). Keep the private key secure.

Keyless attestation

Keyless attestation uses Sigstore to tie your OIDC identity (GitHub, Google, or Microsoft account) to the attestation. This eliminates key management overhead.

Create a keyless attestation

syft attest --output cyclonedx-json <IMAGE>

Replace <IMAGE> with your image reference (e.g., docker.io/myorg/myimage:latest). You must have write access to this image.

What happens:

  1. Syft opens your browser to authenticate via OIDC (GitHub, Google, or Microsoft)
  2. After authentication, Syft generates the SBOM
  3. Sigstore signs the SBOM using your identity
  4. The attestation is uploaded to the OCI registry alongside your image

Verify a keyless attestation

Anyone can verify the attestation using cosign:

COSIGN_EXPERIMENTAL=1 cosign verify-attestation <IMAGE>

Successful output shows:

  • Attestation claims are validated
  • Claims exist in the Sigstore transparency log
  • Certificates verified against Fulcio (Sigstore’s certificate authority)
  • Certificate subject (your identity email)
  • Certificate issuer (identity provider URL)

Example:

Certificate subject:  user@example.com
Certificate issuer URL:  https://accounts.google.com

This proves the attestation was created by the specified identity.

Local key attestation

Local key attestation uses cryptographic key pairs you manage. You sign attestations with your private key, and consumers verify with your public key.

Create a key-based attestation

Generate the attestation and save it locally:

syft attest --output spdx-json --key cosign.key docker.io/myorg/myimage:latest > attestation.json

The output is a DSSE envelope containing an in-toto statement with your SBOM as the predicate.

Attach the attestation to your image

Use cosign to attach the attestation:

cosign attach attestation --attestation attestation.json docker.io/myorg/myimage:latest

You need write access to the image registry for this to succeed.

Verify a key-based attestation

Consumers verify using your public key:

cosign verify-attestation --key cosign.pub --type spdxjson docker.io/myorg/myimage:latest

Successful output shows:

Verification for docker.io/myorg/myimage:latest --
The following checks were performed on each of these signatures:
  - The cosign claims were validated
  - The signatures were verified against the specified public key
  - Any certificates were verified against the Fulcio roots.

To extract and view the SBOM:

cosign verify-attestation --key cosign.pub --type spdxjson docker.io/myorg/myimage:latest | \
  jq '.payload | @base64d | .payload | fromjson | .predicate'

Use with vulnerability scanning

Pipe the verified SBOM directly to Grype for vulnerability analysis:

cosign verify-attestation --key cosign.pub --type spdxjson docker.io/myorg/myimage:latest | \
  jq '.payload | @base64d | .payload | fromjson | .predicate' | \
  grype

This ensures you’re scanning a verified, trusted SBOM.

Troubleshooting

Authentication failures

  • Ensure you’re logged into the registry: docker login <registry>
  • Verify you have write access to the image repository

Cosign version errors

  • Update to cosign ≥ v1.12.0: cosign version

Verification failures

  • For keyless: ensure COSIGN_EXPERIMENTAL=1 is set
  • For key-based: verify you’re using the correct public key
  • Check the attestation type matches (--type spdxjson or --type cyclonedx-json)

Permission denied uploading attestations

  • Verify write access to the registry
  • Check authentication credentials are current
  • Ensure the image exists in the registry before attaching attestations