skip to content

What does the Kyverno CLI command kyverno apply do with a policy and a manifest file?

level: juniorimportance: must knowfreq 62%

answer

  1. runs on your laptop, not a cluster
  2. feed it YAML of two kinds
  3. policy file plus resource file
  4. prints pass, fail, skip, warn
  5. a dry run, nothing is admitted

basics

~20 s

kyverno apply reads policy files and resource files from disk and evaluates the rules against them locally, printing pass, fail, skip and warn results. It is a dry run: no cluster is contacted and nothing is admitted.

solid answer

~40 s

It is Kyverno's offline evaluator. You point it at one or more policy files and one or more resource manifests (`kyverno apply policy.yaml --resource deployment.yaml`) and it runs the same rules the in-cluster engine would run, but against the YAML on disk, printing a per-rule result and a pass/fail/skip/warn summary. It exits non-zero when rules fail, which is what lets a CI job or a pre-commit hook gate on it, and it can emit the findings in policy-report form for another tool to read. For a mutate policy it prints the patched resource so you can diff it. Nothing is created: it never talks to an API server, never admits anything, and never writes PolicyReport objects into a cluster.

go deeper

for a junior

Be ready to say what you feed it (policy YAML plus resource YAML), what it prints (pass, fail, skip, warn plus a summary) and that no cluster is involved. Knowing it exits non-zero on failure is enough to explain how CI uses it.

for a middle

Explain the difference between a fail and a skip, and what each tells you about your match block. Be able to say why the file the CLI evaluates is not the object admission validates.

for a senior

Show where this sits in a real workflow: rendered output rather than templates, running in CI on the merge request, and knowing which classes of rule cannot be judged offline at all.

for a principal

Own the position that offline evaluation is cheap confidence and nothing more. Decide what your organisation gates on locally versus what it can only learn from admission and background scans, and be honest about the gap.

## What the command is for A Kyverno policy is a Kubernetes custom resource whose rules match resources and then `validate`, `mutate` or `generate`. Once installed, those rules decide at admission — when someone submits an object to the API server — and they are also re-run in the background against objects that are already stored. Neither of those is a good place to find out that your brand-new rule matches the wrong kind or denies everything. `kyverno apply` is the escape hatch: it runs the policy engine as a local process over YAML files. ``` kyverno apply policy.yaml --resource deployment.yaml ``` You can pass several policies, several resources, or directories of each. The engine loads them, works out which rules match which resources, evaluates the rule bodies, and prints what happened. ## What comes back For each rule/resource pair you get one of a small set of outcomes: | result | meaning | | --- | --- | | pass | the rule matched the resource and the resource satisfied it | | fail | the rule matched and the resource violated it | | skip | the rule did not apply to this resource (match/exclude, preconditions) | | warn | a violation from a rule configured to advise rather than block | | error | the rule could not be evaluated — bad variable, missing context | plus a summary of the counts. The distinction between **fail** and **skip** is the one beginners misread: a long list of `skip` usually means your `match` block names a kind, a selector or an API group the resource does not have, so the rule you are proud of never ran at all. A wall of `error` usually means the rule references something that only exists at admission time. The process exits non-zero when there are failures, so it drops straight into CI: render your manifests, run the policies over them, fail the job. It can also emit its findings in the policy-report shape rather than as human text, which is handy when you want to feed the results into a dashboard instead of a terminal. For a `mutate` rule the CLI prints the resource after the patch, which is the fastest way to check that a mutation does what you meant rather than what you typed. ## Where it sits relative to the other two evaluation points Think of three places the same rule can run: 1. **The CLI, over files.** Before anything exists. No cluster, no state, no request. This is the dry run. 2. **Admission, over a request.** When someone submits an object. There is a requesting user, an operation, and for an update an old object; the answer is allow, deny or mutate. 3. **The background scan, over stored objects.** On an interval, against what is already in the cluster. Nobody is blocked; results are written into `PolicyReport` and `ClusterPolicyReport` objects. The CLI is the only one you can run on a laptop or in a pipeline that has no cluster, and the only one whose input you fully control. That is its value and also its limitation: it evaluates the file exactly as written, and neither of the other two positions ever sees exactly that. ## What a green run does and does not tell you It tells you the policy parses, the match block selects the resources you think it selects, and the rule body reaches the verdict you expect for the inputs you supplied. That is genuinely most of the mistakes. It does not tell you that admission will agree. The API server applies defaults to an object before validating it, and mutating admission — including Kyverno's own mutate rules and anyone else's webhooks — runs before validating admission, so the object that gets validated in a real cluster is not the file you handed the CLI. Rules that look up a ConfigMap, call the API, or read the requesting user have nothing to read offline unless you stub it with a values file. It also says nothing about objects already in the cluster. A rule can be perfectly green over every manifest in your repository while hundreds of stored objects violate it, because those objects were created before the rule existed and no one is resubmitting them. Finding those is the background scan's job, not the CLI's. ## Related tooling Alongside `apply` the CLI has `kyverno test`, which reads a test manifest declaring policies, resources and the result expected for each pair, and reports mismatches — the same engine, driven by declared expectations instead of eyeballed output. Designing those expectation sets is a testing discipline of its own; the point here is only that `apply` is the interactive form and `test` is the asserted form of the same offline evaluation.

  • Can it evaluate rendered Helm or Kustomize output rather than hand-written manifests?
    Yes — it reads resource YAML from files, and it does not care how that YAML was produced. Render the chart or the kustomization to a file first and point the CLI at the output. That is the right order anyway, because the rendered object is what would actually be submitted, and a rule about a field in the rendered result cannot be judged from the template.
  • Does a passing run mean admission will accept the same manifest?
    No. The API server defaults fields before validation, and mutating admission runs before validating admission, so the object validated in-cluster differs from the file. Rules that consult cluster state or the requesting identity also have nothing to read offline. A green CLI run means the rule is well-formed and matches what you expect; it is not a prediction of the admission verdict.
  • Does the CLI create PolicyReport objects?
    No. It prints results, and it can render them in policy-report shape as output for another tool to parse, but it never writes anything into a cluster. PolicyReport and ClusterPolicyReport resources are created by the in-cluster controllers from admission results and background scans, not by a local run.

It is a spell-checker run over the document before you email it: it catches what is wrong with the text you wrote, but it cannot know what the recipient's mail client will do to the formatting.

saying these in an interview costs you the question

  • Thinks the CLI contacts the cluster to reach its verdict
  • Treats a green local run as proof admission will accept it
  • Confuses the CLI dry run with a background scan of stored objects
  • Expects the CLI to create PolicyReport objects in a cluster
  • Reads a wall of skip results as success rather than a broken match block

context