Skip to content

feat(cg/transformers): add chainguard osv transformer#3474

Open
crosleyzack wants to merge 7 commits into
anchore:mainfrom
crosleyzack:crosley/chainguard-osv-transformer
Open

feat(cg/transformers): add chainguard osv transformer#3474
crosleyzack wants to merge 7 commits into
anchore:mainfrom
crosleyzack:crosley/chainguard-osv-transformer

Conversation

@crosleyzack

@crosleyzack crosleyzack commented May 29, 2026

Copy link
Copy Markdown
Contributor

What

Add Chainguard transformer for new OSV feed. This also sets the architecture on packages so vuln matches can be filtered by architecture. Test images from Chainguard are currently being reviewed and should be in our GCR bucket soon.

Why

Allows grype to convert the vunnel output into vuln matches

Notes

Similar but updated version of #3255

Part of Chainguard issue INT-520

Comment thread grype/db/v6/blobs.go Outdated
Comment thread grype/db/v6/vulnerability.go Outdated
Comment thread grype/db/v6/vulnerability_test.go
@crosleyzack crosleyzack changed the title feat(cg/transformers) INT-512: add chainguard osv transformer feat(cg/transformers): add chainguard osv transformer May 29, 2026
Comment thread grype/db/v6/build/transformers/osv/transform_cg.go Outdated
@crosleyzack crosleyzack force-pushed the crosley/chainguard-osv-transformer branch 2 times, most recently from 867ffd9 to 2cc549e Compare June 2, 2026 17:08
Comment on lines +9 to +19
// OSVVulnerability extends the standard OSV Vulnerability model with additional
// fields used by Chainguard/Wolfi advisories that aren't yet in the osv-scanner library.
type OSVVulnerability struct {
models.Vulnerability

// TODO should this be put into upstream osv-scanner?
// Upstream contains IDs of upstream vulnerabilities that this advisory addresses.
// Per OSV spec, this is semantically correct for distro advisories that reference
// upstream CVEs. Included alongside "related" for backwards compatibility.
// See: https://ossf.github.io/osv-schema/
Upstream []string `json:"upstream,omitempty"`

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be put into the upstream models.Vulnerability?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"github.com/google/osv-scanner/pkg/models" is deprecated and not getting updates any more. We might need to implement our own structs in this repo soon. I think this approach is ok for this PR.

@crosleyzack crosleyzack force-pushed the crosley/chainguard-osv-transformer branch 4 times, most recently from 4817276 to d9d6fde Compare June 10, 2026 01:20
Comment on lines +41 to +46
// setArchFromPURL runs for every format: no SBOM decoder populates grype's
// pkg.Arch field directly, so without this the architecture qualifier on
// distro-keyed vulnerabilities can't filter by package arch.
enhancers := []Enhancer{setArchFromPURL}
if fmtID != syftjson.ID {
enhancers = purlEnhancers(applyChannel)
enhancers = append(enhancers, setUpstreamsFromPURL, setDistroFromPURL(applyChannel))

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we want normal scans to also include the arch information if available

Comment on lines +38 to +41
// setArchFromPURL is applied for image scans because syft does not populate
// grype's pkg.Arch field directly — without this the architecture qualifier
// on distro-keyed vulnerabilities can't filter by package arch.
packages := FromCollection(s.Artifacts.Packages, s.Relationships, config.SynthesisConfig, setArchFromPURL)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

include arch information in sbom scans

@crosleyzack crosleyzack force-pushed the crosley/chainguard-osv-transformer branch from fc60746 to 6d183ed Compare June 10, 2026 18:06
Signed-off-by: crosleyzack <mail@crosleyzack.com>
Signed-off-by: Zackary Crosley <zackary.crosley@chainguard.dev>
Signed-off-by: crosleyzack <mail@crosleyzack.com>
Signed-off-by: Zackary Crosley <zackary.crosley@chainguard.dev>
Signed-off-by: crosleyzack <mail@crosleyzack.com>
Signed-off-by: Zackary Crosley <zackary.crosley@chainguard.dev>
Signed-off-by: crosleyzack <mail@crosleyzack.com>
Signed-off-by: Zackary Crosley <zackary.crosley@chainguard.dev>
Signed-off-by: crosleyzack <mail@crosleyzack.com>
Signed-off-by: Zackary Crosley <zackary.crosley@chainguard.dev>
@crosleyzack crosleyzack force-pushed the crosley/chainguard-osv-transformer branch from 3b83a4a to dca342b Compare June 17, 2026 18:15
Signed-off-by: Zackary Crosley <zackary.crosley@chainguard.dev>
Signed-off-by: Zackary Crosley <zackary.crosley@chainguard.dev>
}

// archFromPURL reads arch data for Grype can use, which is ignored by Syft's PURL conversion
func archFromPURL(purl packageurl.PackageURL) (arch string) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is unnecessary now that anchore/syft#4987 is in Syft.

Comment thread grype/pkg/package.go
Language syftPkg.Language // the language ecosystem this package belongs to (e.g. JavaScript, Python, etc)
Distro *distro.Distro // a specific distro this package originated from
// TODO: should this be an enum to avoid mismatches like "amd64" vs "x86_64"?
Arch string // the architecture of the package (e.g. "amd64", "arm64", etc)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This field should be on the ApkMetadata struct, not the top level package. Specifically here: https://github.com/anchore/grype/blob/main/grype/pkg/apk_metadata.go#L12 and set here: https://github.com/anchore/grype/blob/main/grype/pkg/package.go#L381

The package types in Grype are a narrowing of the Syft package interface. For example, APKs in Grype have owned file records because grype uses that for matching. This PR adds the ability for APKs to filter matching based on architecture.

We don't want Architecture on the top level package struct because it doesn't make sense for all package types. For example, a binary package could be a macOS multiarch binary, which would give us nothing good to put in a string field here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants