You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This proposes migrating off the openvex/discovery library and implementing OCI VEX discovery natively in Trivy.
Trivy discovers VEX attestations attached to OCI artifacts (--vex oci) through openvex/discovery. That library only looks for legacy .att-tag attestations (Cosign v2 default) and is effectively unmaintained. Starting with Cosign v3, cosign attest defaults to --new-bundle-format=true and stores the attestation as an OCI 1.1 referrer (the new Sigstore bundle format). As a result, attestations produced by a default cosign attest on Cosign v3 are not discovered and users get No VEX attestations found.
Reported in #10656 (Cosign v3.0.6, cosign attest --type openvex).
The migration moves discovery in-tree, adds support for the new bundle format, and keeps backward compatibility with the legacy .att path.
Root Cause
No Cosign v3 / new bundle format support.openvex/discovery (the version we depend on) only resolves legacy .att-tag attestations. The OCI 1.1 referrer that Cosign v3 produces by default is not picked up. Confirmed in oras attached VEX attestation not found by Trivy #10656.
openvex/discovery is effectively unmaintained. Over the last year the repo has merged only Dependabot/CI bumps — no features or bug fixes:
openvex/discovery#112 — bump cosign/v2 → cosign/v3@v3.0.3 — open since 2025-12-11, currently in merge conflict, no maintainer response (a "Are there plans to merge this?" ping on 2026-04-16 went unanswered).
openvex/discovery#82 — request for registry auth options — open since 2025-05-26, 0 comments.
Library logs are invisible.openvex/discovery exposes its own *slog.Logger via Agent.Options.Logger (default: JSON handler to stderr at INFO). Trivy does not reconfigure it (see pkg/vex/oci.go:40), so the library's DebugContext lines never surface through Trivy's --debug, and users can't self-diagnose.
Registry auth not reused. The discovery path falls back to the default go-containerregistry keychain instead of Trivy's native registry auth. Confirmed in bug(vex): Trivy doesn't support auth for OCI images from private registries #8916: VEX discovery against a private registry fails with UNAUTHORIZED even though the image itself scans fine. The workaround — trivy registry login / docker login to populate the Docker config that the default keychain reads — confirms the mechanism: credentials passed via Trivy's own flags/env (TRIVY_USERNAME / TRIVY_PASSWORD) never reach discovery. Tracked upstream as Is it planned to add auth options? openvex/discovery#82 (auth options for ProbePurl).
Proposed Solution
Implement OCI VEX discovery natively in Trivy (replace the openvex/discovery dependency in pkg/vex/oci.go) and support both attestation layouts:
Legacy .att tag (Cosign v2 default) — keep working for the existing majority of users.
OCI 1.1 referrer + Sigstore bundle (Cosign v3 default) — list referrers, filter by artifact type, decode the bundle → DSSE → in-toto Statement → OpenVEX predicate.
Benefits of going in-tree:
Wire Trivy's own *slog.Logger into the discovery code (fixes (3)).
Reuse Trivy's existing registry auth / transport for private registries (addresses (4)).
Control over the format support timeline instead of waiting on an unmaintained upstream.
openvex/discovery is a thin wrapper over a couple of Cosign helpers (~50 lines of application logic), so moving it in-tree does not mean re-implementing heavy infrastructure.
Note: discovery is scoped to attestations attached via cosign attest (legacy .att or the new bundle referrer). Raw oras attach of an arbitrary in-toto blob is out of scope, as today.
Dependency Impact
Current state (go.mod + go mod why -m):
github.com/openvex/discovery — direct.
github.com/sigstore/cosign/v2 v2.6.2 — indirect, pulled only via openvex/discovery → probers/oci → cosign/v2/pkg/cosign.
github.com/sigstore/sigstore-go v1.1.4 — indirect, pulled via the same chain (cosign/v2 → sigstore-go/pkg/bundle).
sigstore-go becomes a direct dependency (needed to decode the new bundle).
go-containerregistry (referrers/manifest/blob/tag fetch) and go-vex (parse the Statement into a VEX predicate) stay direct.
The Cosign dependency depends on the decision in Open Question 1.
Open Questions / Decisions Needed
How to handle the Cosign dependency for the implementation?
A. Depend on cosign/v3 as a thin wrapper (uses cosign.FetchAttestationsForReference, ociremote.Referrers, ociremote.Bundle). Least code; effectively the swap that upstream PR False positives on Alpine (GNU vs Busybox) #112 attempts (cosign/v2 → cosign/v3).
B (I'm leaning towards this option.). Drop Cosign entirely and implement on go-containerregistry (referrers + tag/manifest/blob fetch) + sigstore-go (bundle decode) + go-vex (parse). More code, fewer/lighter deps, full control over auth and logging.
New package name: reshape pkg/vex/oci.go into pkg/vex/oci/, or introduce pkg/vex/discovery/?
Description
This proposes migrating off the
openvex/discoverylibrary and implementing OCI VEX discovery natively in Trivy.Trivy discovers VEX attestations attached to OCI artifacts (
--vex oci) throughopenvex/discovery. That library only looks for legacy.att-tag attestations (Cosign v2 default) and is effectively unmaintained. Starting with Cosign v3,cosign attestdefaults to--new-bundle-format=trueand stores the attestation as an OCI 1.1 referrer (the new Sigstore bundle format). As a result, attestations produced by a defaultcosign atteston Cosign v3 are not discovered and users getNo VEX attestations found.Reported in #10656 (Cosign v3.0.6,
cosign attest --type openvex).The migration moves discovery in-tree, adds support for the new bundle format, and keeps backward compatibility with the legacy
.attpath.Root Cause
openvex/discovery(the version we depend on) only resolves legacy.att-tag attestations. The OCI 1.1 referrer that Cosign v3 produces by default is not picked up. Confirmed in oras attached VEX attestation not found by Trivy #10656.openvex/discoveryis effectively unmaintained. Over the last year the repo has merged only Dependabot/CI bumps — no features or bug fixes:cosign/v2 → cosign/v3@v3.0.3— open since 2025-12-11, currently in merge conflict, no maintainer response (a "Are there plans to merge this?" ping on 2026-04-16 went unanswered).go-vexto v0.2.8 — open since 2026-04-16, 0 comments.openvex/discoveryexposes its own*slog.LoggerviaAgent.Options.Logger(default: JSON handler to stderr at INFO). Trivy does not reconfigure it (seepkg/vex/oci.go:40), so the library'sDebugContextlines never surface through Trivy's--debug, and users can't self-diagnose.UNAUTHORIZEDeven though the image itself scans fine. The workaround —trivy registry login/docker loginto populate the Docker config that the default keychain reads — confirms the mechanism: credentials passed via Trivy's own flags/env (TRIVY_USERNAME/TRIVY_PASSWORD) never reach discovery. Tracked upstream as Is it planned to add auth options? openvex/discovery#82 (auth options forProbePurl).Proposed Solution
Implement OCI VEX discovery natively in Trivy (replace the
openvex/discoverydependency inpkg/vex/oci.go) and support both attestation layouts:.atttag (Cosign v2 default) — keep working for the existing majority of users.Benefits of going in-tree:
*slog.Loggerinto the discovery code (fixes (3)).openvex/discoveryis a thin wrapper over a couple of Cosign helpers (~50 lines of application logic), so moving it in-tree does not mean re-implementing heavy infrastructure.Dependency Impact
Current state (
go.mod+go mod why -m):github.com/openvex/discovery— direct.github.com/sigstore/cosign/v2 v2.6.2— indirect, pulled only viaopenvex/discovery → probers/oci → cosign/v2/pkg/cosign.github.com/sigstore/sigstore-go v1.1.4— indirect, pulled via the same chain (cosign/v2 → sigstore-go/pkg/bundle).github.com/google/go-containerregistry v0.21.6— direct.github.com/openvex/go-vex v0.2.7— direct.cosign/v3in the module graph today (the upstream v2→v3 bump is the still-open PR False positives on Alpine (GNU vs Busybox) #112).After migration:
github.com/openvex/discovery.sigstore-gobecomes a direct dependency (needed to decode the new bundle).go-containerregistry(referrers/manifest/blob/tag fetch) andgo-vex(parse the Statement into a VEX predicate) stay direct.Open Questions / Decisions Needed
cosign/v3as a thin wrapper (usescosign.FetchAttestationsForReference,ociremote.Referrers,ociremote.Bundle). Least code; effectively the swap that upstream PR False positives on Alpine (GNU vs Busybox) #112 attempts (cosign/v2 → cosign/v3).go-containerregistry(referrers + tag/manifest/blob fetch) +sigstore-go(bundle decode) +go-vex(parse). More code, fewer/lighter deps, full control over auth and logging.pkg/vex/oci.gointopkg/vex/oci/, or introducepkg/vex/discovery/?References
pkg/vex/oci.godocs/docs/supply-chain/vex/oci.md