syft Documentation

CLI tool and library for generating a Software Bill of Materials from container images and filesystems

9,154 stars Go Go 1 file ยท ~3,359 tokens #containers#cyclonedx#docker#go#golang#hacktoberfest#oci#sbom
RAW Doc

Docker & Self-Hosted Deployment Verified OCI

Deploy syft on any server, homelab, or cloud container platform.

1-Click Terminal Command
bash (docker run)
docker run -d --name syft --restart always anchore/syft:latest

File: README.md

Syft

A CLI tool and Go library for generating a Software Bill of Materials (SBOM) from container images and filesystems. Exceptional for vulnerability detection when used with a scanner like Grype.

Features

[!TIP]
New to Syft? Check out the Getting Started guide for a walkthrough!

Installation

The quickest way to get up and going:

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

[!TIP]
See Installation docs for more ways to get Syft, including Homebrew, Docker, Scoop, Chocolatey, Nix, and more!

The basics

See the packages within a container image or directory:

bash
# container image
syft alpine:latest

# directory
syft ./my-project

To get an SBOM, specify one or more output formats:

bash
# SBOM to stdout
syft  -o cyclonedx-json

# Multiple SBOMs to files
syft  -o spdx-json=./spdx.json -o cyclonedx-json=./cdx.json

[!TIP]
Check out the Getting Started guide to explore all of the capabilities and features.

Want to know all of the ins-and-outs of Syft? Check out the CLI docs, configuration docs, and JSON schema.

Contributing

We encourage users to help make these tools better by submitting issues when you find a bug or want a new feature.
Check out our contributing overview and developer-specific documentation if you are interested in providing code contributions.

Syft development is sponsored by Anchore, and is released under the Apache-2.0 License.
The Syft logo by Anchore is licensed under CC BY 4.0

For commercial support options with Syft or Grype, please contact Anchore.

Come talk to us!

The Syft Team holds regular community meetings online. All are welcome to join to bring topics for discussion.


File: examples/README.md

Syft API Examples

This directory contains examples of how to use the Syft API.

  • create_simple_sbom: Create a simple SBOM from scratch
  • create_custom_sbom: Create an SBOM using as much custom configuration as possible, including a custom cataloger implementation
  • decode_sbom: Take an existing SBOM file (of arbitrary format) and decode it into a Syft SBOM object
  • select_catalogers: Example demonstrating how to select specific catalogers to run
  • source_detection: Shows how to detect what to catalog automatically from a user string (e.g. container image vs directory)
  • source_from_image: Construct a source from only a container image
  • source_from_registry: Construct a source directly from a container registry

You can run any of these examples from this directory with:

bash
go run ./DIRECTORY_NAME

File: internal/cache/README.md

Caching

All caches are created from a global manager. By default this is a bypassedCache, which performs no caching.
One benefit of this is that tests don't need to worry about caching causing issues unless they explicitly need
to test the cache and can opt-in using the cache.TestCache(t) helper.

Syft sets a filesystemCache when the cache options are loaded.

When using the filesystemCache all items are stored on disk under a root directory, generally in the form of:

text
<rootDir>/<named-cache>/<data-version>/path/to/data

Using the cache

The easiest and preferred method to use the cache is a cache.Resolver, which automatically creates a <data-version>
based on the structure of the provided type.
If the structure changes in any way it will end up with a new version key and all will re populate this new key,
ignoring cached values from older, different versions.
The resolver will store items using the json package to serialize/deserialize values, so to save space
it is encouraged to use omitempty. For example:

go
type myCacheItem struct {
	Name string `json:"name",omitempty`
}

It is possible to use core types such as pkg.Package as long as they support the standard json serialization,
but this is discouraged in order to decouple changes to them from affecting the information stored in the cache.

To get a cache for this type:

go
resolver := cache.GetResolver[myCacheItem]("myCacheName", "v1")

Using the resolver is a single call, which manages checking for items in the cache, expiry times,
and if not found invoking the callback to populate the cache and return a value:

go
data := resolver.Resolve("some/cache/key", func() (myCacheItem, error) {
	// do things to return a myCacheItem or error
})

If it is common that checking for an item will result in errors, and you do not want to re-run the resolve function
when errors are encountered, instead of using GetResolver, you can use GetResolverCachingErrors, which is useful
for things such as resolving artifacts over a network, where a number of them will not be resolved, and you do not want
to continue to have the expense of running the network resolution. This should be used when it is acceptable a network
outage and cached errors is an acceptable risk.

An example can be seen in the golang cataloger fetching remote licenses.


File: schema/json/README.md

JSON Schema

This is the JSON schema for output from the JSON presenters (syft packages -o json). The required inputs for defining the JSON schema are as follows:

  • the value of internal.JSONSchemaVersion that governs the schema filename
  • the Document struct definition within github.com/anchore/syft/syft/formats/syftjson/model/document.go that governs the overall document shape
  • generated AllTypes() helper function within the syft/internal/sourcemetadata and syft/internal/packagemetadata packages

With regard to testing the JSON schema, integration test cases provided by the developer are used as examples to validate that JSON output from Syft is always valid relative to the schema/json/schema-$VERSION.json file.

Versioning

Versioning the JSON schema must be done manually by changing the JSONSchemaVersion constant within internal/constants.go.

This schema is being versioned based off of the "SchemaVer" guidelines, which slightly diverges from Semantic Versioning to tailor for the purposes of data models.

Given a version number format MODEL.REVISION.ADDITION:

  • MODEL: increment when you make a breaking schema change which will prevent interaction with any historical data
  • REVISION: increment when you make a schema change which may prevent interaction with some historical data
  • ADDITION: increment when you make a schema change that is compatible with all historical data

Adding a New `pkg.*Metadata` Type

When adding a new pkg.*Metadata that is assigned to the pkg.Package.Metadata struct field you must add a test case to cmd/syft/internal/test/integration/catalog_packages_cases_test.go that exercises the new package type with the new metadata.

Additionally it is important to generate a new JSON schema since the pkg.Package.Metadata field is covered by the schema.

Generating a New Schema

Create the new schema by running make generate-json-schema from the root of the repo:

  • If there is not an existing schema for the given version, then the new schema file will be written to schema/json/schema-$VERSION.json
  • If there is an existing schema for the given version and the new schema matches the existing schema, no action is taken
  • If there is an existing schema for the given version and the new schema does not match the existing schema, an error is shown indicating to increment the version appropriately (see the "Versioning" section)

Note: never delete a JSON schema and never change an existing JSON schema once it has been published in a release! Only add new schemas with a newly incremented version. All previous schema files must be stored in the schema/json/ directory.

Exception: `description`-only corrections

A published schema may be amended in place for one narrow case: the change touches only description text and leaves the data shape identical. Descriptions are documentation carried alongside the schema rather than constraints a validator evaluates, so correcting one cannot invalidate a document that already validated against that version. Minting a new version instead would leave the old one permanently describing the tool incorrectly, and spend a version number on no semantic change.

This applies when every one of the following holds:

  • the only differences are description values
  • no field, type, enum, required entry, or $ref is added, removed, or altered
  • the $id version is unchanged

Anything else, including adding a field that happens to be optional, is a schema change and needs a version bump per the "Versioning" section above.

The generator blocks an in-place edit by design, since it refuses to overwrite a file that differs from what it would produce. To amend one, delete the schema file and regenerate so it is rewritten from the current Go doc comments:

bash
rm schema/json/schema-$VERSION.json
make generate-json-schema

The result is byte-identical to what the generator produces, so do not hand-edit the JSON. Re-running make generate-json-schema afterwards should report No change to the existing schema!, and make check-json-schema-drift should pass. Confirm with git diff that the only changes are the intended description lines.


File: schema/cyclonedx/README.md

CycloneDX Schemas

syft generates a CycloneDX Bom output. We want to be able to validate the CycloneDX schemas
(and dependent schemas) against generated syft output. The best way to do this is with xmllint,
however, this tool does not know how to deal with references from HTTP, only the local filesystem.
For this reason we've included a copy of all schemas needed to validate syft output, modified
to reference local copies of dependent schemas.

You can get the latest schemas from the CycloneDX specifications repo.

When the spec version is bumped an approach to determining prior modifications is to compare the
prior spec version (e.g. if updating to 1.7, compare the files in this directory against the 1.6
equivalents).

One can also update the schemas and observe the errors in order to make the necessary updates.
At the time of writing, the cyclonedx.xsd needed modifications to link to the local spdx.xsd,
and also to change the minOccurs for a license tag to 0. (The json schema does not require
modification for the generated file to lint properly, but can simply be copy/pasted).


File: syft/pkg/cataloger/golang/internal/README.md

xcoff

The code in this package comes from: https://github.com/golang/go/tree/master/src/internal/xcoff -- it was copied over to add support for xcoff binaries. Golang keeps this package as internal, forbidding its external use.