anchore/grype
Package providers
Active contributors: Alex Goodman, Will Murphy, Keith Zantow
Purpose
The package provider layer translates user input — an image reference, a directory, an SBOM file, a PURL, a CPE — into the canonical []pkg.Package plus pkg.Context shape that the matcher pipeline consumes. It is also the integration boundary with Syft.
Directory layout
grype/pkg/
├── package.go # Package struct + conversions
├── context.go # Context (distro detection, etc.)
├── provider.go # Provide() entry point + dispatch
├── provider_config.go # ProviderConfig
├── purl_provider.go # pkg:... and purl: file inputs
├── cpe_provider.go # cpe:... and cpes: file inputs
├── syft_provider.go # delegates to syft for image/dir/file/oci/registry
├── syft_sbom_provider.go # decodes Syft JSON, SPDX, CycloneDX SBOMs
├── upstream_package.go # source package handling (rpm sourceRPM, etc.)
├── version_format.go # ecosystem-aware version format selection
├── apk_metadata.go, rpm_metadata.go,
│ golang_metadata.go,
│ java_metadata.go # ecosystem-specific metadata extraction
└── qualifier/ # PURL qualifier handlingThe Provide entry point
grype/pkg/provider.go::Provide is the single function the CLI calls:
packages, pkgContext, sbom, err := pkg.Provide(userInput, getProviderConfig(opts))It dispatches based on userInput prefix:
| Prefix / shape | Provider |
|---|---|
purl: or pkg: |
purl_provider.go |
cpe:2.3: or cpes: |
cpe_provider.go |
sbom:, stdin, .json, .xml |
syft_sbom_provider.go |
| Anything else | syft_provider.go |
The syft_provider further delegates to syft.GetSource(...), which understands all the image and filesystem source schemes (docker:, oci-archive:, oci-dir:, singularity:, dir:, file:, registry:, plus the bare-tag/path heuristic).
Package model
grype/pkg/package.go::Package is Grype's canonical package struct. It carries:
- Identity:
ID,Name,Version,Type(Syft package type),Language,PURL. - Distribution:
Distro(pointer todistro.Distro). - Locations:
Locations(file system paths). - Licenses, CPEs, MetadataType + ecosystem-specific Metadata.
RelatedPackagesmap — used byIgnoreRelatedPackagefilters to find upstream relationships.Upstreams— a list of source packages (e.g. for an rpm, the SRPM; for a debian binary, the source package).
The model is intentionally a superset of what Syft exposes: matchers need a few fields that Syft's pkg.Package does not carry, and Syft's package shape is allowed to evolve independently.
Context
pkg.Context carries scan-wide signals that the matchers need:
Source— the original Syft source description.Distro— the detected Linux distribution.DistroDetectionFailed— true whenos-releasewas present but unmapped.
The matcher uses DistroDetectionFailed to emit a single warning rather than per-package noise.
SBOM provider
syft_sbom_provider.go is the most-exercised provider — it powers grype sbom:... and the stdin pipeline (syft <target> -o json | grype). It:
- Detects the SBOM format (Syft JSON, SPDX, CycloneDX) using Syft's format autodetector.
- Decodes into
sbom.SBOM. - Iterates
sbom.Artifacts.Packagesand converts each Syft package to apkg.Packageviapackage.go::New. - Extracts the OS distribution from
sbom.Artifacts.LinuxDistribution. - Returns the original
*sbom.SBOMso downstream presenters (CycloneDX especially) can preserve the full BOM in their output.
PURL and CPE providers
purl_provider.go and cpe_provider.go are minimal; they parse the input form (a single PURL/CPE on the command line, or one per line in a file), construct pkg.Package objects with only the fields that PURL/CPE carry, and synthesize a pkg.Context without distro information. These flows are mostly used for CI integrations and one-off lookups.
Upstream packages
For distro packages, the matcher needs to consult both the binary package name and its source/upstream:
- An rpm
kernel-headers-Xis built from the SRPMkernel. The matcher pipeline wants vulnerabilities for both. - A Debian
linux-libc-devis built from the sourcelinux.
upstream_package.go::UpstreamPackages(p) returns the synthesized upstream Package objects, which the matcher iterates alongside the binary package itself. The match.IgnoreRulePackage.UpstreamName field lets users target rules at upstream identities.
Version formats
version_format.go::VersionFormatFromPkg maps a pkg.Package to a version.Format (apk, deb, rpm, semver, gem, maven, pep440, ...). The matcher pipeline relies on this to pick the right comparator from grype/version/.
Key abstractions
| Symbol | Where | Description |
|---|---|---|
pkg.Package |
grype/pkg/package.go |
Grype's canonical package model. |
pkg.Context |
grype/pkg/context.go |
Scan-wide signals (distro, source). |
pkg.Provide |
grype/pkg/provider.go |
Entry point dispatching to the right provider. |
pkg.ProviderConfig |
grype/pkg/provider_config.go |
User-supplied options (catalog selection, registry creds, etc.). |
pkg.UpstreamPackages |
grype/pkg/upstream_package.go |
Synthesizes source-package siblings for distro packages. |
Key source files
| File | Purpose |
|---|---|
grype/pkg/provider.go |
Dispatches input strings to providers. |
grype/pkg/syft_sbom_provider.go |
SBOM decoding (Syft JSON, SPDX, CycloneDX). |
grype/pkg/syft_provider.go |
Image and filesystem source delegation to Syft. |
grype/pkg/package.go |
The pkg.Package struct and conversions. |
grype/pkg/upstream_package.go |
Source/upstream package synthesis. |
Entry points for modification
- New input form — extend the dispatch in
provider.go::Provideand add a new*_provider.gofile. The simplest model ispurl_provider.go. - New ecosystem metadata — add a
*_metadata.gofile with the type, register the conversion inpackage.go::New, and updateversion_format.goif the comparator selection should change. - New SBOM format — usually handled by upgrading Syft, since Syft owns format decoding. Grype just adapts whatever Syft returns.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.