ImageValidatingPolicy

Validate container images and their metadata

The Kyverno ImageValidatingPolicy type is a Kyverno policy type designed for verifying container image signatures and attestations.

Additional Fields

The ImageValidatingPolicy extends the Kyverno ValidatingPolicy with the following additional fields for image verification features. A complete reference is provided in the API specification

images

When Kubernetes resources are evaluated images for pods and pod templates are automatically extracted for processing. For custom resources, or for JSON payloads, the images field can be used to declare CEL expressions that extract images from the payload.

For example, this policy declaration will process the image specified in the imageReference field:

 1apiVersion: policies.kyverno.io/v1alpha1
 2kind: ImageValidatingPolicy
 3metadata:
 4  name: sample
 5spec:
 6  evaluation:
 7    mode: JSON
 8  images:
 9    - name: imagerefs
10      expression: "[object.imageReference]"
11  ...

imageRules

The spec.imageRules field defines rules for matching container images. It allows specifying glob patterns or CEL expressions that specify which images the policy should match.

1apiVersion: policies.kyverno.io/v1alpha1
2kind: ImageValidatingPolicy
3metadata:
4  name: check-images
5spec:
6  imageRules:
7    - glob: "ghcr.io/kyverno/*"        # Match images using glob pattern
8    - cel: "image.registry == 'ghcr.io'"  # Match using CEL expression
9  ...

attestors

The attestors field declares trusted signing authorities, such as keys or certificates.

Cosign attestors: These use public keys, keyless signing, transparency logs, certificates, or TUF-based metadata for image validation.

 1apiVersion: policies.kyverno.io/v1alpha1
 2kind: ImageValidatingPolicy
 3metadata:
 4  name: check-images
 5spec:
 6  matchConstraints:
 7    resourceRules:
 8      - apiGroups: [""]
 9        apiVersions: ["v1"]
10        operations: ["CREATE"]
11        resources: ["pods"]
12  attestors:
13  - name: cosign                      # A unique name to identify this attestor
14    cosign:
15      key:                            # Public key-based verification
16        secretRef:                    # Reference to a Kubernetes secret that holds the cosign public key
17          name: cosign-pubkey-secret
18          namespace: kyverno
19        kms: "gcpkms://..."           # KMS URI for key verification (e.g., GCP KMS, AWS KMS)
20        hashAlgorithm: "sha256"       # Optional hash algorithm used with the key
21        data: |                       # Direct inline public key data (optional if secretRef or kms is used)
22          -----BEGIN PUBLIC KEY-----
23          ...
24          -----END PUBLIC KEY-----
25
26      keyless:                        # Keyless signing verification (OIDC-based)
27        identities:                   # List of accepted signing identities
28          - subject: "https://github.com/myorg/myrepo/.github/workflows/deploy.yaml@refs/heads/main"
29            issuer: "https://token.actions.githubusercontent.com"
30            subjectRegExp: ".*github\\.com/.*/.*/.github/workflows/.*"  # Optional regex for subject matching
31            issuerRegExp: "https://token\\.actions\\.githubusercontent\\.com"  # Optional regex for issuer matching
32        root: |                       # Roots is an optional set of PEM encoded trusted root certificates. If not provided, the system roots are used.
33            -----BEGIN CERTIFICATE-----
34            ...
35            -----END CERTIFICATE-----
36
37      ctlog:                          # Transparency log settings (e.g., Rekor)
38        url: "https://rekor.sigstore.dev"
39        rekorPubKey: |                # Public key for verifying Rekor entries
40          -----BEGIN PUBLIC KEY-----
41          ...
42          -----END PUBLIC KEY-----
43        ctLogPubKey: |                # Public key for verifying CT log entries (optional)
44          -----BEGIN PUBLIC KEY-----
45          ...
46          -----END PUBLIC KEY-----
47        tsaCertChain: |              # Certificate chain for Time Stamp Authority (optional)
48          -----BEGIN CERTIFICATE-----
49          ...
50          -----END CERTIFICATE-----
51        insecureIgnoreTlog: false     # Skip TLog verification (for testing only)
52        insecureIgnoreSCT: false      # Skip Signed Certificate Timestamp (for testing only)
53
54      certificate:                    # Certificate-based verification
55        cert: |                       # Inline signing certificate
56          -----BEGIN CERTIFICATE-----
57          ...
58          -----END CERTIFICATE-----
59        certChain: |                 # Certificate chain associated with the signer
60          -----BEGIN CERTIFICATE-----
61          ...
62          -----END CERTIFICATE-----
63
64      source:                         # Optional metadata to constrain image source (optional)
65        repository: "ghcr.io/myorg/myimage"   # Limit to specific image repo
66        pullSecrets:                  # Kubernetes secrets used to access the registry
67          - name: my-registry-secret
68        tagPrefix: "v1."              # Restrict verification to images starting with this tag
69
70      tuf: 
71        root:
72          path: "/var/run/tuf/root.json"  # Local path to TUF root metadata (optional)
73          data: |                         # Optional base64-encoded TUF root metadata (optional)
74            eyJzaWduZWQiOiB7Li4ufSwgInNpZ25hdHVyZXMiOiBbLi4uXX0=
75        mirror: "https://tuf.example.org" # Sigstore TUF mirror URL (optional)
76
77  ...

Notary attestors: These use certificates and optional Time Stamp Authority (TSA) certificates for image signature verification.

 1apiVersion: policies.kyverno.io/v1alpha1
 2kind: ImageValidatingPolicy
 3metadata:
 4  name: check-images
 5spec:
 6  matchConstraints:
 7    resourceRules:
 8      - apiGroups: [""]
 9        apiVersions: ["v1"]
10        operations: ["CREATE"]
11        resources: ["pods"]
12  imageRules:
13    - glob: ghcr.io/*                         
14  attestors:
15        - name: notary                        # Unique identifier for this attestor
16          notary:
17            certs: |                          # Certificate(s) used to verify the signature
18              -----BEGIN CERTIFICATE-----
19              MIIBjTCCATOgAwIBAgIUdMiN3gC...
20              -----END CERTIFICATE-----
21            tsaCerts: |                       # Optional: Time Stamp Authority (TSA) certificates
22              -----BEGIN CERTIFICATE-----
23              MIIC4jCCAcqgAwIBAgIQAm3T2tWk...
24              -----END CERTIFICATE-----

attestations

The attestations field specifies additional metadata to validate.

 1apiVersion: policies.kyverno.io/v1alpha1
 2kind: ImageValidatingPolicy
 3metadata:
 4  name: check-images
 5spec:
 6  matchConstraints:
 7    resourceRules:
 8      - apiGroups: [""]
 9        apiVersions: ["v1"]
10        operations: ["CREATE"]
11        resources: ["pods"]
12  imageRules:
13    - glob: ghcr.io/*
14  attestors:
15        - name: notary
16          notary:
17            certs: |-
18              -----BEGIN CERTIFICATE-----
19              MIIBjTCCATOgAwIBAgIUdMiN3gC...
20              -----END CERTIFICATE-----
21  attestations:
22    - name: sbom                                # Logical name for this attestation
23      referrer:                                 # Uses OCI artifact type for verification
24        type: sbom/cyclone-dx                   
25
26    - name: toto                                # Another attestation named `toto`
27      intoto:
28        type: https://example.com/attestations/slsa-provenance/v0.2  # Predicate type URI for in-toto format

mutateDigest

The mutateDigest field enables, or disables, mutating the image reference to replace the tag with a digest. Image tags are mutable and as a best practice digests should be used prior to deployment.

verifyDigest

The verifyDigest field enables, or disables, verification that all matching images are using a digest.

required

The required field enables, or disables, a check that all images must be validated by one or more policies.

 1apiVersion: policies.kyverno.io/v1alpha1
 2kind: ImageValidatingPolicy
 3metadata:
 4  name: check-images
 5spec:
 6  imageRules:
 7    - glob: ghcr.io/*
 8  mutateDigest: true
 9  required: true
10  verifyDigest: true

credentials

Credentials specify the authentication information required to securely access and interact with a registry.

 1apiVersion: policies.kyverno.io/v1alpha1
 2kind: ImageValidatingPolicy
 3metadata:
 4  name: check-images
 5spec:
 6  imageRules:
 7    - glob: ghcr.io/*
 8  credentials:
 9    allowInsecureRegistry: false  # Deny insecure access to registries
10    providers: # specifies whose authentication providers are provided
11      - "default"  
12      - "google"   
13      - "azure"    
14      - "amazon"
15      - "github"
16
17    secrets:
18      - "my-registry-secret"  # Secrets specifies a list of secrets that are provided for credentials. Secrets must live in the Kyverno namespace.

Kyverno CEL Libraries

Kyverno enhances Kubernetes’ CEL environment with libraries enabling complex policy logic and advanced features for image validation. In addition to common Kyverno CEL Libraries the following additional libraries are supported for ImageValidatingPolicy types.

Image Verification Library

Kyverno provides specialized functions for verifying image signatures and attestations:

CEL ExpressionPurpose
images.containersRetrieves all container images in the resource
verifyImageSignatures(image, [attestors.notary])Verify image signatures using specified attestors
verifyAttestationSignatures(image, attestations.sbom, [attestors.notary])Verify attestation signatures for specific metadata
payload(image, attestations.sbom).bomFormat == 'CycloneDX'Extract the in-toto payload

The following policy demonstrates the use of these functions:

 1apiVersion: policies.kyverno.io/v1alpha1
 2kind: ImageValidatingPolicy
 3metadata:
 4  name: check-images
 5spec:
 6  matchConstraints:
 7    resourceRules:
 8      - apiGroups: [""]
 9        apiVersions: ["v1"]
10        operations: ["CREATE"]
11        resources: ["pods"]
12  imageRules:
13    - glob: ghcr.io/*
14      attestors:
15        - name: notary
16          notary:
17            certs: |-
18              -----BEGIN CERTIFICATE-----
19              ...
20              -----END CERTIFICATE-----
21      attestations:
22        - name: sbom
23          referrer:
24            type: sbom/cyclone-dx
25  validations:
26    - expression: >-
27        images.containers.map(image, verifyImageSignatures(image, [attestors.notary])).all(e, e > 0)
28      message: failed to verify image with notary cert
29    - expression: >-
30        images.containers.map(image, verifyAttestationSignatures(image, 
31           attestations.sbom, [attestors.notary])).all(e, e > 0)
32      message: failed to verify attestation with notary cert
33    - expression: >-
34        images.containers.map(image, payload(image, attestations.sbom).bomFormat == 'CycloneDX').all(e, e)
35      message: sbom is not a cyclone dx sbom

This policy ensures that:

  1. All images are signed by the specified notary attestor
  2. All images have valid SBOM attestations
  3. All SBOMs are in CycloneDX format

Cosign Keyless Signature and Attestation Verification

This sample policy demonstrates how to verify container image signatures using Cosign keyless signing and validate the presence of a vulnerability scan attestation.

Kyverno supports the use of regular expressions in identities.subjectRegExp and identities.issuerRegExp fields when configuring keyless attestors

 1apiVersion: policies.kyverno.io/v1alpha1
 2kind: ImageValidatingPolicy
 3metadata:
 4  name: require-vulnerability-scan
 5spec:
 6  validationActions: [Audit]
 7  webhookConfiguration:
 8    timeoutSeconds: 15
 9  failurePolicy: Fail
10  matchConstraints:
11    resourceRules:
12      - apiGroups: [""]
13        apiVersions: ["v1"]
14        resources: ["pods"]
15        operations: ["CREATE", "UPDATE"]
16  imageRules:
17    - glob: "ghcr.io/myorg/myrepo:*"
18  attestors:
19    - name: cosign
20      cosign:
21          keyless:
22            identities:
23              - subject: "https://github.com/myorg/myrepo/.github/workflows/*"
24                issuer: "https://token.actions.githubusercontent.com"
25          ctlog:
26               url: "https://rekor.sigstore.dev"
27  attestations:
28   - name: cosign-attes
29     intoto:
30       type: cosign.sigstore.dev/attestation/vuln/v1
31  validations:
32    - expression: >-
33        images.containers.map(image, verifyImageSignatures(image,  [attestors.cosign])).all(e, e > 0)
34      message: "Failed image signature verification"
35    - expression: >-
36        images.containers.map(image, verifyAttestationSignatures(image, [attestations.cosign-attes], [attestors.cosign])).all(e, e > 0)
37      message: "Failed to verify vulnerability scan attestation with Cosign keyless"

Cosign Public Key Signature Verification

This policy ensures that container images are signed with a specified Cosign public key before being admitted.

 1apiVersion: policies.kyverno.io/v1alpha1
 2kind: ImageValidatingPolicy
 3metadata:
 4  name: verify-image-ivpol
 5spec:
 6  webhookConfiguration:
 7    timeoutSeconds: 15
 8  evaluation:
 9   background:
10    enabled: false
11  validationActions: [Deny]
12  matchConstraints:
13    resourceRules:
14      - apiGroups: [""]
15        apiVersions: ["v1"]
16        operations: ["CREATE", "UPDATE"]
17        resources: ["pods"]
18  imageRules:
19        - glob : "docker.io/kyverno/kyverno*"
20  mutateDigest: true
21  attestors:
22  - name: cosign
23    cosign:
24     key:
25      data: |
26                -----BEGIN PUBLIC KEY-----
27                MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE6QsNef3SKYhJVYSVj+ZfbPwJd0pv
28                DLYNHXITZkhIzfE+apcxDjCCkDPcJ3A3zvhPATYOIsCxYPch7Q2JdJLsDQ==
29                -----END PUBLIC KEY-----
30  validations:
31    - expression: >-
32       images.containers.map(image, verifyImageSignatures(image, [attestors.cosign])).all(e ,e > 0)
33      message: >-
34       failed the image Signature verification

Note: To learn how to sign container images using Cosign with keyless signing, refer to the official Cosign documentation.


Last modified April 18, 2025 at 4:24 PM PST: chore: cosmetic updates for ivpol and vpol (#1530) (8fa097f)