Kubernetes v1.36: Securing Admission Policies with Manifest-Based Control

By ✦ min read

The Challenge of Protecting Admission Policies

Admins who have attempted to uniformly enforce security rules across multiple Kubernetes clusters quickly encounter a classic chicken-and-egg dilemma. Admission policies are themselves API objects — they don't exist until someone creates them, and any user with sufficient permissions can delete them. This leaves a window of vulnerability during cluster initialization when policies are not yet active, and there is no mechanism to prevent a privileged user from removing critical policies after they are deployed.

Kubernetes v1.36: Securing Admission Policies with Manifest-Based Control

Kubernetes v1.36 introduces an alpha feature designed to close this gap: manifest-based admission control. This approach allows you to define admission webhooks and CEL-based policies as files on disk, which the API server loads at startup before it begins serving any requests. Once loaded, these policies cannot be altered or removed through the API — they are effectively immutable from the cluster’s perspective.

Closing the Bootstrap Gap

Most Kubernetes policy enforcement today relies on the API layer. You create a ValidatingAdmissionPolicy or a webhook configuration as an API object, and the admission controller picks it up. While this works well in steady state, it has fundamental limitations. During cluster bootstrap — for example, when restoring from a backup or recovering from an etcd failure — there is a delay between the API server starting and the policies becoming active. That delay can be significant, leaving the cluster exposed.

There is also a self-protection problem. Admission webhooks and policies cannot intercept operations on their own configuration resources. Kubernetes intentionally skips invoking webhooks on types like ValidatingWebhookConfiguration to avoid circular dependencies. Consequently, a user with enough privileges can delete your essential admission policies, and the admission chain offers no protection.

As the Kubernetes SIG API Machinery team explains: “We wanted a way to say ‘these policies are always on, full stop.’”

How Manifest-Based Admission Control Works

The new feature adds a staticManifestsDir field to the AdmissionConfiguration file that you already pass to the API server via --admission-control-config-file. Point it at a directory, drop your policy YAML files in there, and the API server loads them before it starts serving requests.

apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: ValidatingAdmissionPolicy
  configuration:
    apiVersion: apiserver.config.k8s.io/v1
    kind: ValidatingAdmissionPolicyConfiguration
    staticManifestsDir: "/etc/kubernetes/admission/validating-policies/"

The manifest files are standard Kubernetes resource definitions. The only special requirement is that all objects defined in these manifests must have names ending with .static.k8s.io. This reserved suffix prevents collisions with API-based configurations and makes it easy to identify the source of an admission decision in metrics or audit logs.

What Goes in the Manifest Files?

You can include any resource type supported by the admission registration API, such as ValidatingAdmissionPolicy, MutatingAdmissionPolicy, or ValidatingWebhookConfiguration. Each file contains a standard Kubernetes resource YAML. Once placed in the directory and the API server restarted, those policies become active immediately — with no ability to delete or modify them through the API.

Concrete Example: Denying Privileged Pods

Here is a complete example that denies privileged containers from running outside the kube-system namespace, using a ValidatingAdmissionPolicy stored as a static manifest:

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
  name: "deny-privileged.static.k8s.io"
  annotations:
    kubernetes.io/description: "Deny launching privileged pods, anywhere this policy is applied"
spec:
  failurePolicy: Fail
  matchConstraints:
    resourceRules:
      - apiGroups: [""]
        apiVersions: ["v1"]
        operations: ["CREATE", "UPDATE"]
        resources: ["pods"]
  validations:
    - expression: "object.spec.containers.all(c, !has(c.securityContext) || !c.securityContext.privileged)"
      message: "Privileged containers are not allowed outside kube-system"

This policy ensures that no pod with privileged containers can be created or updated in any namespace other than kube-system. Because it is loaded from a static manifest, it cannot be deleted or bypassed after the cluster is running.

Implications for Cluster Operators

Manifest-based admission control provides a robust layer of defense for the chicken-and-egg problem we started with. Operators can now bake essential policies directly into the cluster bootstrap process, ensuring they are active from the very first request. This is especially valuable for:

The feature is still in alpha in v1.36, so it requires enabling the AdmissionWebhookMatchConditions feature gate (or the appropriate gate for your version). Once activated, however, it offers a straightforward path to tamper-proof policy enforcement — exactly what the SIG set out to deliver.

By moving from API-object-only policies to a combination of API and manifest-based policies, Kubernetes now closes a long-standing vulnerability. Your admission policies can finally be “always on, full stop.”

Tags:

Recommended

Discover More

Chainsaw Man: Rez Arc and Pixar's Hoppers Headline This Weekend's Streaming ReleasesHow to Build Your Own Lego Sega Genesis: A Step-by-Step GuideStranger Than Heaven: Your Guide to the Yakuza Prequel's Surprising Cast10 Key Insights into Ana Inês Inácio's Journey Shaping Wireless TechnologyHow to Future-Proof Your Career with Coursera's 2026 AI and Human Skills Programs