✦ For everyone, free.

Practical knowledge for real and everyday life

Home

Kubernetes Admission Webhook Matching

Kubernetes Admission Webhook Matching ensures valid requests are processed by aligning incoming operations with predefined webhook rules.

Kubernetes Admission Webhook Matching is the set of rules and selectors that determine, for any given API request, precisely which registered mutating or validating webhooks are actually invoked. Because a cluster can have many webhooks registered simultaneously covering overlapping resources, understanding the matching mechanism precisely — rules, matchPolicy, namespaceSelector, and objectSelector — is essential both for scoping a new webhook correctly and for diagnosing why an existing webhook did or did not fire for a particular request.


The rules Field

Matching on Group, Version, Resource, and Operation

Each webhook's rules list specifies apiGroups, apiVersions, resources, and operations; a request matches a rule only if it satisfies every one of these dimensions simultaneously — a webhook scoped to operations: ["CREATE"] never fires for UPDATE or DELETE requests against the same resource, regardless of how the resource itself is matched.

rules:
- apiGroups: ["apps"]
  apiVersions: ["v1"]
  operations: ["CREATE", "UPDATE"]
  resources: ["deployments"]
  scope: "Namespaced"

The scope Field

scope restricts matching to Namespaced resources, Cluster resources, or * (both), which matters for resource types that can exist at either scope conceptually but are represented differently — most commonly relevant when a webhook should only apply to namespaced instances of a resource and not accidentally match a cluster-scoped variant.


matchPolicy: Equivalent Versus Exact

Equivalent (Default)

With matchPolicy: Equivalent, the API server matches a request against a webhook's rules even if the request used a different, but convertible, API version than the ones explicitly listed — for example, a webhook listing only apps/v1 still matches a request submitted via an older equivalent version if the resource supports conversion between them.

matchPolicy: Equivalent

Exact

With matchPolicy: Exact, only requests using an API version explicitly listed in rules are matched, which is useful when a webhook's logic depends on version-specific field behavior and should not be silently applied to a converted representation it was not designed to inspect.


namespaceSelector and objectSelector

Scoping by Namespace Labels

namespaceSelector restricts a webhook to only fire for requests within namespaces matching a given label selector, commonly used to exempt system namespaces from application-oriented policy, or conversely to apply a policy only to namespaces explicitly labeled as subject to it.

namespaceSelector:
  matchExpressions:
  - key: pod-security.kubernetes.io/enforce
    operator: NotIn
    values: ["privileged"]

Scoping by Object Labels

objectSelector restricts a webhook to only fire for objects (not namespaces) matching a given label selector, allowing fine-grained targeting — for instance, a webhook that only mutates pods explicitly labeled to opt into sidecar injection, leaving all other pods untouched by default.

objectSelector:
  matchLabels:
    sidecar-injection: enabled

Practical Matching Scenarios

Excluding a Webhook's Own Infrastructure

A webhook service running as a pod in the cluster it polices commonly excludes its own namespace via namespaceSelector using a NotIn expression, avoiding a circular dependency where the webhook's own deployment could be blocked by policy it has not yet started serving.

Layering Multiple Narrow Webhooks Instead of One Broad One

Rather than registering a single webhook matching every resource type broadly and implementing conditional logic internally, registering multiple narrowly-scoped webhooks — each with precise rules and selectors for a specific concern — keeps matching behavior legible from the configuration alone, without needing to read the webhook's implementation to understand what it actually applies to.


Diagnosing Matching Issues

Confirming Whether a Webhook Fired

When a policy appears not to have been enforced, checking whether the webhook's rules, namespaceSelector, and objectSelector actually cover the specific request in question — rather than assuming the webhook's logic itself is at fault — is the first diagnostic step, since a narrowly scoped or mismatched selector is a more common cause of unexpected non-enforcement than a bug in the validation logic.

kubectl get validatingwebhookconfigurations <name> -o jsonpath='{.webhooks[0].rules}'
kubectl get namespace payments --show-labels

Testing Match Coverage Deliberately

Submitting deliberately crafted test requests — varying API version, operation type, and namespace or object labels — against a webhook's configuration in a staging environment confirms its matching behavior empirically, which is more reliable than reasoning about selector logic from the YAML alone, particularly when matchPolicy: Equivalent conversion behavior is involved.