Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
SyftCLIScanner: support SBOM generation with syft CLI
Packit currently supports SBOM generation with syft tooling by utilizing syft's go library. This has caused packit maintainers significant maintainence burden. This commit adds a mechanism for buildpack authors to utlize the syft CLI instead to generate SBOM. The intention here is that with widespread adoption of this, we can phase out the codebase that uses the syft go libary and thereby relieve the maintainers of this pain. Until recently, syft did not allow consumers to specify the exact schema version of an SBOM mediatype they want generated (the tooling currently supports passing a version for CycloneDX and SPDX - github.com/anchore/syft/issues/846#issuecomment-1908676454). So packit was forced to vendor-in (copy) large chunks of upstream syft go code into packit in order to pin SBOM mediatype versions to versions that most consumers wanted to use. Everytime a new version of Syft comes out, maintainers had to painfully update the vendored-in code to work with upstream syft components (e.g. github.com//pull/491). Furthermore, it is advantageous to use the syft CLI instead of syft go library for multiple reasons. With CLI, we can delegate the entire SBOM generation mechanism easily to syft. It should help buildpacks avoid any CVEs that are exposed to it via syft go libaries. The CLI tool is well documented and widely used in the community, and it seems like the syft project is developed with with a CLI-first approach. The caveat here is that buildpack authors who use this method should include the Paketo Syft buildpack in their buildplan to have access to the CLI during the build phase. Example usage: \# detect \# unless BP_DISABLE_BOM is true requirements = append(requirements, packit.BuildPlanRequirement{ Name: "syft", Metadata: map[string]interface{}{ "build": true, }, }) \# build syftCLIScanner := sbomgen.NewSyftCLIScanner( pexec.NewExecutable("syft"), scribe.NewEmitter(os.Stdout), ) \# To scan a layer after installing a dependency _ = syftCLIScanner.GenerateSBOM(myLayer.Path, context.Layers.Path, myLayer.Name, context.BuildpackInfo.SBOMFormats..., ) \# OR to scan the workspace dir after running a process _ = syftCLIScanner.GenerateSBOM(context.WorkingDir, context.Layers.Path, myLayer.Name, context.BuildpackInfo.SBOMFormats..., ) - A new package sbomgen is created instead of adding the functionality to the existing sbom package because it helps buildpacks remove pinned "anchore/syft" lib from their go.mod which were flagged down by CVE scanners. - I have not implemented pretty-fication of SBOM that the codepath that use syft go lib implements. This seems to be adding bloat to the app image and not supported via CLI. Consumers of SBOM can easily prettify the SBOM JSONs. - In the codepath that use the syft go lib, license information is manually injected from buildpack.toml data into the SBOM. This is not available with the SyftCLIScanner. I couldn't find any reasoning for why this was done in the first place. - I have intentionally not reused some code in methods that's mixed up with the syft go library with an intention to easily phase out that codebase in the near future.
- Loading branch information