Repository: kyverno/kyverno
Pull request #13168: chore: Add exception tests for image validating policies
Author: login: arnabnandikgp
Labels: name: cherry-pick-required
name: cherry-pick-completed
description: The PR was cherry-picked (or merged) to required release branches
name: size:XL
description: This PR changes 500-999 lines, ignoring generated files.
Created: 2025-05-16T17:13:06Z | Merged: 2025-05-20T07:48:04Z

## Explanation

<!--
In a couple sentences, explain why this PR is needed and what it addresses. This should be an explanation a non-developer user can understand and covers the "why" question. It should also clearly indicate whether this PR represents an addition, a change, or a fix of existing behavior. This explanation will be used to assist in the release note drafting process.

THIS IS MANDATORY.
-->

## Related issue

<!--
Please link the GitHub issue this pull request resolves in the format of `Closes #1234`. If you discussed this change
with a maintainer, please mention her/him using the `@` syntax (e.g. `@JimBugwadia`).

If this change neither resolves an existing issue nor has sign-off from one of the maintainers, there is a
chance substantial changes will be requested or that the changes will be rejected.

You can discuss changes with maintainers in the [Kyverno Slack Channel](https://kubernetes.slack.com/).
-->

## Milestone of this PR
<!--

Add the milestone label by commenting `/milestone 1.2.3`.

-->

## Documentation (required for features)

My PR contains new or altered behavior to Kyverno. 
- [ ] I have sent the draft PR to add or update [the documentation](https://github.com/kyverno/website) and the link is:
  <!-- Uncomment to link to the PR -->
  <!-- https://github.com/kyverno/website/pull/123 -->

## What type of PR is this

<!--

> Uncomment only one ` /kind <>` line, hit enter to put that in a new line, and remove leading white spaces from that line:
>
> /kind api-change
> /kind bug
> /kind cleanup
> /kind design
> /kind documentation
> /kind failing-test
> /kind feature
-->

## Proposed Changes

<!--
Describe the big picture of your changes here to communicate to the maintainers why we should accept this pull request. 

***NOTE***: If this PR results in new or altered behavior which is user facing, you **MUST** read and follow the steps outlined in the [PR documentation guide](pr_documentation.md) and add Proof Manifests as defined below.
-->

### Proof Manifests

<!--
Read and follow the [PR documentation guide](https://github.com/kyverno/kyverno/blob/main/.github/pr_documentation.md) for more details first. This section is for pasting your YAML manifests (Kubernetes resources and Kyverno policies) and Kyverno CLI test manifests which allow maintainers to prove the intended functionality is achieved by your PR. Please use proper fenced code block formatting, for example:

# Kubernetes resource

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: roles-dictionary
  namespace: default
data:
  allowed-roles: "[\"cluster-admin\", \"cluster-operator\", \"tenant-admin\"]"
```

# Kyverno CLI test manifest (please see docs for latest manifest format at https://kyverno.io/docs/kyverno-cli/). See kyverno/policies for complete examples of all related test files.

```yaml
name: prepend-image-registry
policies:
  - prepend_image_registry.yaml
resources:
  - resource.yaml
variables: values.yaml
results:
  - policy: prepend-registry
    rule: prepend-registry-containers
    resource: mypod
    # if mutate rule
    patchedResource: patchedResource01.yaml
    kind: Pod
    result: pass
```
-->

## Checklist

<!--
Put an `x` in the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of
them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your code.
-->

- [ ] I have read the [contributing guidelines](https://github.com/kyverno/kyverno/blob/main/CONTRIBUTING.md).
- [ ] I have read the [PR documentation guide](https://github.com/kyverno/kyverno/blob/main/.github/pr_documentation.md) and followed the process including adding proof manifests to this PR.
- [ ] This is a bug fix and I have added unit tests that prove my fix is effective.
- [ ] This is a feature and I have added CLI tests that are applicable.
- [ ] My PR needs to be cherry picked to a specific release branch which is <replace>.
- [ ] My PR contains new or altered behavior to Kyverno and
  - [ ] CLI support should be added and my PR doesn't contain that functionality.

## Further Comments

<!--
If this is a relatively large or complex change, kick off the discussion by explaining why you chose the solution
you did and what alternatives you considered, etc...
-->


Linked issue #1234: [BUG] Error reporting for openAPISchema validation
**Describe the bug**
Per [this](https://github.com/kyverno/kyverno/issues/954#issuecomment-722015854) discussion, Kyverno keeps logging errors when a CRD does not have openAPI schema defined.

>Kyverno should have a mode where we can quiet this down in some way.. or it should simply not fail here.

We should turn the error log into a leveled info log, only log out the error during the policy validation - when a policy is defined on a custom resource that does not have openAPISchema.

Linked issue comments: user: login: realshuting
created_at: 2020-11-12T19:03:00Z
body: Related issue reported in Kyverno Slack: https://kubernetes.slack.com/archives/CLGR9BJU9/p1605207195190800?thread_ts=1605191779.161900&cid=CLGR9BJU9
author_association: MEMBER
user: login: Raboldar
created_at: 2020-11-12T21:48:05Z
body: I get a similar error : 
```
[60]\n\nValidationError(org.projectcalico.crd.v1.IPAMBlock.spec.allocations): unknown object type \"nil\" in org.projectcalico.crd.v1.IPAMBlock.spec.allocations[61]\n\nValidationError(org.projectcalico.crd.v1.IPAMBlock.spec.allocations): unknown object type \"nil\" in org.projectcalico.crd.v1.IPAMBlock.spec.allocations[62]\n\nValidationError(org.projectcalico.crd.v1.IPAMBlock.spec.allocations): unknown object type \"nil\" in org.projectcalico.crd.v1.IPAMBlock.spec.allocations[63]" "action"="mutate" "operation"="UPDATE" "resource"="IPAMBlock/192-168-86-0-26" "policy"="insert-container"
I1112 20:43:33.501452       1 mutation.go:78] WebhookServer "msg"="mutation rules from policy applied successfully" "action"="mutate" "operation"="UPDATE" "resource"="default/Deployment/hello-kube" "policy"="insert-container" "rules"=["insert-container"]
```
I'm trying to deploy the following: 
```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-kube 
  labels:
    app: bar 
    service: front 
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-kube
      service: front 
  template:
    metadata:
      labels:
        app: hello-kube  
        service: front 
    spec:
      containers:
      - name: hello-kube 
        image: paulbouwer/hello-kubernetes:1.8
        ports:
        - containerPort: 8080
          name: http 
```
This is the Kyverno policy that i applied previously:
```
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: kyverno-admin-generate
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: kyverno:generatecontroller # clusterRole defined above, to manage generated resources
subjects:
- kind: ServiceAccount
  name: kyverno-service-account # default kyverno serviceAccount
  namespace: kyverno
```
```
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: insert-container
spec:
  rules:
    - name: insert-container
      match:
        resources:
          kinds:
          - Deployment
      mutate:
        overlay:
          spec:
            template:
              spec:
                topologySpreadConstraints:
                - maxSkew: 1
                  topologyKey: topology.psud.nc/datacenter 
                  whenUnsatisfiable: DoNotSchedule
                  labelSelector:
                    matchLabels:
                      app: bar
```
Calico :
The pods get an IP and can communicate. 

author_association: NONE
user: login: kacejot
created_at: 2021-02-18T00:32:32Z
body: I see three possible ways to resolve it:
- We could leave the things as they are.
    Pros: we keep compatibility with openapi standards without adding specific validation for 3rd-party CRDs. And we don't need to do anything.
    Cons: 3rd-party CRD that violate openAPI will have error on validation.
- We could change logging logic as Shuting proposes.
    Pros/Cons: specific 3rd-party CRD support, which is good for audience coverage, but not product architecture.
    Pros: Easy to do.
- We could change validation logic by adding support of 3rd party CRD right there.
    Pros: specific 3rd-party CRD support
    Cons: Complex task;

Personally I like the second way, where the logging process should be updated.
I will look more at alternatives and comment back.
author_association: CONTRIBUTOR
user: login: JimBugwadia
created_at: 2021-02-19T17:30:34Z
body: @kacejot - this sounds good to me. Please proceed.
author_association: MEMBER
user: login: kacejot
created_at: 2021-02-23T02:44:45Z
body: After additional research I came up with oneliner solution. I have implemented it and started testing.
I have set up calico over my cluster and its CRD already had OpenAPIv3 schema, so I wasn't able to reproduce this issue anymore. When I tried to recreate old CRD without OpenAPIv3 schema, Kubernetes declined my try saying:
```
The CustomResourceDefinition "globalnetworkpolicies.crd.projectcalico.org" is invalid: 
* spec.versions[0].schema.openAPIV3Schema: Required value: schemas are required
```

But anyway, the problem was that Kyverno tried to validate the resource with empty schema. I have added check for this case. I will push my changes to separate branch, but there is no sense to merge it until we have stable reproduce. I will try to downgrade my Kubernetes version to November 2020 and try again.
author_association: CONTRIBUTOR
user: login: JimBugwadia
created_at: 2021-02-23T05:36:52Z
body: @kacejot - Calico was one example but seems like we would have this issue anytime a CRD does not have openAPI schema defined, right?
author_association: MEMBER
user: login: realshuting
created_at: 2021-02-23T06:50:21Z
body: @kacejot check this comment - https://github.com/kyverno/kyverno/issues/1234#issuecomment-726276476, `HelmRelease` is another CRD that we can use to reproduce the issue.
author_association: MEMBER
user: login: kacejot
created_at: 2021-02-25T00:13:39Z
body: cc: @realshuting @JimBugwadia 

I have installed Helm Operator (without flux) and wrote [some instructions](https://github.com/kyverno/kyverno/wiki/How-to-install-Helm-Operator) how to do this, because I was encountering lots of difficulties and it should help someone who want to reproduce this issue.

So, I have added HelmRelease custom resource much like it is described in [slack thread]( https://kubernetes.slack.com/archives/CLGR9BJU9/p1605207195190800?thread_ts=1605191779.161900&cid=CLGR9BJU9):
```yaml
apiVersion: helm.fluxcd.io/v1
kind: HelmRelease
metadata:
  name: azure-arc-sample
  namespace: default
spec:
  releaseName: arc-k8s-demo
  chart:
    git: https://github.com/Azure/arc-helm-demo
    ref: master
    path: charts/azure-arc-sample
  values:
    serviceName: arc-k8s-demo
```
Also I created the same policy as is in the thread:
```yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata: 
  name: add-labels
spec: 
  background: false
  rules:
  - name: add-ns-label
    match:
      resources:
        kinds:
        - Namespace
        name: "epi-*"
    mutate:
      patchStrategicMerge:
        metadata:
          labels:
            name: "{{ request.object.metadata.name }}"
```
And created sample namespace:
```
kubectl create namespace epi-sample
```
All worked fine and there is no errors in logs.
author_association: CONTRIBUTOR
user: login: JimBugwadia
created_at: 2021-03-02T16:15:43Z
body: @realshuting are you able to reproduce this?
author_association: MEMBER
user: login: realshuting
created_at: 2021-03-02T19:49:41Z
body: No I cannot reproduce the issue with `HelmRelease`.

We had suppressed the error log in [this](https://github.com/kyverno/kyverno/pull/1255/files#diff-51a43f2d1bdcedd38e4b4b122ed9bda070cdbbc3ce65ed04f87b88f13646b065R69) PR, if I apply [`machinehealthchecks.cluster.x-k8s.io`](https://github.com/kyverno/kyverno/issues/954#issue-645905828), I can see the error in level 4:
```
I0302 19:38:38.852973       1 mutation.go:77] WebhookServer "msg"="validation error" "action"="mutate" "operation"="UPDATE" "resource"="CustomResourceDefinition/machinehealthchecks.cluster.x-k8s.io" "error"="ValidationError(io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceDefinition.spec.conversion): unknown field \"webhook\" in io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceConversion\n\nValidationError(io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceDefinition.spec.versions[0].additionalPrinterColumns[0]): unknown field \"jsonPath\" in io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceColumnDefinition\n\nValidationError(io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceDefinition.spec.versions[0].additionalPrinterColumns[0]): missing required field \"JSONPath\" in io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceColumnDefinition\n\nValidationError(io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceDefinition.spec.versions[0].additionalPrinterColumns[1]): unknown field \"jsonPath\" in io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceColumnDefinition\n\nValidationError(io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceDefinition.spec.versions[0].additionalPrinterColumns[1]): missing required field \"JSONPath\" in io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceColumnDefinition\n\nValidationError(io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceDefinition.spec.versions[0].additionalPrinterColumns[2]): unknown field \"jsonPath\" in io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceColumnDefinition\n\nValidationError(io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceDefinition.spec.versions[0].additionalPrinterColumns[2]): missing required field \"JSONPath\" in io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceColumnDefinition" "policy"="add-labels"
```

We still need to -
>log out the error during the policy validation - when a policy is defined on the custom resource that does not have openAPISchema.
author_association: MEMBER
user: login: JimBugwadia
created_at: 2021-03-19T05:33:07Z
body: @kacejot - are you planning on submitting a PR for this?
author_association: MEMBER
user: login: kacejot
created_at: 2021-03-19T17:43:08Z
body: @JimBugwadia, not for the current release. I was working on other issues. I think I will apply Shuting's comments on the next release
author_association: CONTRIBUTOR
user: login: realshuting
created_at: 2021-03-22T22:19:29Z
body: >log out the error during the policy validation - when a policy is defined on the custom resource that does not have openAPISchema.

It seems we already do it - https://github.com/kyverno/kyverno/issues/1218#issuecomment-799734944:
```
E0315 19:48:52.649398       1 crdSync.go:146]  "msg"="could not parse crd schema" "error"="crd schema has no properties"  "name"="Task"
```

author_association: MEMBER
user: login: realshuting
created_at: 2021-03-22T22:19:54Z
body: Closing this issue.
Please feel free to reopen if this can be reproduced.
author_association: MEMBER
user: login: awoodobvio
created_at: 2022-01-23T21:44:27Z
body: @realshuting 

We are seeing something similar to this with version 1.5.3 and the "IstioOperator" crd.  Not sure if this warrants opening the bug again, but I found this while searching for some way to suppress the log output and it seems related.  We have no policies running against IstioOperator or CRD objects in the cluster.

That has a schema that looks like this:

``` yaml
schema:
      openAPIV3Schema:
        type: object
        x-kubernetes-preserve-unknown-fields: true
```

This results in the following log message being continuously sent:

``` log
E0123 21:43:14.364473       1 crdSync.go:179]  "msg"="could not parse crd schema" "error"="crd schema has no properties" "name"="IstioOperator"
```

**Entire CRD definition is below:**

``` yaml
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  annotations:
  labels:
    release: istio
  name: istiooperators.install.istio.io
spec:
  conversion:
    strategy: None
  group: install.istio.io
  names:
    kind: IstioOperator
    listKind: IstioOperatorList
    plural: istiooperators
    shortNames:
    - iop
    - io
    singular: istiooperator
  scope: Namespaced
  versions:
  - additionalPrinterColumns:
    - description: Istio control plane revision
      jsonPath: .spec.revision
      name: Revision
      type: string
    - description: IOP current state
      jsonPath: .status.status
      name: Status
      type: string
    - description: 'CreationTimestamp is a timestamp representing the server time
        when this object was created. It is not guaranteed to be set in happens-before
        order across separate operations. Clients may not set this value. It is represented
        in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for
        lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata'
      jsonPath: .metadata.creationTimestamp
      name: Age
      type: date
    name: v1alpha1
    schema:
      openAPIV3Schema:
        type: object
        x-kubernetes-preserve-unknown-fields: true
    served: true
    storage: true
    subresources:
      status: {}
```

author_association: NONE
user: login: JimBugwadia
created_at: 2022-01-24T02:57:43Z
body: Is this reproducible with 1.6.x? I believe it was fixed, but would be good to verify.
author_association: MEMBER

Diff:
diff --git a/test/conformance/chainsaw/image-validating-policies/exceptions/autogen/README.md b/test/conformance/chainsaw/image-validating-policies/exceptions/autogen/README.md
new file mode 100644
index 000000000000..44e7ddb0955b
--- /dev/null
+++ b/test/conformance/chainsaw/image-validating-policies/exceptions/autogen/README.md
@@ -0,0 +1,11 @@
+## Description
+
+The policy contains autogen rules for cronjobs, deployments and statefulsets.
+The policy enforces tighter security context by disallowing privilege escalation for containers.
+The exception helps to bypass the policy for resources marked as "skipped" which are configured to violate the policy.
+
+## Expected Behavior
+
+The good deployment should pass regardless as it satisfies the requirement of the policy.
+The bad deployment should be blocked as per the policy.
+The skipped deployment should get skipped due to enforcement of the policyexception.
diff --git a/test/conformance/chainsaw/image-validating-policies/exceptions/autogen/bad-resources.yaml b/test/conformance/chainsaw/image-validating-policies/exceptions/autogen/bad-resources.yaml
new file mode 100644
index 000000000000..af0042f47cb1
--- /dev/null
+++ b/test/conformance/chainsaw/image-validating-policies/exceptions/autogen/bad-resources.yaml
@@ -0,0 +1,74 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: bad-deployment
+  labels:
+    prod: "true"
+    app: bad-nginx
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      prod: "true"
+      app: bad-nginx
+  template:
+    metadata:
+      labels:
+        prod: "true"
+        app: bad-nginx
+    spec:
+      containers:
+      - name: nginx
+        image: ghcr.io/kyverno/test-verify-image:unsigned
+        securityContext:
+          allowPrivilegeEscalation: true
+---
+apiVersion: batch/v1
+kind: CronJob
+metadata:
+  name: bad-cronjob  
+spec:
+  schedule: "*/5 * * * *"  
+  concurrencyPolicy: Forbid  
+  jobTemplate:
+    metadata:
+      labels:
+        prod: "true"  
+    spec:
+      template:
+        metadata:
+          labels:
+            prod: "true"  
+        spec:
+          containers:
+          - name: secure-container  
+            image: ghcr.io/kyverno/test-verify-image:unsigned
+            command: ["echo", "Hello, world"]  
+            securityContext:
+              allowPrivilegeEscalation: true 
+          restartPolicy: OnFailure  
+---
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+  name: bad-statefulset
+  labels:
+    prod: "true"
+spec:
+  serviceName: my-app-service
+  replicas: 3
+  selector:
+    matchLabels:
+      prod: "true"
+      app: busybox
+  template:
+    metadata:
+      labels:
+        prod: "true"
+        app: busybox
+    spec:
+      containers:
+      - name: my-app-container
+        image: ghcr.io/kyverno/test-verify-image:unsigned
+        securityContext:
+          allowPrivilegeEscalation: true
\ No newline at end of file
diff --git a/test/conformance/chainsaw/image-validating-policies/exceptions/autogen/chainsaw-test.yaml b/test/conformance/chainsaw/image-validating-policies/exceptions/autogen/chainsaw-test.yaml
new file mode 100644
index 000000000000..290553068fe2
--- /dev/null
+++ b/test/conformance/chainsaw/image-validating-policies/exceptions/autogen/chainsaw-test.yaml
@@ -0,0 +1,46 @@
+# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json
+apiVersion: chainsaw.kyverno.io/v1alpha1
+kind: Test
+metadata:
+  name: autogen-deployments-cronjobs-statefulsets
+spec:
+  steps:
+  - name: create exception
+    try:
+    - create:
+        file: exception.yaml
+    - sleep:
+        duration: 10s
+  - name: create policy
+    use:
+      template: ../../../_step-templates/create-policy.yaml
+      with:
+        bindings:
+        - name: file
+          value: policy.yaml
+  - name: wait policy ready
+    use:
+      template: ../../../_step-templates/image-validating-policy-ready.yaml
+      with:
+        bindings:
+        - name: name
+          value: ivpol-autogen-sample
+  - name: check autogen policy
+    try:
+    - assert:
+        file: check-autogen.yaml
+  - name: create bad resources
+    try:
+    - create:
+        file: bad-resources.yaml
+        expect:
+          - check:
+              ($error != null): true
+  - name: create good resources
+    try:
+    - create:
+        file: good-resources.yaml
+  - name: create skipped resources
+    try:
+    - create:
+        file: skipped-resources.yaml
diff --git a/test/conformance/chainsaw/image-validating-policies/exceptions/autogen/check-autogen.yaml b/test/conformance/chainsaw/image-validating-policies/exceptions/autogen/check-autogen.yaml
new file mode 100644
index 000000000000..562974fcd17a
--- /dev/null
+++ b/test/conformance/chainsaw/image-validating-policies/exceptions/autogen/check-autogen.yaml
@@ -0,0 +1,155 @@
+apiVersion: policies.kyverno.io/v1alpha1
+kind: ImageValidatingPolicy
+metadata:
+    name: ivpol-autogen-sample
+status:
+  autogen:
+    configs:
+      defaults-ivpol-autogen-sample:
+        spec:
+          attestations:
+          - name: sbom
+            referrer:
+              type: sbom/cyclone-dx
+          attestors:
+          - name: notary
+            notary:
+              certs:
+                value: |-
+                  -----BEGIN CERTIFICATE-----
+                  MIIDTTCCAjWgAwIBAgIJAPI+zAzn4s0xMA0GCSqGSIb3DQEBCwUAMEwxCzAJBgNV
+                  BAYTAlVTMQswCQYDVQQIDAJXQTEQMA4GA1UEBwwHU2VhdHRsZTEPMA0GA1UECgwG
+                  Tm90YXJ5MQ0wCwYDVQQDDAR0ZXN0MB4XDTIzMDUyMjIxMTUxOFoXDTMzMDUxOTIx
+                  MTUxOFowTDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0
+                  dGxlMQ8wDQYDVQQKDAZOb3RhcnkxDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3
+                  DQEBAQUAA4IBDwAwggEKAoIBAQDNhTwv+QMk7jEHufFfIFlBjn2NiJaYPgL4eBS+
+                  b+o37ve5Zn9nzRppV6kGsa161r9s2KkLXmJrojNy6vo9a6g6RtZ3F6xKiWLUmbAL
+                  hVTCfYw/2n7xNlVMjyyUpE+7e193PF8HfQrfDFxe2JnX5LHtGe+X9vdvo2l41R6m
+                  Iia04DvpMdG4+da2tKPzXIuLUz/FDb6IODO3+qsqQLwEKmmUee+KX+3yw8I6G1y0
+                  Vp0mnHfsfutlHeG8gazCDlzEsuD4QJ9BKeRf2Vrb0ywqNLkGCbcCWF2H5Q80Iq/f
+                  ETVO9z88R7WheVdEjUB8UrY7ZMLdADM14IPhY2Y+tLaSzEVZAgMBAAGjMjAwMAkG
+                  A1UdEwQCMAAwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0G
+                  CSqGSIb3DQEBCwUAA4IBAQBX7x4Ucre8AIUmXZ5PUK/zUBVOrZZzR1YE8w86J4X9
+                  kYeTtlijf9i2LTZMfGuG0dEVFN4ae3CCpBst+ilhIndnoxTyzP+sNy4RCRQ2Y/k8
+                  Zq235KIh7uucq96PL0qsF9s2RpTKXxyOGdtp9+HO0Ty5txJE2txtLDUIVPK5WNDF
+                  ByCEQNhtHgN6V20b8KU2oLBZ9vyB8V010dQz0NRTDLhkcvJig00535/LUylECYAJ
+                  5/jn6XKt6UYCQJbVNzBg/YPGc1RF4xdsGVDBben/JXpeGEmkdmXPILTKd9tZ5TC0
+                  uOKpF5rWAruB5PCIrquamOejpXV9aQA/K2JQDuc0mcKz
+                  -----END CERTIFICATE-----
+          autogen:
+            podControllers:
+              controllers:
+              - deployments
+              - cronjobs
+              - statefulsets
+          failurePolicy: Ignore
+          matchImageReferences:
+          - glob: ghcr.io/*
+          matchConditions:
+          - expression: '!((object.apiVersion == ''apps/v1'' && object.kind ==''Deployment'')
+              || (object.apiVersion == ''apps/v1'' && object.kind ==''StatefulSet''))
+              || (has(object.spec.template.metadata.labels) && has(object.spec.template.metadata.labels.prod)
+              && object.spec.template.metadata.labels.prod == ''true'')'
+            name: autogen-defaults-check-prod-label
+          matchConstraints:
+            resourceRules:
+            - apiGroups:
+              - apps
+              apiVersions:
+              - v1
+              operations:
+              - CREATE
+              resources:
+              - deployments
+              - statefulsets
+          validationActions:
+          - Deny
+          validations:
+          - expression: images.containers.map(image, verifyImageSignatures(image,
+              [attestors.notary])).all(e, e > 0)
+            message: failed to verify image with notary cert
+          - expression: images.containers.map(image, verifyAttestationSignatures(image,
+              attestations.sbom ,[attestors.notary])).all(e, e > 0)
+            message: failed to verify attestation with notary cer
+          - expression: images.containers.map(image, extractPayload(image, attestations.sbom).bomFormat
+              == 'CycloneDX').all(e, e)
+            message: sbom is not a cyclone dx sbom
+          validationConfigurations:
+            mutateDigest: true
+            required: true
+            verifyDigest: true
+          webhookConfiguration:
+            timeoutSeconds: 20
+      cronjobs-ivpol-autogen-sample:
+        spec:
+          attestations:
+          - name: sbom
+            referrer:
+              type: sbom/cyclone-dx
+          attestors:
+          - name: notary
+            notary:
+              certs:
+                value: |-
+                  -----BEGIN CERTIFICATE-----
+                  MIIDTTCCAjWgAwIBAgIJAPI+zAzn4s0xMA0GCSqGSIb3DQEBCwUAMEwxCzAJBgNV
+                  BAYTAlVTMQswCQYDVQQIDAJXQTEQMA4GA1UEBwwHU2VhdHRsZTEPMA0GA1UECgwG
+                  Tm90YXJ5MQ0wCwYDVQQDDAR0ZXN0MB4XDTIzMDUyMjIxMTUxOFoXDTMzMDUxOTIx
+                  MTUxOFowTDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0
+                  dGxlMQ8wDQYDVQQKDAZOb3RhcnkxDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3
+                  DQEBAQUAA4IBDwAwggEKAoIBAQDNhTwv+QMk7jEHufFfIFlBjn2NiJaYPgL4eBS+
+                  b+o37ve5Zn9nzRppV6kGsa161r9s2KkLXmJrojNy6vo9a6g6RtZ3F6xKiWLUmbAL
+                  hVTCfYw/2n7xNlVMjyyUpE+7e193PF8HfQrfDFxe2JnX5LHtGe+X9vdvo2l41R6m
+                  Iia04DvpMdG4+da2tKPzXIuLUz/FDb6IODO3+qsqQLwEKmmUee+KX+3yw8I6G1y0
+                  Vp0mnHfsfutlHeG8gazCDlzEsuD4QJ9BKeRf2Vrb0ywqNLkGCbcCWF2H5Q80Iq/f
+                  ETVO9z88R7WheVdEjUB8UrY7ZMLdADM14IPhY2Y+tLaSzEVZAgMBAAGjMjAwMAkG
+                  A1UdEwQCMAAwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0G
+                  CSqGSIb3DQEBCwUAA4IBAQBX7x4Ucre8AIUmXZ5PUK/zUBVOrZZzR1YE8w86J4X9
+                  kYeTtlijf9i2LTZMfGuG0dEVFN4ae3CCpBst+ilhIndnoxTyzP+sNy4RCRQ2Y/k8
+                  Zq235KIh7uucq96PL0qsF9s2RpTKXxyOGdtp9+HO0Ty5txJE2txtLDUIVPK5WNDF
+                  ByCEQNhtHgN6V20b8KU2oLBZ9vyB8V010dQz0NRTDLhkcvJig00535/LUylECYAJ
+                  5/jn6XKt6UYCQJbVNzBg/YPGc1RF4xdsGVDBben/JXpeGEmkdmXPILTKd9tZ5TC0
+                  uOKpF5rWAruB5PCIrquamOejpXV9aQA/K2JQDuc0mcKz
+                  -----END CERTIFICATE-----
+          autogen:
+            podControllers:
+              controllers:
+              - deployments
+              - cronjobs
+              - statefulsets
+          failurePolicy: Ignore
+          matchImageReferences:
+          - glob: ghcr.io/*
+          matchConditions:
+          - expression: '!((object.apiVersion == ''batch/v1'' && object.kind ==''CronJob''))
+              || (has(object.spec.jobTemplate.spec.template.metadata.labels) && has(object.spec.jobTemplate.spec.template.metadata.labels.prod)
+              && object.spec.jobTemplate.spec.template.metadata.labels.prod == ''true'')'
+            name: autogen-cronjobs-check-prod-label
+          matchConstraints:
+            resourceRules:
+            - apiGroups:
+              - batch
+              apiVersions:
+              - v1
+              operations:
+              - CREATE
+              resources:
+              - cronjobs
+          validationActions:
+          - Deny
+          validations:
+          - expression: images.containers.map(image, verifyImageSignatures(image,
+              [attestors.notary])).all(e, e > 0)
+            message: failed to verify image with notary cert
+          - expression: images.containers.map(image, verifyAttestationSignatures(image,
+              attestations.sbom ,[attestors.notary])).all(e, e > 0)
+            message: failed to verify attestation with notary cer
+          - expression: images.containers.map(image, extractPayload(image, attestations.sbom).bomFormat
+              == 'CycloneDX').all(e, e)
+            message: sbom is not a cyclone dx sbom
+          validationConfigurations:
+            mutateDigest: true
+            required: true
+            verifyDigest: true
+          webhookConfiguration:
+            timeoutSeconds: 20
\ No newline at end of file
diff --git a/test/conformance/chainsaw/image-validating-policies/exceptions/autogen/exception.yaml b/test/conformance/chainsaw/image-validating-policies/exceptions/autogen/exception.yaml
new file mode 100644
index 000000000000..99e42fc387c3
--- /dev/null
+++ b/test/conformance/chainsaw/image-validating-policies/exceptions/autogen/exception.yaml
@@ -0,0 +1,12 @@
+apiVersion: policies.kyverno.io/v1alpha1
+kind: PolicyException
+metadata:
+  name: check-name
+spec:
+  policyRefs:
+    - name: ivpol-autogen-sample
+      kind: ImageValidatingPolicy
+  matchConditions:
+    - name: "check-name"
+      expression: >-
+        object.metadata.name in ['skipped-deployment', 'skipped-cronjob', 'skipped-statefulset']
\ No newline at end of file
diff --git a/test/conformance/chainsaw/image-validating-policies/exceptions/autogen/good-resources.yaml b/test/conformance/chainsaw/image-validating-policies/exceptions/autogen/good-resources.yaml
new file mode 100644
index 000000000000..aec2da1c6ec9
--- /dev/null
+++ b/test/conformance/chainsaw/image-validating-policies/exceptions/autogen/good-resources.yaml
@@ -0,0 +1,74 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: good-deployment
+  labels:
+    prod: "true"
+    app: bad-nginx
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      prod: "true"
+      app: bad-nginx
+  template:
+    metadata:
+      labels:
+        prod: "true"
+        app: bad-nginx
+    spec:
+      containers:
+      - name: nginx
+        image: ghcr.io/kyverno/test-verify-image:signed
+        securityContext:
+          allowPrivilegeEscalation: true
+---
+apiVersion: batch/v1
+kind: CronJob
+metadata:
+  name: good-cronjob  
+spec:
+  schedule: "*/5 * * * *"  
+  concurrencyPolicy: Forbid  
+  jobTemplate:
+    metadata:
+      labels:
+        prod: "true"  
+    spec:
+      template:
+        metadata:
+          labels:
+            prod: "true"  
+        spec:
+          containers:
+          - name: secure-container  
+            image: ghcr.io/kyverno/test-verify-image:signed
+            command: ["echo", "Hello, world"]  
+            securityContext:
+              allowPrivilegeEscalation: true 
+          restartPolicy: OnFailure  
+---
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+  name: good-statefulset
+  labels:
+    prod: "true"
+spec:
+  serviceName: my-app-service
+  replicas: 3
+  selector:
+    matchLabels:
+      prod: "true"
+      app: busybox
+  template:
+    metadata:
+      labels:
+        prod: "true"
+        app: busybox
+    spec:
+      containers:
+      - name: my-app-container
+        image: ghcr.io/kyverno/test-verify-image:signed
+        securityContext:
+          allowPrivilegeEscalation: true
\ No newline at end of file
diff --git a/test/conformance/chainsaw/image-validating-policies/exceptions/autogen/policy.yaml b/test/conformance/chainsaw/image-validating-policies/exceptions/autogen/policy.yaml
new file mode 100644
index 000000000000..aca4d2a1b36c
--- /dev/null
+++ b/test/conformance/chainsaw/image-validating-policies/exceptions/autogen/policy.yaml
@@ -0,0 +1,67 @@
+apiVersion: policies.kyverno.io/v1alpha1
+kind: ImageValidatingPolicy
+metadata:
+  name: ivpol-autogen-sample
+spec:
+  autogen:
+    podControllers:
+      controllers:
+      - deployments
+      - cronjobs
+      - statefulsets
+  webhookConfiguration:
+    timeoutSeconds: 20
+  failurePolicy: Ignore
+  validationActions:
+  - Deny
+  matchConstraints:
+    resourceRules:
+      - apiGroups: [""]
+        apiVersions: ["v1"]
+        operations: ["CREATE"]
+        resources: ["pods"]
+  matchConditions:
+    - name: "check-prod-label"  
+      expression: >- 
+        has(object.metadata.labels) && has(object.metadata.labels.prod) && object.metadata.labels.prod == 'true'
+  matchImageReferences:
+    - glob: ghcr.io/*
+  attestors:
+    - name: notary
+      notary:
+        certs:
+          value: |-
+            -----BEGIN CERTIFICATE-----
+            MIIDTTCCAjWgAwIBAgIJAPI+zAzn4s0xMA0GCSqGSIb3DQEBCwUAMEwxCzAJBgNV
+            BAYTAlVTMQswCQYDVQQIDAJXQTEQMA4GA1UEBwwHU2VhdHRsZTEPMA0GA1UECgwG
+            Tm90YXJ5MQ0wCwYDVQQDDAR0ZXN0MB4XDTIzMDUyMjIxMTUxOFoXDTMzMDUxOTIx
+            MTUxOFowTDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0
+            dGxlMQ8wDQYDVQQKDAZOb3RhcnkxDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3
+            DQEBAQUAA4IBDwAwggEKAoIBAQDNhTwv+QMk7jEHufFfIFlBjn2NiJaYPgL4eBS+
+            b+o37ve5Zn9nzRppV6kGsa161r9s2KkLXmJrojNy6vo9a6g6RtZ3F6xKiWLUmbAL
+            hVTCfYw/2n7xNlVMjyyUpE+7e193PF8HfQrfDFxe2JnX5LHtGe+X9vdvo2l41R6m
+            Iia04DvpMdG4+da2tKPzXIuLUz/FDb6IODO3+qsqQLwEKmmUee+KX+3yw8I6G1y0
+            Vp0mnHfsfutlHeG8gazCDlzEsuD4QJ9BKeRf2Vrb0ywqNLkGCbcCWF2H5Q80Iq/f
+            ETVO9z88R7WheVdEjUB8UrY7ZMLdADM14IPhY2Y+tLaSzEVZAgMBAAGjMjAwMAkG
+            A1UdEwQCMAAwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0G
+            CSqGSIb3DQEBCwUAA4IBAQBX7x4Ucre8AIUmXZ5PUK/zUBVOrZZzR1YE8w86J4X9
+            kYeTtlijf9i2LTZMfGuG0dEVFN4ae3CCpBst+ilhIndnoxTyzP+sNy4RCRQ2Y/k8
+            Zq235KIh7uucq96PL0qsF9s2RpTKXxyOGdtp9+HO0Ty5txJE2txtLDUIVPK5WNDF
+            ByCEQNhtHgN6V20b8KU2oLBZ9vyB8V010dQz0NRTDLhkcvJig00535/LUylECYAJ
+            5/jn6XKt6UYCQJbVNzBg/YPGc1RF4xdsGVDBben/JXpeGEmkdmXPILTKd9tZ5TC0
+            uOKpF5rWAruB5PCIrquamOejpXV9aQA/K2JQDuc0mcKz
+            -----END CERTIFICATE-----
+  attestations:
+    - name: sbom
+      referrer:
+        type: sbom/cyclone-dx
+  validations:
+    - expression: >-
+        images.containers.map(image, verifyImageSignatures(image, [attestors.notary])).all(e, e > 0)
+      message: failed to verify image with notary cert
+    - expression: >-
+        images.containers.map(image, verifyAttestationSignatures(image, attestations.sbom ,[attestors.notary])).all(e, e > 0)
+      message: failed to verify attestation with notary cer
+    - expression: >-
+        images.containers.map(image, extractPayload(image, attestations.sbom).bomFormat == 'CycloneDX').all(e, e)
+      message: sbom is not a cyclone dx sbom
diff --git a/test/conformance/chainsaw/image-validating-policies/exceptions/autogen/skipped-resources.yaml b/test/conformance/chainsaw/image-validating-policies/exceptions/autogen/skipped-resources.yaml
new file mode 100644
index 000000000000..19fe59fa1ae3
--- /dev/null
+++ b/test/conformance/chainsaw/image-validating-policies/exceptions/autogen/skipped-resources.yaml
@@ -0,0 +1,74 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: skipped-deployment
+  labels:
+    prod: "true"
+    app: bad-nginx
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      prod: "true"
+      app: bad-nginx
+  template:
+    metadata:
+      labels:
+        prod: "true"
+        app: bad-nginx
+    spec:
+      containers:
+      - name: nginx
+        image: ghcr.io/kyverno/test-verify-image:unsigned
+        securityContext:
+          allowPrivilegeEscalation: true
+---
+apiVersion: batch/v1
+kind: CronJob
+metadata:
+  name: skipped-cronjob  
+spec:
+  schedule: "*/5 * * * *"  
+  concurrencyPolicy: Forbid  
+  jobTemplate:
+    metadata:
+      labels:
+        prod: "true"  
+    spec:
+      template:
+        metadata:
+          labels:
+            prod: "true"  
+        spec:
+          containers:
+          - name: secure-container  
+            image: ghcr.io/kyverno/test-verify-image:unsigned
+            command: ["echo", "Hello, world"]  
+            securityContext:
+              allowPrivilegeEscalation: true 
+          restartPolicy: OnFailure  
+---
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+  name: skipped-statefulset
+  labels:
+    prod: "true"
+spec:
+  serviceName: my-app-service
+  replicas: 3
+  selector:
+    matchLabels:
+      prod: "true"
+      app: busybox
+  template:
+    metadata:
+      labels:
+        prod: "true"
+        app: busybox
+    spec:
+      containers:
+      - name: my-app-container
+        image: ghcr.io/kyverno/test-verify-image:unsigned
+        securityContext:
+          allowPrivilegeEscalation: true
\ No newline at end of file
diff --git a/test/conformance/chainsaw/image-validating-policies/exceptions/bad-pod.yaml b/test/conformance/chainsaw/image-validating-policies/exceptions/regular/bad-pod.yaml
similarity index 100%
rename from test/conformance/chainsaw/image-validating-policies/exceptions/bad-pod.yaml
rename to test/conformance/chainsaw/image-validating-policies/exceptions/regular/bad-pod.yaml
diff --git a/test/conformance/chainsaw/image-validating-policies/exceptions/chainsaw-test.yaml b/test/conformance/chainsaw/image-validating-policies/exceptions/regular/chainsaw-test.yaml
similarity index 86%
rename from test/conformance/chainsaw/image-validating-policies/exceptions/chainsaw-test.yaml
rename to test/conformance/chainsaw/image-validating-policies/exceptions/regular/chainsaw-test.yaml
index 11f91e62e5a3..d22e3615d80d 100755
--- a/test/conformance/chainsaw/image-validating-policies/exceptions/chainsaw-test.yaml
+++ b/test/conformance/chainsaw/image-validating-policies/exceptions/regular/chainsaw-test.yaml
@@ -15,14 +15,14 @@ spec:
         file: exception.yaml
   - name: create policy
     use:
-      template: /../../_step-templates/create-policy.yaml
+      template: /../../../_step-templates/create-policy.yaml
       with:
         bindings:
         - name: file
           value: policy.yaml
-  - name: wait-image-validating-policy-ready
+  - name: wait policy ready
     use:
-      template: /../../_step-templates/image-validating-policy-ready.yaml
+      template: /../../../_step-templates/image-validating-policy-ready.yaml
       with:
         bindings:
         - name: name
diff --git a/test/conformance/chainsaw/image-validating-policies/exceptions/exception-assert.yaml b/test/conformance/chainsaw/image-validating-policies/exceptions/regular/exception-assert.yaml
similarity index 100%
rename from test/conformance/chainsaw/image-validating-policies/exceptions/exception-assert.yaml
rename to test/conformance/chainsaw/image-validating-policies/exceptions/regular/exception-assert.yaml
diff --git a/test/conformance/chainsaw/image-validating-policies/exceptions/exception.yaml b/test/conformance/chainsaw/image-validating-policies/exceptions/regular/exception.yaml
similarity index 100%
rename from test/conformance/chainsaw/image-validating-policies/exceptions/exception.yaml
rename to test/conformance/chainsaw/image-validating-policies/exceptions/regular/exception.yaml
diff --git a/test/conformance/chainsaw/image-validating-policies/exceptions/good-pod.yaml b/test/conformance/chainsaw/image-validating-policies/exceptions/regular/good-pod.yaml
similarity index 100%
rename from test/conformance/chainsaw/image-validating-policies/exceptions/good-pod.yaml
rename to test/conformance/chainsaw/image-validating-policies/exceptions/regular/good-pod.yaml
diff --git a/test/conformance/chainsaw/image-validating-policies/exceptions/policy.yaml b/test/conformance/chainsaw/image-validating-policies/exceptions/regular/policy.yaml
similarity index 100%
rename from test/conformance/chainsaw/image-validating-policies/exceptions/policy.yaml
rename to test/conformance/chainsaw/image-validating-policies/exceptions/regular/policy.yaml
diff --git a/test/conformance/chainsaw/image-validating-policies/exceptions/skipped-pod.yaml b/test/conformance/chainsaw/image-validating-policies/exceptions/regular/skipped-pod.yaml
similarity index 100%
rename from test/conformance/chainsaw/image-validating-policies/exceptions/skipped-pod.yaml
rename to test/conformance/chainsaw/image-validating-policies/exceptions/regular/skipped-pod.yaml
diff --git a/test/conformance/chainsaw/image-validating-policies/exceptions/wrong-exception/README.md b/test/conformance/chainsaw/image-validating-policies/exceptions/wrong-exception/README.md
new file mode 100644
index 000000000000..e225c2941f4d
--- /dev/null
+++ b/test/conformance/chainsaw/image-validating-policies/exceptions/wrong-exception/README.md
@@ -0,0 +1,10 @@
+## Description
+
+The policyexceptions should only apply to policies specified and not on all the policies of same kind.
+
+## Expected Behavior
+
+The policyexception is set for a different policy and not the applied policy.
+
+The good-deployment should pass without any failure.
+The skipped-deployment should fail regardless of the fact it is added in the wrongly configured policyexception.
\ No newline at end of file
diff --git a/test/conformance/chainsaw/image-validating-policies/exceptions/wrong-exception/chainsaw-test.yaml b/test/conformance/chainsaw/image-validating-policies/exceptions/wrong-exception/chainsaw-test.yaml
new file mode 100644
index 000000000000..5a959e127ae7
--- /dev/null
+++ b/test/conformance/chainsaw/image-validating-policies/exceptions/wrong-exception/chainsaw-test.yaml
@@ -0,0 +1,39 @@
+# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json
+apiVersion: chainsaw.kyverno.io/v1alpha1
+kind: Test
+metadata:
+  name: exception-test
+spec:
+  steps:
+  - name: create exception
+    try:
+    - create:
+        file: exception.yaml
+    - sleep:
+        duration: 10s
+  - name: create policy
+    use:
+      template: ../../../_step-templates/create-policy.yaml
+      with:
+        bindings:
+        - name: file
+          value: policy.yaml
+  - name: wait policy ready
+    use:
+      template: ../../../_step-templates/image-validating-policy-ready.yaml
+      with:
+        bindings:
+        - name: name
+          value: ivpol-sample
+  - name: create good deployment
+    try:
+    - create:
+        file: good-deployment.yaml
+  - name: create skipped deployment
+    try:
+    - create:
+        file: skipped-deployment.yaml
+        expect:
+          - check:
+              ($error): >-
+                 admission webhook "ivpol.validate.kyverno.svc-ignore-finegrained-ivpol-sample" denied the request: Policy ivpol-sample failed: failed to verify image with notary cert
\ No newline at end of file
diff --git a/test/conformance/chainsaw/image-validating-policies/exceptions/wrong-exception/exception.yaml b/test/conformance/chainsaw/image-validating-policies/exceptions/wrong-exception/exception.yaml
new file mode 100644
index 000000000000..466f41e35e7c
--- /dev/null
+++ b/test/conformance/chainsaw/image-validating-policies/exceptions/wrong-exception/exception.yaml
@@ -0,0 +1,11 @@
+apiVersion: policies.kyverno.io/v1alpha1
+kind: PolicyException
+metadata:
+  name: check-name
+spec:
+  policyRefs:
+    - name: not-ivpol-sample
+      kind: ImageValidatingPolicy
+  matchConditions:
+    - name: "check-name"
+      expression: "object.metadata.name == 'skipped-deployment'"
\ No newline at end of file
diff --git a/test/conformance/chainsaw/image-validating-policies/exceptions/wrong-exception/good-deployment.yaml b/test/conformance/chainsaw/image-validating-policies/exceptions/wrong-exception/good-deployment.yaml
new file mode 100644
index 000000000000..4f04112d3565
--- /dev/null
+++ b/test/conformance/chainsaw/image-validating-policies/exceptions/wrong-exception/good-deployment.yaml
@@ -0,0 +1,24 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: good-deployment
+  labels:
+    prod: "true"
+    app: bad-nginx
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      prod: "true"
+      app: bad-nginx
+  template:
+    metadata:
+      labels:
+        prod: "true"
+        app: bad-nginx
+    spec:
+      containers:
+      - name: nginx
+        image: ghcr.io/kyverno/test-verify-image:signed
+        securityContext:
+          allowPrivilegeEscalation: true
\ No newline at end of file
diff --git a/test/conformance/chainsaw/image-validating-policies/exceptions/wrong-exception/policy.yaml b/test/conformance/chainsaw/image-validating-policies/exceptions/wrong-exception/policy.yaml
new file mode 100644
index 000000000000..748899faeed4
--- /dev/null
+++ b/test/conformance/chainsaw/image-validating-policies/exceptions/wrong-exception/policy.yaml
@@ -0,0 +1,61 @@
+apiVersion: policies.kyverno.io/v1alpha1
+kind: ImageValidatingPolicy
+metadata:
+  name: ivpol-sample
+spec:
+  webhookConfiguration:
+    timeoutSeconds: 20
+  failurePolicy: Ignore
+  validationActions:
+    - Deny
+  matchConstraints:
+    resourceRules:
+      - apiGroups: [""]
+        apiVersions: ["v1"]
+        operations: ["CREATE"]
+        resources: ["pods"]
+  matchConditions:
+    - name: "check-prod-label"
+      expression: >-
+        has(object.metadata.labels) && has(object.metadata.labels.prod) && object.metadata.labels.prod == 'true'
+  matchImageReferences:
+    - glob: ghcr.io/*
+  attestors:
+    - name: notary
+      notary:
+        certs:
+          value: |-
+            -----BEGIN CERTIFICATE-----
+            MIIDTTCCAjWgAwIBAgIJAPI+zAzn4s0xMA0GCSqGSIb3DQEBCwUAMEwxCzAJBgNV
+            BAYTAlVTMQswCQYDVQQIDAJXQTEQMA4GA1UEBwwHU2VhdHRsZTEPMA0GA1UECgwG
+            Tm90YXJ5MQ0wCwYDVQQDDAR0ZXN0MB4XDTIzMDUyMjIxMTUxOFoXDTMzMDUxOTIx
+            MTUxOFowTDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0
+            dGxlMQ8wDQYDVQQKDAZOb3RhcnkxDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3
+            DQEBAQUAA4IBDwAwggEKAoIBAQDNhTwv+QMk7jEHufFfIFlBjn2NiJaYPgL4eBS+
+            b+o37ve5Zn9nzRppV6kGsa161r9s2KkLXmJrojNy6vo9a6g6RtZ3F6xKiWLUmbAL
+            hVTCfYw/2n7xNlVMjyyUpE+7e193PF8HfQrfDFxe2JnX5LHtGe+X9vdvo2l41R6m
+            Iia04DvpMdG4+da2tKPzXIuLUz/FDb6IODO3+qsqQLwEKmmUee+KX+3yw8I6G1y0
+            Vp0mnHfsfutlHeG8gazCDlzEsuD4QJ9BKeRf2Vrb0ywqNLkGCbcCWF2H5Q80Iq/f
+            ETVO9z88R7WheVdEjUB8UrY7ZMLdADM14IPhY2Y+tLaSzEVZAgMBAAGjMjAwMAkG
+            A1UdEwQCMAAwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0G
+            CSqGSIb3DQEBCwUAA4IBAQBX7x4Ucre8AIUmXZ5PUK/zUBVOrZZzR1YE8w86J4X9
+            kYeTtlijf9i2LTZMfGuG0dEVFN4ae3CCpBst+ilhIndnoxTyzP+sNy4RCRQ2Y/k8
+            Zq235KIh7uucq96PL0qsF9s2RpTKXxyOGdtp9+HO0Ty5txJE2txtLDUIVPK5WNDF
+            ByCEQNhtHgN6V20b8KU2oLBZ9vyB8V010dQz0NRTDLhkcvJig00535/LUylECYAJ
+            5/jn6XKt6UYCQJbVNzBg/YPGc1RF4xdsGVDBben/JXpeGEmkdmXPILTKd9tZ5TC0
+            uOKpF5rWAruB5PCIrquamOejpXV9aQA/K2JQDuc0mcKz
+            -----END CERTIFICATE-----
+  attestations:
+    - name: sbom
+      referrer:
+        type: sbom/cyclone-dx
+  validations:
+    - expression: >-
+        images.containers.map(image, verifyImageSignatures(image, [attestors.notary])).all(e, e > 0)
+      message: failed to verify image with notary cert
+    - expression: >-
+        images.containers.map(image, verifyAttestationSignatures(image, attestations.sbom ,[attestors.notary])).all(e, e > 0)
+      message: failed to verify attestation with notary cer
+    - expression: >-
+        images.containers.map(image, extractPayload(image, attestations.sbom).bomFormat == 'CycloneDX').all(e, e)
+      message: sbom is not a cyclone dx sbom
diff --git a/test/conformance/chainsaw/image-validating-policies/exceptions/wrong-exception/skipped-deployment.yaml b/test/conformance/chainsaw/image-validating-policies/exceptions/wrong-exception/skipped-deployment.yaml
new file mode 100644
index 000000000000..67764ee96a83
--- /dev/null
+++ b/test/conformance/chainsaw/image-validating-policies/exceptions/wrong-exception/skipped-deployment.yaml
@@ -0,0 +1,24 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: skipped-deployment
+  labels:
+    prod: "true"
+    app: bad-nginx
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      prod: "true"
+      app: bad-nginx
+  template:
+    metadata:
+      labels:
+        prod: "true"
+        app: bad-nginx
+    spec:
+      containers:
+      - name: nginx
+        image: ghcr.io/kyverno/test-verify-image:unsigned
+        securityContext:
+          allowPrivilegeEscalation: true
\ No newline at end of file


Reviews:
user: login: eddycharly
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-19T08:09:42Z
user: login: eddycharly
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-19T08:10:03Z
user: login: eddycharly
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-19T08:10:21Z
user: login: eddycharly
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-20T07:08:16Z

Review comments:
diff_hunk: @@ -0,0 +1,39 @@
+# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json
+apiVersion: chainsaw.kyverno.io/v1alpha1
+kind: Test
+metadata:
+  name: exception-test
+spec:
+  steps:
+  - name: create exception
+    try:
+    - create:
+        file: exception.yaml
+    - sleep:
+        duration: 10s
+  - name: create policy
+    use:
+      template: ../../../_step-templates/create-policy.yaml
+      with:
+        bindings:
+        - name: file
+          value: policy.yaml
+  - name: wait-validating-policy-ready
path: test/conformance/chainsaw/image-validating-policies/exceptions/wrong-exception/chainsaw-test.yaml
user: login: eddycharly
body: ```suggestion
  - name: wait policy ready
```
created_at: 2025-05-19T08:09:42Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,46 @@
+# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json
+apiVersion: chainsaw.kyverno.io/v1alpha1
+kind: Test
+metadata:
+  name: autogen-deployments-cronjobs-statefulsets
+spec:
+  steps:
+  - name: create exception
+    try:
+    - create:
+        file: exception.yaml
+    - sleep:
+        duration: 10s
+  - name: create policy
+    use:
+      template: ../../../_step-templates/create-policy.yaml
+      with:
+        bindings:
+        - name: file
+          value: policy.yaml
+  - name: wait-validating-policy-ready
path: test/conformance/chainsaw/image-validating-policies/exceptions/autogen/chainsaw-test.yaml
user: login: eddycharly
body: ```suggestion
  - name: wait policy ready
```
created_at: 2025-05-19T08:10:03Z
author_association: MEMBER
diff_hunk: @@ -15,14 +15,14 @@ spec:
         file: exception.yaml
   - name: create policy
     use:
-      template: /../../_step-templates/create-policy.yaml
+      template: /../../../_step-templates/create-policy.yaml
       with:
         bindings:
         - name: file
           value: policy.yaml
   - name: wait-image-validating-policy-ready
path: test/conformance/chainsaw/image-validating-policies/exceptions/regular/chainsaw-test.yaml
user: login: eddycharly
body: ```suggestion
  - name: wait policy ready
```
created_at: 2025-05-19T08:10:20Z
author_association: MEMBER

PR comments:
user: login: codecov[bot]
created_at: 2025-05-16T17:23:20Z
body: ## [Codecov](https://app.codecov.io/gh/kyverno/kyverno/pull/13168?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kyverno) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 15.35%. Comparing base [(`21b351a`)](https://app.codecov.io/gh/kyverno/kyverno/commit/21b351ae07c26828454c9d85479062c44c2f9885?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kyverno) to head [(`af90eb9`)](https://app.codecov.io/gh/kyverno/kyverno/commit/af90eb9bf25baf5c1fbccea6c0a423df417f060a?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kyverno).
> Report is 13 commits behind head on main.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main   #13168      +/-   ##
==========================================
- Coverage   15.35%   15.35%   -0.01%     
==========================================
  Files         940      940              
  Lines      101340   101340              
==========================================
- Hits        15558    15557       -1     
  Misses      84066    84066              
- Partials     1716     1717       +1     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/kyverno/kyverno/pull/13168?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kyverno).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kyverno).

<details><summary> :rocket: New features to boost your workflow: </summary>

- :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
</details>
author_association: NONE
user: login: eddycharly
created_at: 2025-05-19T08:11:38Z
body: LGTM, just some minor comments
author_association: MEMBER
user: login: eddycharly
created_at: 2025-05-22T10:08:25Z
body: /cherry-pick release-1.14
author_association: MEMBER