✦ For everyone, free.

Practical knowledge for real and everyday life

Home

Kubernetes Admission Webhook Selection

Kubernetes Admission Webhook Selection determines which webhooks are used to validate or mutate API requests, ensuring controlled and secure cluster operations.

Kubernetes Admission Webhook Selection is the design practice of using label-based selectors — namespaceSelector and objectSelector — to deliberately choose which specific namespaces or objects a registered webhook applies to, as opposed to the resource-type-and-operation matching performed by the rules field. Where rule matching answers "what kind of request is this," selector-based selection answers "should this particular instance, given its labels, actually be subject to this webhook," and designing a clear labeling taxonomy is what makes that selection legible and maintainable.


Selection via namespaceSelector

Opt-In Versus Opt-Out Models

A webhook can be designed around an opt-in model, where only namespaces explicitly labeled to request a behavior are selected, or an opt-out model, where all namespaces are selected except those explicitly labeled to be exempt. Opt-in tends to suit optional features (sidecar injection, for instance), while opt-out tends to suit baseline security requirements that should apply everywhere unless a specific, justified exception exists.

# Opt-in: only namespaces explicitly requesting injection
namespaceSelector:
  matchLabels:
    mesh-injection: enabled
# Opt-out: applies everywhere except explicitly exempted namespaces
namespaceSelector:
  matchExpressions:
  - key: policy-exempt
    operator: NotIn
    values: ["true"]

Excluding System Namespaces by Default

Regardless of the opt-in or opt-out model chosen for application namespaces, most webhook selection design explicitly excludes kube-system, kube-public, and the webhook's own operating namespace, since applying application-oriented policy to control-plane or infrastructure components is rarely intended and can introduce circular dependencies.


Selection via objectSelector

Targeting Individual Objects Regardless of Namespace

objectSelector operates on the labels of the object itself rather than its containing namespace, useful when the decision of whether a webhook should apply depends on characteristics of the specific workload rather than a blanket namespace-level policy — for instance, only pods explicitly labeled tier: frontend receiving a particular sidecar, even within a namespace containing many different workload types.

objectSelector:
  matchExpressions:
  - key: tier
    operator: In
    values: ["frontend", "gateway"]

Combining Both Selectors

namespaceSelector and objectSelector can be used together on the same webhook, in which case both must match for the webhook to be invoked — a pattern used when a feature should only be available in namespaces that have opted in, and even then, only for objects within those namespaces that are further labeled to request it.


Designing a Maintainable Label Taxonomy

Consistent, Documented Label Keys

Because selection depends entirely on label presence and value, establishing a small, consistent, documented set of label keys used specifically for webhook selection (distinct from labels used for other purposes such as cost allocation or ownership) keeps selection behavior predictable and avoids accidental matches caused by label reuse across unrelated purposes.

Avoiding Selector Sprawl Across Many Webhooks

When multiple independently-owned webhooks each define their own selection labels without coordination, a single namespace or object can end up subject to an unpredictable combination of policies that is difficult to reason about as a whole; centralizing selection label conventions, even across teams owning different webhooks, keeps the aggregate selection behavior auditable.


Verifying Selection Behavior

Testing Against Representative Labels

Before relying on a webhook's selection logic in production, applying test objects and namespaces with the full range of expected label combinations and confirming the webhook fires (or does not fire) as intended catches selector logic errors — a matchExpressions operator error (In versus NotIn, for instance) is a common and easy mistake to make.

kubectl label namespace test-ns mesh-injection=enabled --dry-run=client -o yaml

Auditing What Is Currently Selected

Listing all namespaces and objects matching a webhook's current selector configuration gives a concrete view of its actual current scope, which is more reliable than inferring scope from the selector's YAML definition alone, especially in a cluster where labels are applied by multiple teams independently over time.

kubectl get namespaces -l mesh-injection=enabled

Selection as an Ongoing Governance Concern

Reviewing Selection Scope as the Cluster Evolves

As new namespaces and workloads are created, whether they fall inside or outside a given webhook's selection criteria depends entirely on the labels applied to them at creation time; periodically confirming that newly created namespaces and objects receive the labels their team intended (through templating, policy enforcement, or manual review) prevents silent gaps in coverage from accumulating unnoticed.