skip to content

In a Kyverno verifyImages rule, what does imageReferences select and what happens to an image it does not match?

level: juniorimportance: must knowfreq 60%

answer

  1. it is a list, not one image
  2. which container positions does it cover?
  3. init and ephemeral containers count too
  4. no matching pattern means no check
  5. silent pass, not a denial

basics

~20 s

imageReferences is a list of glob patterns matched against every image string in the pod spec, including initContainers and ephemeral containers. An image matching no pattern is never evaluated by that rule, so it is admitted unverified.

solid answer

~40 s

`imageReferences` is a list of wildcard patterns, and the rule is evaluated against each image reference in the matched resource that matches at least one of them. It covers every image position in the pod spec — `containers`, `initContainers` and `ephemeralContainers` — so a sidecar or an init image is verified on the same terms as the app image. The consequence people miss is the negative one: an image that matches no pattern is not evaluated at all, so the rule neither passes nor fails it and the pod goes through. That makes an over-narrow pattern a silent hole rather than a visible failure — write `registry.example.com/apps/*` and then deploy `docker.io/vendor/agent` and you have verified nothing. Most teams pair narrow per-source rules with one broad catch-all so no image slips past every pattern.

go deeper

for a junior

Be ready to say in one breath that imageReferences is a list of wildcard patterns scoping the rule, and that an image matching none of them is simply not checked.

for a middle

Explain the mechanics: matching is against the full reference including the registry host, all container positions in the pod spec are covered, and every matching rule is evaluated rather than just the first.

for a senior

Show you have operated it — describe how you prove coverage across an estate, why an over-narrow pattern is more dangerous than an over-broad one, and how layered rules compose.

for a principal

Own the coverage model: who is allowed to add a registry, how a new image source gets picked up by policy by default rather than by someone remembering to edit a pattern list.

## What a verifyImages rule is Kyverno is an admission-time policy engine for Kubernetes. Alongside `validate` and `mutate`, a rule can carry a `verifyImages` block, which is the rule type that reaches out to the container registry, checks signatures and attestations attached to an image, and decides whether the workload referencing that image may be admitted. Every `verifyImages` entry starts with the same question: *which images am I talking about?* That is what `imageReferences` answers. ## imageReferences is a pattern list, not an image `imageReferences` is a list of wildcard patterns compared against the image reference string as the rule resolves it — registry host, repository path, and tag or digest. A rule fires for an image if the image matches **at least one** pattern in the list. Typical entries look like: ```yaml imageReferences: - "registry.example.com/apps/*" - "ghcr.io/myorg/*" ``` Two mechanical points follow. First, the pattern is matched against the *whole* reference, so the registry host is part of what you are matching; a pattern written as `myorg/*` will not cover `ghcr.io/myorg/app`. Second, patterns are independent — adding a second entry widens the rule, it does not narrow it. ## Every image position in the pod spec A pod can reference images in more than one place: the application containers under `containers`, the setup images under `initContainers`, and any debug images injected as `ephemeralContainers`. A `verifyImages` rule considers all of them. This matters because the weakest image in a pod is often not the app image: a logging sidecar pulled from a vendor registry, or an init container that runs a database migration, gets the same access to the pod's volumes, service-account token and network namespace as the main process. A policy that only reasons about "the app image" is reasoning about the wrong threat. ## The unmatched image is the failure mode The single most important behaviour to internalise is that **no match means no evaluation**. The rule is not a default-deny over all images; it is a conditional check that only runs on images its patterns select. An image outside every pattern produces no pass and no fail from that rule, and unless some other rule covers it, the pod is admitted. This is what makes a typo or an over-narrow pattern dangerous. If a rule blocks unsigned images from `registry.example.com/apps/*` and a team starts deploying from `registry.example.com/platform/*`, nothing breaks, nothing is logged as a violation, and the guardrail quietly stops applying to a growing share of the estate. Compare that with the opposite mistake — a pattern that is too broad — which fails loudly the first time somebody deploys an image nobody signs, and gets fixed the same afternoon. A silent hole is worse than a noisy one because nothing forces you to look at it. ## Designing coverage Because every matching rule in every policy is evaluated, requirements accumulate rather than compete: if two rules both select an image, the image has to satisfy both. That composition is what makes a coverage strategy possible. A common shape is: - a broad rule whose `imageReferences` is effectively a catch-all, expressing the minimum every image must meet; - narrower rules per registry or per vendor, layering on stricter requirements — a specific signing identity, a required attestation — for images from that source. The coverage question then becomes answerable: rather than auditing each rule's pattern individually, you ask whether any running image fails to match the catch-all. Teams that skip the catch-all end up maintaining a pattern list that has to be updated every time a new registry appears, and they find out it was not updated only when someone goes looking. ## What to say in an interview Define `imageReferences` as a glob list scoping the rule; note that it spans containers, initContainers and ephemeral containers; then volunteer the negative case — an unmatched image is admitted unverified — and the mitigation of a catch-all pattern plus narrower layered rules. Volunteering the silent-pass behaviour is what separates someone who has run this in a cluster from someone who has read the field reference.

  • If two verifyImages rules both select the same image, which one wins?
    Neither — every matching rule is evaluated and the image must satisfy all of them. Requirements accumulate, so a broad baseline rule and a narrow per-registry rule compose rather than override each other. That is what lets you layer a catch-all minimum under stricter per-source requirements without writing one giant pattern list.
  • How do you find out whether some running image is matched by no pattern at all?
    Treat it as a coverage question, not a policy question: list the distinct image references actually running in the cluster and test each against the union of your patterns. Adding a catch-all rule makes the check trivial, because then "matched by nothing" cannot happen and any gap shows up as a failure instead of silence.
  • Why does the rule bother with initContainers when they exit before the app starts?
    An init container runs with the pod's volumes, service-account token and network namespace, often as a more privileged setup step. It can exfiltrate secrets or write a compromised binary into a shared volume that the app container then executes. Exiting early limits its uptime, not its access.

saying these in an interview costs you the question

  • Thinks an unmatched image is denied by default
  • Assumes only app container images are checked
  • Writes repository patterns without the registry host
  • Treats imageReferences as a single image string
  • Believes the first matching rule wins and the rest are skipped

context