Skip to main content
Earlier we built a Kyverno policy to verify that container images are signed. That solves “who built this image?” and “was it tampered with?” — but it doesn’t guarantee the image is safe to run. Alex learned this the hard way: an image signed by the official CI/CD pipeline reached production and, although the signature was valid, it contained a brand-new critical CVE. A signature proves origin and integrity, but it does not prove the image’s contents are secure or meet policy requirements. Let’s check in with Alex. His image-signing policy worked, and he’s confident — until the security team alerts him that the deployed image has a critical vulnerability. The signature only proves authenticity, not quality. Alex knows the security scanner produces signed reports, so his next questions are:
  • Can Kyverno find the signed vulnerability report (an attestation) attached to the image?
  • Can Kyverno verify the attestation’s signature?
  • Can Kyverno inspect the attestation content and make a decision based on it?
This is precisely what attestations solve.
The image shows a challenge faced by Alex, where image signing in the CI pipeline seems successful, but a signed image has a critical vulnerability.
What is an attestation? An attestation is a signed statement (typically a JSON document) that claims facts about an image. Unlike a bare image signature, which only proves integrity and origin, attestations express verifiable assertions such as:
  • What software components are inside this image? — represented by a signed SBOM (Software Bill of Materials).
  • What vulnerabilities were found? — represented by a signed vulnerability scan report.
  • Did the image pass tests? — represented by signed test results.
Because the attestation document itself is signed, consumers can verify it hasn’t been tampered with and can trust the claims it contains.
The image presents a challenge for Alex about verifying image signatures and validating vulnerability reports using Kyverno, ensuring zero critical vulnerabilities.
Attestation lifecycle Attestations are typically produced in CI/CD pipelines and follow three clear steps: Step 1 — Generate the evidence. Specialized tools output JSON (or similar) files: SBOMs list components; scanners produce vulnerability reports.
The image depicts the first step of "The Attestation Lifecycle," which involves generating evidence using specialized tools that analyze an image and produce a data file with findings.
Step 2 — Sign the evidence. Use a signing tool (for example, Cosign) to sign the data file and produce a verifiable attestation artifact.
The image describes step 2 of "The Attestation Lifecycle," focusing on signing evidence using a cryptographic signature with a tool like Cosign to create a verifiable attestation.
Step 3 — Attach the attestation to the image. The signer pushes the attestation to the registry; the artifact is cryptographically linked to the image digest (the image itself is unchanged).
The image describes "The Attestation Lifecycle" with three steps: Generate Evidence, Sign the Evidence, and Attach to Image, resulting in a cryptographically linked artifact.
Discovering attestations in a registry A normal docker pull won’t show attestations. Use ORAS to view artifacts attached to an image: oras discover shows a tree of linked artifacts and their types. Example output:
You can see the image digest, its signature, and additional signed artifacts like SBOMs and scanner reports. With these artifacts available, admission controllers like Kyverno can make evidence-based decisions about whether to allow a workload to run.
The image is a screenshot of a terminal window showing the discovery of attestations using ORAS, listing various signed components and documents like a vulnerability scan, SBOM, and VEX.
How Kyverno verifies attestations Kyverno extends verifyImages with an attestations block. Each attestation item tells Kyverno:
  • which attestation type to look for (must match the ORAS artifact type),
  • how to validate the attestation’s signature using attestors (trusted keys or certificates),
  • optional conditions to evaluate the attestation’s JSON payload using JMESPath expressions.
High-level example of the structure:
Notes on key fields:
  • type: Must match the attestation type shown by ORAS (e.g., sbom/cyclone-dx).
  • attestors: Verifies the signature of the attestation document itself (not the base image). Provide trusted keys/certificates here.
  • conditions: After the attestation signature is validated, Kyverno parses the attestation JSON and evaluates JMESPath-based conditions. The key field uses a JMESPath expression; the example extracts all license expressions from components.
The attestors block verifies the attestation document’s signature — it does not verify the base image signature. Only when the attestation signature is trusted will Kyverno evaluate the specified conditions against the attestation’s JSON content.
Example policy: require a signed SBOM and enforce component licenses This ClusterPolicy matches Pods referencing images with the given pattern, verifies that an sbom/cyclone-dx attestation is attached and signed by a trusted certificate, then ensures every component license equals GPL-3.0.
How this policy works:
  1. The policy matches Pods that reference images matching ghcr.io/kyverno/test-verify-image*.
  2. Kyverno looks for an attestation of type sbom/cyclone-dx attached to the image in the registry.
  3. The attestors block supplies the trusted certificate used to verify the SBOM attestation’s signature.
  4. If the signature validates, Kyverno evaluates the JMESPath condition {{ components[].licenses[].expression }} which collects license expressions across all components. AllIn ensures every collected license appears in the allowed list (["GPL-3.0"]). If any component has an unapproved license, the Pod admission is blocked.
The image illustrates the security requirements for checking SBOM (Software Bill of Materials) licenses, emphasizing attaching a valid, signed SBOM and using approved licenses for components.
Best practices and tips
  • Always treat attestations as first-class artifacts in CI/CD: generate, sign, and attach them in the pipeline.
  • Use Sigstore/Cosign for easy, auditable signing workflows.
  • Keep attestor trust roots (public keys/certificates) in a secure store and update Kyverno policies if keys rotate.
  • Structure JMESPath expressions to robustly handle missing or nested fields.
  • Consider multiple attestation types (vulnerability-scan, sbom, test-results) to make richer admission decisions.
Summary
  • An attestation is a signed piece of evidence (SBOM, vulnerability report, test results) attached to an image.
  • Attestation lifecycle: generate evidence → sign evidence → attach to image (registry).
  • Use ORAS to discover attestations attached to an image.
  • Kyverno’s verifyImages attestation block first verifies the attestation signature using attestors, then evaluates JMESPath-based conditions against the attestation JSON to enforce fine-grained security policies.
Links and references

Watch Video