Admission Basics
This page walks through the concrete objects and commands for admission control: the built-in gate, the two webhook configurations, and the in-process CEL policy. Each example is a small, runnable starting point you can adapt.
Search across all documentation pages
This page walks through the concrete objects and commands for admission control: the built-in gate, the two webhook configurations, and the in-process CEL policy. Each example is a small, runnable starting point you can adapt.
kubectl matching your cluster minor.kubectl apply and namespaces.Quick check that admission plug-ins are active:
kubectl api-resources | grep -i admission
kubectl get validatingwebhookconfigurations,mutatingwebhookconfigurationsPod Security Admission is a built-in validating controller. Label a namespace restricted and it rejects privileged Pods.
kubectl create namespace demo
kubectl label namespace demo \
pod-security.kubernetes.io/enforce=restrictedPodSecurity admission controller for that namespace.enforce blocks; warn and audit only report.Apply a Pod that violates the restricted profile and read the error.
kubectl -n demo run bad --image=nginx --restart=Neverforbidden error describing the violated fields.kubectl get pod bad shows nothing.Webhook configurations are cluster-scoped objects that route writes to an endpoint.
kubectl get validatingwebhookconfigurations -o yaml | head -40webhooks[].rules lists the apiGroups, resources, and operations intercepted.clientConfig points to a Service or URL plus the CA bundle.failurePolicy decides behavior when the endpoint is unreachable.namespaceSelector and objectSelector narrow the match.These two fields control availability risk. Know them before you deploy any webhook.
webhooks:
- name: validate.example.com
failurePolicy: Fail # Fail = reject on error; Ignore = allow
timeoutSeconds: 5 # max 30
sideEffects: None
admissionReviewVersions: ["v1"]failurePolicy: Fail is stricter but can wedge writes if the webhook is down.timeoutSeconds caps how long the API server waits per call.sideEffects: None tells the API server the webhook does not mutate external state.admissionReviewVersions must include v1.Excluding control-plane namespaces is the single most important safety step.
namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: NotIn
values: ["kube-system", "kube-node-lease"]kubernetes.io/metadata.name label.kube-system keeps core controllers writable during a policy outage.objectSelector to skip specific labeled objects.The in-process path needs no external service. Define a policy and bind it to namespaces.
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
name: require-limits
spec:
matchConstraints:
resourceRules:
- apiGroups: ["apps"]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["deployments"]
validations:
- expression: >-
object.spec.template.spec.containers.all(c,
has(c.resources.limits))
message: "every container must set resources.limits"matchConstraints selects which writes the policy evaluates.validations[].expression is CEL that must return true to allow.A ValidatingAdmissionPolicyBinding connects the policy to a scope and enforcement action.
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
name: require-limits-binding
spec:
policyName: require-limits
validationActions: ["Deny"]
matchResources:
namespaceSelector:
matchLabels:
team: paymentsvalidationActions can be Deny, Warn, or Audit.matchResources narrows the binding to labeled namespaces.Warn or Audit to measure impact before switching to Deny.Mutating webhooks patch objects. This snippet shows the configuration side; the endpoint returns a JSONPatch.
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: add-default-labels
webhooks:
- name: mutate.example.com
reinvocationPolicy: IfNeeded
failurePolicy: Ignore
sideEffects: None
admissionReviewVersions: ["v1"]
clientConfig:
service:
name: policy-webhook
namespace: policy-system
path: /mutate
caBundle: <base64-ca>
rules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE"]
resources: ["pods"]reinvocationPolicy: IfNeeded re-runs the webhook if another mutation changes the object.caBundle lets the API server trust the endpoint's TLS cert.Kyverno and Gatekeeper install as webhooks. After a Helm install, verify the configurations exist.
helm install kyverno kyverno/kyverno -n kyverno --create-namespace
kubectl get validatingwebhookconfigurations | grep kyverno
kubectl get pods -n kyvernofailurePolicy.Server-side dry-run runs the full admission chain without persisting the object.
kubectl apply -f deployment.yaml --dry-run=server--dry-run=server executes mutating and validating admission, then discards the result.--dry-run=client, it reflects the actual policies installed.Stack versions: This page was written for Kubernetes 1.36.2, Docker Engine 29.6.1 (BuildKit default), containerd (CRI runtime on nodes), Helm 3, Compose v2, Argo CD (latest - verify at build), and Gateway API (GA - verify controller support at build).
Reviewed by Chris St. John·Last updated Jul 16, 2026