Vex purl encoding and grype match#17
Merged
Merged
Conversation
Two changes that together get VEX-based suppression working in both Trivy and Grype against the docker-images CI scans: 1) Add a bare `pkg:oci/<name>` product entry per OCI statement. Grype's scan-time image PURL is the bare form -- it does not carry a `repository_url` qualifier -- so qualified-only product entries are invisible to Grype's statement matcher even when the VEX file is fed in directly via `--vex`. The qualified entries are kept and continue to scope statements per registry for Trivy's index lookup; the bare entry is what lets Grype apply the same statement. 2) Drop percent-encoding in VEX statement product/subcomponent @ids. PURL consumers (Trivy's statement matcher, Grype, vexctl) normalise qualifier values before comparing, so `repository_url=quay.io/...` and `repository_url=quay.io%2F...` are equivalent at match time. The unencoded form is the convention in other public vexhubs and is much easier to read and diff. The `index.json` lookup is the one place that does byte-level string match, so `build_index.py` continues to emit the canonical percent-encoded form there. tools/build_index.py: - _parse_purl now stores qualifier values decoded and accepts either encoded or unencoded input. The strict `_ensure_percent_encoded` rejection is removed -- canonicalisation happens on emit, not on ingest. - index_id_for_purl no longer hard-requires `repository_url` for OCI PURLs. Bare `pkg:oci/<name>` products are valid and produce a bare index entry; qualified products produce a percent-encoded entry as before. Empty `repository_url` is still rejected. pkg/oci/opentelemetry-target-allocator/scan.openvex.json, pkg/oci/stackstate-k8s-agent/scan.openvex.json: - Decode `%2F` in repository_url qualifier values. - Decode `%2B` in subcomponent versions (e.g. v28.5.2+incompatible). - Add a bare `pkg:oci/<name>` product entry per statement, with the same subcomponents as the qualified entries. index.json: regenerated. Each OCI image now has three entries -- one per registry-scoped product plus one bare -- alongside the existing maven entry.
Grype reports CVE-2026-34040 and CVE-2026-33997 a second time under their Go vulnerability database IDs (GO-2026-4887 and GO-2026-4883 respectively), because grype pulls from both NVD/GHSA and the Go vulndb and only partially deduplicates findings whose primary ID differs across databases. Statement matching is keyed on `vulnerability.name` and `aliases[]`; without the GO-* aliases the two Go-DB findings stayed unmatched even though their CVE-* twins were filtered. Add the Go IDs as aliases on the corresponding statements in opentelemetry-target-allocator. The other docker/moby CVEs in this file (CVE-2026-41567, CVE-2026-42306, CVE-2026-41568) do not have Go vulndb entries yet, so no further aliasing is required.
deontaljaard
approved these changes
Jun 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Relaxing the requirement on the PURL repository_url encoding in the reports. They can simply use
/, but the index.json must use the encoded version.To be compatible with
grypescans that we use internally, we also need to add an entry without therepository_url.