Grype should find and analyze SBOM attestations
What would you like to be added:
When Grype analyzes an OCI container, it should query the container registry for OCI artifacts. If the artifacts include SBOM attestations, Grype should download them from the registry, decode their base64-encoded payload, and then analyze the embedded SBOM (which is in either CycloneDX or SPDX format). Possibly related: https://github.com/anchore/grype/issues/519.
Why is this needed:
GitHub makes it very easy to generate SBOM attestations and publish them as OCI artifacts. However, if an SBOM is published this way, Grype currently fails to find it. This is a real pity, because cryptographically signed SBOM attestations would be great for securing the software supply chain.
Test case
For a test case, please see https://github.com/brawer/sbom-attestation-test which uses GitHub’s SBOM attestation on a minimal SBOM that claims to use a highly vulnerable dependency.
Observed:
As of July 2026, Grype reports no vulnerabilities even though the scanned container has an OCI artifact with an SBOM attestation that declares, in its base64-encoded CycloneDX payload, a highly vulnerable dependency.
$ grype ghcr.io/brawer/sbom-attestation-test:latest
✔ Parsed image sha256:630f996e5c800dd9e645f171df85cb806e0f923150eda0041d9af8f884f871c3
✔ Cataloged contents d1516981430941ef00c2c7e2e3cf2a1080e0351db30665ef9ae40192135c5b36
├── ✔ Packages [0 packages]
└── ✔ Executables [0 executables]
✔ Scanned for vulnerabilities [0 vulnerability matches]
├── by severity: 0 critical, 0 high, 0 medium, 0 low, 0 negligible
└── by status: 0 fixed, 0 not-fixed, 0 ignored
No vulnerabilities foundExpected:
Grype should find the SBOM artifact (from the base64-encoded payload of the signature envelope) and analyze it.
$ grype ghcr.io/brawer/sbom-attestation-test:latest
✔ Scanned for vulnerabilities [0 vulnerability matches]
├── by severity: 2 critical, 1 high, 4 medium, 0 low, 0 negligible
└── by status: 7 fixed, 0 not-fixed, 0 ignored
NAME INSTALLED FIXED IN TYPE VULNERABILITY SEVERITY EPSS RISK
log4j-core 2.14.1 2.15.0 java-archive GHSA-jfh8-c2jp-5v3q Critical 100.0% (100th) 100.0 KEV
log4j-core 2.14.1 2.16.0 java-archive GHSA-7rjr-3q55-vv33 Critical 100.0% (99th) 99.0 KEV
log4j-core 2.14.1 2.17.0 java-archive GHSA-p6xc-xr62-6r2g High 100.0% (99th) 80.5
log4j-core 2.14.1 2.17.1 java-archive GHSA-8489-44mv-ggj8 Medium 97.9% (99th) 56.8
log4j-core 2.14.1 2.25.4 java-archive GHSA-3pxv-7cmr-fjr4 Medium 0.9% (54th) 0.5
log4j-core 2.14.1 2.25.3 java-archive GHSA-vc5p-v9hr-52mj Medium 0.8% (51st) 0.4
log4j-core 2.14.1 2.25.4 java-archive GHSA-6hg6-v5c8-fphq Medium 0.4% (33rd) 0.2Basically, grype could start by doing the equivalent of oras discover. Probably, though, grype would not want to call another tool such as oras — rather, grype would likely invoke a library function that issues an API call to the OCI container registry, asking what OCI artifacts are available for the scanned container. Just for the sake of illustration, here’s the output of oras discover for the test container:
$ oras discover ghcr.io/brawer/sbom-attestation-test:latest
ghcr.io/brawer/sbom-attestation-test@sha256:d1516981430941ef00c2c7e2e3cf2a1080e0351db30665ef9ae40192135c5b36
└── application/vnd.dev.sigstore.bundle.v0.3+json
├── sha256:0aedce218ae605a31237dab5e6406e39ea899d78cdd8815ce7cb0cbb9cdba2f2
│ └── [annotations]
│ ├── org.opencontainers.image.created: "2026-07-27T14:57:47.823Z"
│ ├── dev.sigstore.bundle.content: dsse-envelope
│ └── dev.sigstore.bundle.predicateType: https://cyclonedx.org/bom
└── sha256:6babc8a7e2709d55bd46af5451d3313932b8c7b0c078f93c80848a3daee85d81
└── [annotations]
├── org.opencontainers.image.created: "2026-07-27T14:57:50.954Z"
├── dev.sigstore.bundle.content: dsse-envelope
└── dev.sigstore.bundle.predicateType: https://slsa.dev/provenance/v1Note the annotation whose dev.sigstore.bundle.predicateType is https://cyclonedx.org/bom — this indicates an SBOM attestation. Grype would download this OCI artifact, (ideally) validate the signature, and decocde the base64-encoded payload field which is a CycloneDX SBOM. The handling of SPDX would be nearly identical.
Source: anchore/grype