Mastering Kubernetes Security — My Journey With Admission Controllers
From Novice to CKS Ready

Kubernetes contains an extension point known as Admission Controllers. They are the gatekeepers of your Kubernetes cluster, overseeing all resource requests that come in and go out. Beyond mere surveillance, these controllers act as sophisticated filters.
They can enforce your organization’s policies, ensure compliance, and modify requests to align with predefined standards.
This article, the fourth in our series on Kubernetes Security, centers on admission controllers.
As I progress towards earning the Certified Kubernetes Security (CKS) certification, I delve into the significance of admission controllers, highlighting their importance in the “Minimize Microservice Vulnerabilities” segment of the CKS curriculum.

What Are Admission Controllers?
Admission controllers play a pivotal role in the Kubernetes ecosystem, acting as the gatekeepers to the Kubernetes API server.
Admission controllers are invoked after a request is authenticated and authorized before the object is persisted in the Kubernetes cluster. Their primary function is to intercept and process requests, ensuring the cluster’s operational integrity and security are maintained.
In the context of Kubernetes, admission controllers are essentially plugins that govern and enforce how the cluster is used. They evaluate requests to the Kubernetes API server, such as creating, modifying, or deleting resources, against pre-defined rules and policies.
Two types of admission controllers: Mutating and Validating
Admission controllers can be classified into two main types: mutating and validating.

Mutating admission controllers can modify the objects they admit. This means they can alter the request’s content before it is processed by the Kubernetes API server, ensuring that the object adheres to specific rules or enhancing the object with additional metadata.
For example, a mutating admission controller might automatically inject sidecar containers into pods to ensure logging or monitoring agents are present in all workloads.
On the other hand, validating admission controllers do not modify the objects. Instead, they check to ensure the request meets all the required criteria. For example, to guarantee that a deployment uses the latest version of an image.
If a request fails these checks, the validating admission controller rejects the operation, and the object is not created, modified, or deleted.
This process is crucial for enforcing organizational policies and ensuring that only compliant and secure configurations are applied to the cluster.
While you can create custom admission controllers tailored to your specific needs, your Kubernetes cluster already has a suite of built-in admission controllers.
The following section will explore these pre-configured controllers' roles and functionalities.
Built-in Admission Controllers in Kubernetes
A default Kubernetes installation automatically contains and activates a suite of built-in admission controllers. For most administrators and users, there’s little need to tinker with these controllers, including disabling any enabled by default.
However, should the need arise to customize your cluster’s behavior or verify which admission controllers are active, Kubernetes provides a straightforward method to do so directly from your control plane.
To list the currently enabled admission controllers, execute the following command in your control plane’s terminal:
kube-apiserver -h | grep enable-admission-plugins
Here’s an overview of some key admission controllers installed by default and their contributions to the Kubernetes ecosystem. The admission controllers vary per Kubernetes version; these are the ones that are built-in in v1.29.
- NamespaceLifecycle — Ensures that requests to a namespace that is being deleted are blocked and that no new namespaces can be created if they match a reserved name. It’s crucial for maintaining the integrity of namespace-specific resources during their lifecycle.
- LimitRanger — Applies constraints specified by a
LimitRange
object to Pod, Container, and PersistentVolumeClaim resources within a namespace. It ensures that resource usage does not exceed the limits defined by administrators, promoting efficient resource allocation and preventing abuse. - ServiceAccount — Automatically attaches a default service account to pods that do not have an explicit
ServiceAccount
specified. This is important for managing permissions and ensuring pods can access the Kubernetes API securely with the appropriate level of access. - PersistentVolumeClaimResize — Allows for resizing existing PersistentVolumeClaims (PVCs) without needing to recreate them. This feature supports dynamic volume resizing, making it easier to adjust storage resources as application requirements change.
- PodSecurity — Enforces the Pod Security Standards, which are predefined security settings for Pods. This controller can prevent the creation of Pods that do not meet the specified security requirements, significantly reducing the risk of security vulnerabilities within the cluster.
- MutatingAdmissionWebhook and ValidatingAdmissionWebhook — These webhooks allow for custom admission policies enforced by external services. We will be discussing them in the upcoming section about Dynamic Admission Control.
- ResourceQuota — Enforces resource quota limits within a namespace, covering CPU, memory, storage, and count-based resources like pods, services, and more. This prevents a single namespace from consuming more than its fair share of cluster resources, promoting fair usage across all services and users.
- Priority — Determines the scheduling priority of pods based on PriorityClass names. This helps prioritize pod scheduling based on the criticality of the applications they represent, ensuring that critical applications have the resources they need to perform optimally.
- RuntimeClass — Supports the selection of container runtime configurations. This allows different container runtimes for pods, facilitating runtime-specific features and optimizations.
- DefaultStorageClass, DefaultIngressClass, and DefaultTolerationSeconds — These controllers automatically set default values for storage class, ingress class, and toleration seconds for pods, respectively, if not explicitly specified. They simplify configurations and ensure that default policies are consistently applied across the cluster.
Dynamic Admission Control in Kubernetes: Enhancing Cluster Security and Management
Dynamic Admission Control is a powerful mechanism to enforce custom policies and streamline cluster management through two pivotal components: the MutatingAdmissionWebhook
and the ValidatingAdmissionWebhook
.
Understanding Dynamic Admission Controllers
Dynamic Admission Controllers come in two flavors: MutatingAdmissionWebhook and ValidatingAdmissionWebhook. These controllers serve as gatekeepers, allowing or denying requests to the Kubernetes API server based on custom policies defined by external services.
MutatingAdmissionWebhook: The Transformer
The MutatingAdmissionWebhook
is a mutating admission controller, and as we saw in the previous section, they are designed to modify or mutate the incoming request before the Kubernetes API server processes it. This capability is handy for scenarios like:
- Injecting sidecar containers: Automatically adding auxiliary containers to pods, which can be used for logging, monitoring, or network traffic control.
- Altering configurations: Modifying pod specifications to adhere to organizational standards, such as adding labels or environment variables.
ValidatingAdmissionWebhook: The Gatekeeper
On the other hand, the ValidatingAdmissionWebhook
is a validating admission controller that focuses on validating the requests against predefined rules before allowing them to proceed. It plays a crucial role in:
- Enforcing custom resource quotas: Ensuring that resource creation does not exceed the limits set by organizational policies.
- Validating custom security policies: Checking configurations to comply with security standards, such as ensuring containers run as non-root users.
Implementing Webhook Admission Controllers
There are two approaches for integrating or developing custom admission controllers. The traditional method involves creating a custom admission controller using a programming language like Go, which offers robust control but requires deep Kubernetes ecosystem knowledge.
Alternatively, Kubernetes provides a more accessible option through webhook admission controllers, namely MutatingAdmissionWebhook
and ValidatingAdmissionWebhook
. These allow developers to introduce custom admission logic by implementing a REST API service with which the Kubernetes API server can communicate via webhooks.
Deployment Flexibility
The REST API service hosting your webhooks can be deployed either inside your Kubernetes cluster or externally, depending on the constraints and capabilities provided by your Kubernetes service provider. This flexibility supports a wide range of deployment scenarios and architectural designs.
Language Agnosticism
One of the significant advantages of webhook-based controllers is their language-agnostic nature. Developers can implement the REST API service in their preferred programming language, whether Node.js, Java, C#, or any other, fostering a broader adoption and customization based on team expertise.
Operational Mechanics
Both types of webhooks operate by interacting with serialized AdmissionReview
objects in JSON format. The ValidatingAdmissionWebhook
should consume the object to make allow/deny decisions.
At the same time, the MutatingAdmissionWebhook
may alter the request payload, offering a versatile mechanism to enforce or modify the behavior of Kubernetes resources dynamically.
You can find various examples on GitHub that demonstrate the implementation of webhooks. For example, this one uses Python. https://github.com/garethr/kubernetes-webhook-examples
Admission Controllers and CKS Exam Preparation
In my journey to conquer the CKS (Certified Kubernetes Security Specialist) exam, I’ve hit the section on Admission Controllers, tucked under the umbrella of minimizing microservice vulnerabilities.
I haven’t sat for the exam yet, but I’m betting it won’t ask me to whip up a custom admission controller from scratch or get into the nitty-gritty of coding a webhook for validation.
Instead, I’m bracing myself for the more likely challenge: figuring out which admission controllers are switched on or off and knowing how to tweak those settings. It aligns more with what the CKS is all about — practical, hands-on skills that real-world Kubernetes security demands.
Wrapping Up: The Gatekeepers of Kubernetes
Before starting my CKS exam preparation, I didn’t even know admission controllers existed. Now, I’ve used a couple of them to add some default stuff, like labels, to my deployments.
Throughout my studies, I’ve discovered many tools and implementations leveraging admission controllers for various tasks. For instance, it’s possible to integrate container image scanning with an admission controller, allowing you to ensure that only the latest version of a specific image is used.
Moreover, some tools build upon the foundation of admission controllers, adding a layer that simplifies the implementation of specific security policies using custom policy description languages.
One such tool is OPA, or Open Policy Agent, which I’ve found is also a requirement for the CKS exam. I plan to dive into OPA in my next article.
Happy studying!