Skip to content

Resource Selection: KCA practice questions

Every Kyverno rule starts by deciding which requests it applies to. The match block selects resources and an optional exclude block removes a subset of them, and both share one structure. Each contains either any or all, never both: any is a logical OR across its entries and all is a logical AND.

By Ibrahim Yesilay · Published · Updated

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

What Resource Selection covers in KCA

Every Kyverno rule starts by deciding which requests it applies to. The match block selects resources and an optional exclude block removes a subset of them, and both share one structure. Each contains either any or all, never both: any is a logical OR across its entries and all is a logical AND. Putting filters directly under match or exclude without any or all is deprecated.

Each entry is a resource filter, or a filter on who made the request. Under resources, kinds is mandatory, and the other fields narrow it: names and namespaces, both accepting wildcards; selector with matchLabels or matchExpressions on the resource's own labels; namespaceSelector on the labels of the resource's namespace; operations such as CREATE, UPDATE, DELETE or CONNECT; and annotations. If operations is left out, CREATE and UPDATE are matched. Inside one resources block the documentation describes the logic as AND across field types and OR within list types, so kinds: [Pod, Service] together with a selector means a Pod or a Service that also carries those labels. The subjects, roles and clusterRoles filters select users, groups and service accounts, namespaced Roles and ClusterRoles; conditions within them are ORed, and because that information only exists in an admission request, rules using them need background: false.

Kinds can be written as Kind, Version/Kind or Group/Version/Kind. The full form resolves conflicts when two API groups define the same kind, NetworkPolicy being the documented example. Wildcards work in kinds too, such as */Kind or a bare *, but policies matching all kinds cannot contain generate or verifyImages rules, and matching everything sends far more requests through Kyverno. Subresources are written with a slash or a dot, as in Pods/status, and the parent should be named explicitly because a subresource such as Scale is shared by several kinds.

Exclude must describe a subset of what match selects, and all match and exclude conditions have to hold for a resource to be selected.

Some selection cannot be expressed with match and exclude. Variables cannot be used there at all. When the decision depends on the content of the request, preconditions come next: they run after a resource has been matched and not excluded, combine expressions under any and all with operators such as Equals, NotEquals, AnyIn, AllNotIn, GreaterThan and the duration comparisons, and when they evaluate to false the rule is not applied and the result is recorded as skip. That differs from exclude, where the resource is ignored immediately.

Selection also happens before Kyverno sees a request. Its webhook only receives the kinds that installed policies match, its ConfigMap's resourceFilters skip some kinds such as Events by default, and the webhook namespaceSelector excludes the kube-system and kyverno namespaces unless reconfigured. A rule that seems not to fire may simply never receive the request.

Key points

  • Under match or exclude, any is OR and all is AND; a block holds only one of them.
  • Without an operations list, a rule matches CREATE and UPDATE requests.
  • Matching on subjects, roles or clusterRoles requires background: false.
  • A precondition that fails records a skip; an exclude ignores the resource outright.

Three sample questions

8 KCA questions on Resource Selection, 8 with explanations. How practice works

Question 1

Your cluster has both a built-in Ingress resource and a separate CRD that also happens to be named Ingress in a different API group. Your match.resources.kinds entry - Ingress is ambiguous. How do you disambiguate it?
  1. A.Use apiVersion instead of kinds in the match block.
  2. B.Add a second kinds entry with just the API group name, e.g. - networking.k8s.io.
  3. C.It cannot be disambiguated; only one Ingress-named resource may exist per cluster.
  4. D.Qualify the entry as group/version/Kind, e.g. - networking.k8s.io/v1/Ingress.

Correct answer: D

When a bare Kind name is ambiguous across API groups, kinds entries can be fully qualified as group/version/Kind, giving Kyverno the exact API resource to match rather than any resource sharing that Kind string.

Question 2

You write resources.names: ["*-secrets"] on a ConfigMap-scoped rule, intending to catch every ConfigMap that holds sensitive data. A teammate creates a ConfigMap named db-password holding an actual database password. What happens?
  1. A.The rule catches it, because *-secrets is treated as a regular expression matching any sensitive-sounding name.
  2. B.The rule does not evaluate it at all — names matches only against metadata.name, and db-password does not end in -secrets.
  3. C.The rule renames the ConfigMap to end in -secrets before evaluating it.
  4. D.The rule catches it anyway, because Kyverno scans ConfigMap values for the word "secret".

Correct answer: B

name/names wildcard matching operates purely on the string in metadata.name. It has no awareness of the object's actual content, so a ConfigMap named db-password — regardless of what it stores — is simply outside the scope of a rule filtered to *-secrets.

Question 3

A rule uses resources.namespaces: ["shop-prod"]. Six months later, a new namespace shop-prod-eu is created for a European region. Does the rule automatically apply to shop-prod-eu?
  1. A.Yes, because namespaces entries are wildcard-capable by default even without an explicit *.
  2. B.No, and it never can be added without deleting and recreating the policy.
  3. C.Yes, because Kyverno treats any namespace sharing a prefix as automatically in scope.
  4. D.No — namespaces is a static literal list; shop-prod-eu is a different string than shop-prod and must be added explicitly (or the entry rewritten with a wildcard).

Correct answer: D

resources.namespaces is a static, literal list. shop-prod-eu is a distinct string from shop-prod, so it is not in scope unless the policy is edited — either adding shop-prod-eu explicitly or rewriting the entry as a wildcard like "shop-prod*".

Practice this topic

Focus mode keeps every question on Resource Selection 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 match a kind that exists in two API groups?

Write the kind as Group/Version/Kind instead of the bare kind name. The Kyverno documentation uses NetworkPolicy, which exists in more than one API group, as the example.