Documentskyverno
CLI Policy Result Processing
CLI Policy Result Processing
Type
Topic
Status
Published
Created
Jul 7, 2026
Updated
Jul 8, 2026
Created by
Dosu Bot
Updated by
Dosu Bot

CLI Policy Result Processing#

Overview#

The kubectl-kyverno apply command processes multiple policy types through distinct execution paths that all converge on a shared ResultCounts struct and a unified output pipeline. The primary entry point is applyCommandHelper in command.go.

Key files:


Separate Processing Paths#

Loaded policies are split into typed slices (kpols, vps, ivps, dps, cps, mps, etc.) and dispatched through independent processing functions :

Policy TypeProcessing FunctionResult Accumulator
Legacy Policy/ClusterPolicy + VAPs, ValidatingPolicies, MutatingPolicies, GeneratingPoliciesapplyPoliciesPolicyProcessor.ApplyPoliciesOnResource()addEngineResponses, addMutateResponse, AddValidatingPolicyResponse, etc.
ImageValidatingPolicyapplyImageValidatingPoliciesAddValidatingPolicyResponse
DeletingPolicyapplyDeletingPoliciesAddValidatingPolicyResponse
CleanupPolicyapplyCleanupPoliciesAddValidatingPolicyResponse
HTTP/Envoy policiesauthzProcessor.Apply*separate response lists

Within ApplyPoliciesOnResource, legacy Kyverno policies are processed in a fixed order: mutate → verify images → validate → generate . ValidatingPolicies are additionally split by evaluation mode: EvaluationModeJSON policies are evaluated against raw JSON via celengine.RequestFromJSON, while default Kubernetes-mode policies go through the standard admission path . Kubernetes-mode policies are silently skipped when the input is a raw JSON payload .

All response slices are merged into a single []engineapi.EngineResponse before being passed to the output stage .


Shared Result Counting (ResultCounts)#

ResultCounts holds five integer counters: Pass, Fail, Warn, Error, Skip. Each policy type has a dedicated accumulator method with different audit-warn semantics:

  • addEngineResponse (legacy Kyverno policies): only processes responses where AsKyvernoPolicy() != nil. A RuleStatusFail is downgraded to Warn if the policy is unscored (annotations.Scored returns false) or if --audit-warn is set and the failure action is Audit .
  • addValidatingAdmissionResponse (VAPs): counts Pass/Fail/Error only — no warn downgrade .
  • AddValidatingPolicyResponse (ValidatingPolicy, DeletingPolicy, CleanupPolicy, ImageValidatingPolicy): counts Pass/Fail/Error/Skip — no audit-warn logic .
  • addMutateResponse: handles Kyverno, MAP, and MutatingPolicy types separately; returns a boolean indicating whether the patched resource should be printed .
  • addGenerateResponse: handles both Kyverno and CEL-based GeneratingPolicy. For GeneratingPolicy, counts all five status types (Pass, Fail, Warn, Error, Skip). Previously, only Pass and Fail were tracked; Error, Skip, and Warn statuses were silently dropped, causing CEL evaluation errors (e.g., when test resources omit metadata.uid and a policy reads object.metadata.uid) to produce all-zero output instead of surfacing the error .

Important: addEngineResponses is called only for legacy Kyverno policy responses . VAP responses are appended after this call and counted separately via addValidatingAdmissionResponse .


Output Formatting Pipeline#

After all policies are processed, the command selects one of four output modes :

  1. --policy-report: calls printReportsComputePolicyReports, which groups results per policy and emits ClusterReport (cluster-scoped) or PolicyReport (namespaced) YAML/JSON objects.
  2. --generate-exceptions: calls printExceptions to emit PolicyException resources for each violation.
  3. --table / -t: calls printTable, which iterates all EngineResponse objects and renders a colored table row per rule result.
  4. Default (violations list): iterates responses inline, printing failed rules per resource with an "audit warning" label when applicable. Error messages are printed for both mutate and generate policies .

In table mode, the --audit-warn flag causes RuleStatusFail results from audit-mode policies to render as warnings (color.ResultWarn()) instead of failures . The --detailed-results flag controls compactness of the table output .

ComputePolicyReportResult applies the same audit-warn downgrade at the report level: if the result is StatusFail, the policy action is Audit, and auditWarn=true, the result is changed to StatusWarn before being written into the report .


Exit Code Logic#

The exit function determines the process exit code from ResultCounts:

  • rc.Fail > 0 → exit 1 ("policy violations")
  • rc.Error > 0 → exit 1 ("policy errors")
  • rc.Warn > 0 and --warn-exit-code N → exit N
  • rc.Pass == 0 and --warn-no-pass → exit with warn code

Policies routed through AddValidatingPolicyResponse (ValidatingPolicy, DeletingPolicy, CleanupPolicy, ImageValidatingPolicy) do not benefit from the audit-warn Fail→Warn downgrade in result counting, so their failures always contribute to rc.Fail and will trigger exit 1 regardless of --audit-warn.

CLI Policy Result Processing | Dosu