writing

Kubernetes security fundamentals: Admission Control

September 5, 2024

Kubernetes Security Fundamentals: Admission Control

In the previous post in this series, we took a look at Kubernetes authorization. In this post we'll take a look at admission control, another key aspect of Kubernetes security.

Admission control is the last of the three stages that requests go through when they're being processed by a Kubernetes cluster. Assuming that the request has valid credentials and is authorized, Kubernetes admission controllers will process the request and may modify or reject it during that process.

Kubernetes authentication, authorization, and admission control

Some form of admission control is typically a security requirement for production clusters that allow users access to create new workloads—without it, it's possible for users to create pods that allow for full access to underlying cluster nodes, which is not desirable.

Admission control overview

Admission controllers are responsible for implementing policies in Kubernetes clusters by either validating requests to make sure the meet a requirement or mutating (changing) them to meet a requirement. They are a combination of internal admission controllers which are provided by Kubernetes and external admission control solutions that are typically implemented as webhooks—these are called when a request to the Kubernetes API meets specific requirements.

It’s important to note the order in which admission controller rules are applied. First, each mutating admission controller is applied sequentially, so any changes are applied before the next one is called. Next, after all changes have been applied, the object schema is validated to ensure it has required fields. Then validating admission controls are applied—here, the checks are made in parallel, since the object won't change between checks.

Flow of mutating and validating admission controllers

One important restriction of admission control is that it can't be applied to every request to the Kubernetes API—specifically, get, list, and watch requests are not sent to admission control. This restriction prevents admission control being used as a general access control or auditing mechanism, since it doesn't see every request.

Internal admission controllers

Kubernetes provides a set of admission controllers that users can enable and make active on any cluster. In unmanaged Kubernetes distributions, the cluster operator can choose which of these to enable via command line flags on the API server. In managed Kubernetes distributions, the provider will typically make that choice, and it generally won't be possible to change it.

There is a set of admission controllers that are enabled by default, though this set can change depending with the release of each new Kubernetes version. The current list of default admission controllers is here.

An example of a validating admission controller that is enabled by default is PodSecurity. This controller works in conjunction with the PodSecurityAdmission (PSA) feature of Kubernetes to ensure that workloads meet specified security requirements and reject them if they do not. PSA was introduced in Kubernetes 1.25 as a replacement for the pod security policy that was removed in that version.

An example of a mutating admission controller that is enabled by default is ServiceAccount. This controller modifies workloads being admitted to a cluster by adding the correct service account information and volume mounts, according to the standard rules.

External admission controllers

In addition to internal admission controllers, Kubernetes allows cluster operators to specify their own admission control checks using one of two Kubernetes object types: ValidatingWebhookConfiguration and MutatingWebhookConfiguration. By creating one of these objects a cluster operator can specify an external service that will be called whenever the criteria specified in the object are met. For example, you could set up a specific external admission controller that will be called whenever a user creates a pod in a specific namespace.

With external admission control, it's important to limit the number of users who can create or modify these objects in the Kubernetes API, as they can effectively remove security controls or add a malicious webhook that modifies user workloads as they're admitted to the cluster.

Risks of implementing external admission control

When implementing external admission control, there are some security considerations to take into account, as these systems typically run with high privileges, receiving sensitive data from the cluster and in the case of mutating admission controllers being able to make changes to cluster objects. This makes them an obvious target for attackers.

First, you’ll need to consider whether you want the admission controller to fail open or closed. This decision will likely depend on the threat model of your cluster. You can configure this setting using the failure policy configuration option. You can either have your cluster ignore the failure or deny the admission of the object. If the cluster ignores the failure, an attacker might be able to create a denial-of-service condition in the webhook and then bypass its restrictions. However, if this option is set to "fail," then a fault with the admission controller could prevent users from creating any new objects in the cluster.

You’ll also have to consider whether to run the admission controllers inside the cluster they’re protecting. Deploying inside the cluster is easier from an ease of implementation standpoint, but it presents the risk that an attacker who gets access to a cluster node running the admission controller could disrupt its operation or modify the rules it applies.

You can find some additional risks to consider, as well as security best practices for deploying external admission controllers, in this Kubernetes blog post and the admission control threat model.

Using admission control for pod security

One of the main reasons to use admission controllers from a security perspective is to restrict what users can do and when they deploy workloads to the cluster. Without admission control, it's easy to escalate privileges to gain access to underlying nodes—and potentially the entire cluster—for instance, by scheduling a privileged pod.

There are three main options for applying pod security restrictions to workloads as they're admitted to the cluster.

The first is pod security admission, which applies one of three levels of restriction to each namespace in the cluster. These levels, defined by pod security standards, are:

  • Privileged, which is unrestricted
  • Baseline, which contains restrictions that attempt to address the main risks of privilege escalation from workloads
  • Restricted, which locks down pods even further but is more likely to cause compatibility issues with workloads that need access to host resources.

Pod security admission is relatively simple to implement—however, it is not very flexible, particularly for cases in which a cluster needs to allow specific rights to workloads without giving them unrestricted access to the cluster node's resources.

The second option is to use the recent validating admission policy capability. This feature is generally available as of Kubernetes 1.30 and allows cluster operators to define specific policy restrictions that they can apply to workloads using Common Expression Language (CEL). This option provides a lot more flexibility than pod security admission, catering to a wider range of use cases. However, it does not currently allow for mutation of workloads, although this capability is planned for the future.

The third option is to make use of external admission controllers for pod security. This is probably the most common choice, as it was the only way to get a flexible level of control until very recently. There are a wide range of external systems available, including options like Kyverno and OPA Gatekeeper. Some distributions also come with a built-in admission control option, like Azure Policy for Kubernetes, which is based on OPA Gatekeeper.

Conclusion

Admission control plays a very important part in Kubernetes security, as it allows operators to apply specific policies to clusters. To make the best use of admission control, it's important to understand its limitations, as well as some of the risks inherent in implementing external admission controllers.

In the next post in this series, we'll take an in-depth look at network security in Kubernetes.

Did you find this article helpful?

Subscribe to the Datadog Security Digest

Get Security Labs posts, insights from the cloud security community, and the latest Datadog security features delivered to your inbox monthly. No spam.

Related Content