Skip to content

[Feature] Make context's imageRegistry fail gracefully

Problem Statement

Given the following policy that check whether the image exists before doing the image-verification:

# Shortened for readability
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: verify-image-signature
spec:
  background: true
  validationFailureAction: Audit
  failurePolicy: Ignore
  rules:
    - name: verify-ghcr-kyverno-test-image
      context:
        - name: imageData
          imageRegistry:
            reference: "{{ request.object.spec.containers[0].image }}"
      preconditions:
        all:
          - key: "{{ imageData.resolvedImage || '' }}"
            operator: NotEquals
            value: ""
      verifyImages:
      # ...

If the image doesn't exist in the repo anymore, the imageRegistry.reference will fail with an error, creating a failed entry in the policy's report. (see this playground)

While the error is valid (manifest not found), in cases where the user wants to discard errors using preconditions, we should allow him to do so.

The end goal would be to allow user to: 1️⃣ skip using a precondition depending on the error that was received during the imageRegistry call 2️⃣ not break the existing behaviour

Solution Description

A better way to handle errors as first member of the imageRegistry response. At the moment, we return a map with all the necessary key in fetchImageDataMap (here):

	data := map[string]interface{}{
		"image":         desc.Image,
		"resolvedImage": desc.ResolvedImage,
		"registry":      desc.Registry,
		"repository":    desc.Repository,
		"identifier":    desc.Identifier,
		"manifestList":  manifestList,
		"manifest":      manifest,
		"configData":    configData,

        // NEW
		"errorMessage": string
		"failed": bool
	}

We'd also need to update the ImageRegistry to allow to "throw" an error or not:

type ImageRegistry struct {
	Reference string `json:"reference"`
	JMESPath string `json:"jmesPath,omitempty"`
	ImageRegistryCredentials *ImageRegistryCredentials `json:"imageRegistryCredentials,omitempty"`
    
    // NEW, default = false, if true => add error to 
    CatchError bool `json:"catchError"`
}

Taking the previous condition, the Policy would look like:

# Policy
context:
  - name: imageData
    imageRegistry:
      reference: "{{ request.object.spec.containers[0].image }}"
      catchError: true # NEW
preconditions:
  all:
    - key: "{{ imageData.resolvedImage.failed }}"
      operator: NotEquals
      value: true
    - key: "{{ imageData.resolvedImage.error || '' }}"
      operator: Equals
      value: "failed to fetch image descriptor"

Alternatives

No response

Additional Context

This comes from a discussion with a user that wants kyverno to avoid creating failed events for missing images in his cluster.

Slack discussion

https://kubernetes.slack.com/archives/CLGR9BJU9/p1761278541835169

Research

  • I have read and followed the documentation AND the troubleshooting guide.
  • I have searched other issues in this repository and mine is not recorded.