#17638·kyverno

[Feature] Support dryRun / audit mode in CEL DeletingPolicy (policies.kyverno.io)

Author: anushkagupta200615-jpgCreated Sep 18, 2026Updated Sep 18, 2026
Labelsenhancementtriage

Problem Statement

Kyverno is migrating from legacy CleanupPolicy (kyverno.io/v2) to CEL based DeletingPolicy and NamespacedDeletingPolicy (policies.kyverno.io/v1beta1).

Currently, when a DeletingPolicy executes on its schedule in pkg/controllers/deleting/controller.go, every resource that matches the policy's matchConstraints and CEL conditions is immediately deleted from the cluster via client.DeleteResource(...).

In production environments, cleanup policies are destructive by design. If an operator writes a new DeletingPolicy (e.g. targeting completed pods, stale jobs, or orphaned secrets), an overly broad CEL condition or misconfigured object selector can inadvertently delete active production workloads.

Unlike ValidatingPolicy, which provides validationFailureAction: Audit | Enforce to safely stage and observe policies before enforcing them, DeletingPolicy currently has no dry run or audit mode. Administrators cannot safely observe which live resources would be affected before enabling actual deletion.

Solution Description

Add dry run / audit support to CEL DeletingPolicy and NamespacedDeletingPolicy:

  1. API Addition: Add an optional dryRun: bool field (or action: Audit | Delete, defaulting to Delete) to DeletingPolicySpec in policies.kyverno.io/v1beta1:
yaml
apiVersion: policies.kyverno.io/v1beta1
kind: DeletingPolicy
metadata:
  name: delete-stale-pods
spec:
  schedule: "0 0 * * *"
  dryRun: true # Or action: Audit
  matchConstraints:
    resourceRules:
      - apiGroups: [""]
        apiVersions: ["v1"]
        resources: ["pods"]
  conditions:
    - name: is-completed
      expression: "object.status.phase == 'Succeeded'"
  1. Controller Behavior: In pkg/controllers/deleting/controller.go, when spec.DryRun is true (or action is Audit):
  • Evaluate matchConstraints and CEL conditions as normal.
  • When a resource matches, skip calling c.client.DeleteResource(...) (or invoke it with metav1.DeleteOptions{DryRun: []string{metav1.DryRunAll}}).
  • Emit an informational Kubernetes event on the target resource and policy (e.g. Reason: PolicyDryRunMatch, message: resource matched deleting policy and would be deleted).
  • Record Prometheus metrics for dry run matches so cluster operators can observe candidate counts in metrics before disabling dryRun.

Alternatives

  • Offline CLI testing only (kubectl-kyverno apply): While the CLI can evaluate policies against local manifests, it cannot account for live cluster state, dynamically changing resource metadata, or complex controller interactions in real environments.
  • Manual inspection via kubectl: Querying resources with custom kubectl commands or JSONPath is error prone and duplicates CEL logic already declared in the policy.

Additional Context

  • Aligns DeletingPolicy with Kyverno's other CEL policy types (ValidatingPolicy audit mode).
  • Matches native Kubernetes dry run conventions (metav1.DryRunAll).
  • Significantly lowers the risk for enterprise platform teams adopting CEL deletion policies.

Slack discussion

No response

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.