Documentskyverno
ValidatingPolicy Status Management
ValidatingPolicy Status Management
Type
Topic
Status
Published
Created
Jul 7, 2026
Updated
Jul 7, 2026
Created by
Dosu Bot
Updated by
Dosu Bot

ValidatingPolicy Status Management#

The policystatus controller (pkg/controllers/policystatus/) reconciles the .status field of all CEL-based policy types — including ValidatingPolicy, NamespacedValidatingPolicy, ImageValidatingPolicy, MutatingPolicy, GeneratingPolicy, and their namespaced variants. For ValidatingPolicy, the status reflects two independent health checks: whether the policy is wired into the webhook, and whether the Kyverno reports service account has the RBAC permissions needed to list the policy's target resources.

Scope distinction: This controller is about status reporting, not policy enforcement. The CEL validation execution pipeline lives in the ValidatingPolicy Engine (vpolengine).


Controller Entry Point#

ItemDetail
Packagepkg/controllers/policystatus
Name constant"status-controller"
Workers3
Max retries3
Instantiationcmd/kyverno/main.go via policystatuscontroller.NewController() — registered as a leader controller

NewController accepts informers for all 8 policy types and a webhook.StateRecorder. It wires two sets of event handlers per policy: one keyed by MetaNamespaceKey (for standard add/update reconciliation) and one keyed by BuildRecorderKey (for webhook-state-change notifications) .


Reconcile Loop#

reconcile() parses the queue key with ParseRecorderKey to determine policy type, name, and namespace, then dispatches to a type-specific update function. All updates are wrapped in retryStatusUpdate, which retries on API conflict and silently drops NotFound errors (policy deleted before the update could land).

A secondary watchdog goroutine drains the StateRecorder.NotifyChannel() and re-enqueues any key that the webhook controller broadcasts, ensuring status is refreshed whenever webhook state changes.


Status Conditions for ValidatingPolicy#

updateVpolStatus and updateNVpolStatus are the ValidatingPolicy-specific handlers. Each:

  1. Wraps the policy in engineapi.NewValidatingPolicy(vpol) to get a GenericPolicy.
  2. Calls reconcileBeta1Conditions to evaluate two conditions.
  3. Derives the boolean Ready field from whether all conditions are ConditionTrue.
  4. Runs vpolautogen.Autogen(vpol) to populate status.autogen.configs .
  5. Writes back the full ValidatingPolicyStatus (conditions + autogen + preserved Generated flag) via controllerutils.UpdateStatus, skipping the API write if status is already equal .

Condition: WebhookConfigured#

reconcileBeta1Conditions first checks backgroundOnly — if the policy has admission disabled and background enabled, the webhook condition is skipped entirely . Otherwise it calls c.polStateRecorder.Ready(key):

  • Returns (true, true) → sets WebhookConfigured=True, message "Webhook configured."
  • Returns (false, true) → sets WebhookConfigured=False, message "Policy is not configured in the webhook."
  • Key not found in recorder (ok=false) → condition not updated

The StateRecorder is a simple mutex-protected map at pkg/controllers/webhook/recorder.go populated by the webhook controller whenever it installs or removes a ValidatingWebhookConfiguration entry for the policy.

Condition: RBACPermissionsGranted#

permissionsCheck iterates over every GroupVersionResource derived from the policy's matchConstraints.resourceRules and issues a SubjectAccessReview for the verbs get, list, and watch . The subject is the reportsSA service account passed at construction time .

  • All checks pass → RBACPermissionsGranted=True, message "Policy is ready for reporting."
  • Any check fails → RBACPermissionsGranted=False with a combined error message listing the missing verbs and resources
  • auth.ErrNoServiceAccount → skipped silently

resolveGVRs expands the cross-product of APIGroups × APIVersions × Resources from the policy's match rules to produce the full GVR list.


Status Struct Layout#

ValidatingPolicyStatus contains :

FieldDescription
ConditionStatusConditions slice + Ready *bool
AutogenValidatingPolicyAutogenStatus{Configs: []...}
GeneratedPreserved from prior status; indicates auto-generated policy

Policy-Type Coverage#

The controller handles all CEL-based policy types via dedicated files. For ValidatingPolicy, the relevant files are:

FileCoverage
controller.goCore reconcile loop, condition helpers, RBAC check
vpol.goValidatingPolicy + NamespacedValidatingPolicy status update

Parallel files exist for ivpol.go (ImageValidatingPolicy), mpol.go (MutatingPolicy), gpol.go (GeneratingPolicy), ngpol.go (NamespacedGeneratingPolicy), and nivpol.go (NamespacedImageValidatingPolicy).