Skip to content

YAML Manifests: KCA practice questions

Kyverno policies are ordinary Kubernetes manifests, so most mistakes are YAML mistakes. A legacy policy has apiVersion kyverno.io/v1, kind ClusterPolicy or Policy, metadata with a name, and a spec whose rules list holds the logic; the CEL-based types use apiVersion policies.kyverno.io/v1.

By Ibrahim Yesilay · Published · Updated

Independent community practice, not affiliated with or endorsed by CNCF or The Linux Foundation.

What YAML Manifests covers in KCA

Kyverno policies are ordinary Kubernetes manifests, so most mistakes are YAML mistakes. A legacy policy has apiVersion kyverno.io/v1, kind ClusterPolicy or Policy, metadata with a name, and a spec whose rules list holds the logic; the CEL-based types use apiVersion policies.kyverno.io/v1.

In a validate pattern, structure is meaning. The pattern mirrors the resource, so a required label belongs at metadata.labels.<key> inside the pattern, not at the top level. Fields that the pattern does not mention are not checked, and child values are only checked when their parent matched, so a misplaced key quietly turns a strict check into one that always passes. Anchors are written into the key itself, as in (name) or X(hostPath), and the value side carries wildcards and operators. Kinds in a match block can be written as Kind, Version/Kind or Group/Version/Kind, and kinds is the one mandatory field of a resources filter.

Messages and values can include variables in double braces, which Kyverno resolves with JMESPath before the rule runs, for example {{request.object.metadata.name}}. Plain JMESPath fields, such as a foreach list, do not need braces. Quoting matters: a context name or data key containing dashes or slashes must be quoted inside the expression, as in {{ "roles-dictionary".data."allowed-roles" }}.

Reference data does not have to be hard-coded. A context entry of type configMap loads a ConfigMap by name and namespace at evaluation time, so editing it changes later decisions without touching the policy. The documented example stores an allowed list as a JSON string in a ConfigMap, converts it with parse_json, and uses a deny condition with the AnyNotIn operator to reject other values; parse_yaml handles a YAML block instead. Labelling the ConfigMap with cache.kyverno.io/enabled: "true" lets Kyverno cache it. An apiCall entry reads from the Kubernetes API by urlPath, optionally reshaped with a jmesPath expression, and can fall back to a default value if the call fails.

Manifests can be checked before they reach a cluster with the Kyverno CLI, installable with Homebrew, as a kubectl plugin through Krew, or as a binary. kyverno apply runs one or more policies against resource files given with --resource, which also accepts stdin, and prints mutated output for mutate rules; --policy-report produces a report for validate rules. kyverno test looks for a kyverno-test.yaml file that declares the expected results, pass, fail, skip or warn, and reports a failure whenever the actual result differs, even if the actual result was a skip. The testing guide shows both commands in a pull request pipeline, where a failing step stops the run. Flags such as --audit-warn and --warn-exit-code control how warnings affect the exit code.

Key points

  • A pattern key at the wrong path is simply not checked, so the rule can pass silently.
  • Context names or keys with dashes must be quoted inside {{ }} expressions.
  • A configMap context is read at evaluation time, so edits take effect without changing the policy.
  • kyverno test fails a case whenever the actual result differs from the expected one.

Three sample questions

10 KCA questions on YAML Manifests, 10 with explanations. How practice works

Question 1

You need a policy that should only ever affect resources inside the billing namespace, and must never be usable to affect any other team's namespace even by accident. Which kind should you choose, and why?
  1. A.Policy, placed in the billing namespace, because a namespaced Policy can only ever see resources created in its own namespace regardless of what match says.
  2. B.Either kind works identically; the choice makes no functional difference.
  3. C.ClusterPolicy with a namespaces filter in match, because Policy objects do not support validate rules.
  4. D.ClusterPolicy, because it is the only kind that supports a validate rule.

Correct answer: A

A namespaced Policy object is scoped by its own metadata.namespace — its rules can only ever evaluate resources created in that same namespace, no matter how permissive its match block is written. This is the strongest guarantee against accidentally affecting another team's resources.

Question 2

You run kubectl apply -f my-policy.yaml and the command reports the object was created successfully. You then run kubectl describe clusterpolicy my-policy and see Ready: False with a message referencing an unknown resource kind. What does this indicate?
  1. A.Kyverno accepted the object but found a validation problem with the policy's own rules — such as a match.resources.kinds entry that does not exist on this cluster — and never activated it.
  2. B.The policy is corrupted and must be deleted and recreated from scratch.
  3. C.The policy is active and enforcing; Ready: False only affects background scanning.
  4. D.kubectl apply silently failed despite reporting success.

Correct answer: A

The Kubernetes API server accepting the object (schema-valid YAML) is a separate step from Kyverno validating the *policy's own logic* is sound. A Ready: False condition with a message naming an unknown kind means a rule's match block references a resource kind that is not registered on this cluster (commonly a typo, or a CRD that is not installed) — the policy exists but Kyverno never activates enforcement for it.

Question 3

You want to test whether a Pod manifest would be accepted or rejected by your cluster's active Kyverno policies, without leaving behind a real Pod object to clean up afterward. Which command achieves this?
  1. A.kubectl apply --dry-run=client -f pod.yaml
  2. B.kyverno test pod.yaml
  3. C.kubectl create -f pod.yaml --validate=false
  4. D.kubectl apply --dry-run=server -f pod.yaml

Correct answer: D

--dry-run=server sends the manifest all the way to the API server, through every admission webhook including Kyverno's, and returns the real admission decision — without persisting the object to etcd.

Practice this topic

Focus mode keeps every question on YAML Manifests until you leave it. 10 free guest answers, then a free account; no credit card.

Or open KCA practice across all topics.

Sources

The explanation above was checked against these official documents.

Frequently asked questions

How do I use a list stored in a ConfigMap inside a policy?

Load the ConfigMap as a context entry, reference the key with a quoted JMESPath expression, and convert the string with parse_json or parse_yaml. The result can be compared with operators such as AnyIn or AnyNotIn in a deny condition.