DevOps & Infrastructure

Kubernetes v1.36: Immutable Admission Policies Gain Traction

The perpetual cat-and-mouse game of securing Kubernetes clusters just got a significant upgrade. Kubernetes v1.36 is quietly rolling out a feature that could fundamentally alter how we enforce policies.

Kubernetes v1.36: Immutable Admission Policies Arrive — Open Source Beat

Key Takeaways

  • Kubernetes v1.36 introduces manifest-based admission control, loading policies from disk at API server startup.
  • This feature aims to close security gaps during cluster bootstrapping and protect against deletion of critical admission policies.
  • Policies defined via static manifests are designed to be undeletable through the API, addressing self-protection vulnerabilities.

The hum of a production Kubernetes cluster, a symphony of ephemeral workloads and ever-shifting API calls, is easily disrupted. One rogue command, one errant click, and suddenly your carefully crafted security policies — the invisible guardians of your data — can vanish, leaving a gaping, exploitable wound.

For years, this has been the vexing reality for anyone tasked with maintaining sane security postures across distributed Kubernetes environments. You build your defenses, your ValidatingAdmissionPolicies and WebhookConfigurations, only to find they exist as mere API objects. And like all API objects, they’re subject to the whims of anyone with sufficient privilege. This creates a terrifying chicken-and-egg scenario, especially during cluster bootstrapping or recovery: a window where policies don’t yet exist, or worse, can be outright deleted before they can even intercept a malicious operation.

Kubernetes v1.36, however, is nudging the needle with an alpha feature that’s less about a flashy new knob and more about an architectural shift: manifest-based admission control. The core idea? Load your policies directly from files on disk, before the API server even starts serving requests. Think of it as planting the seeds for your security infrastructure before the soil is even prepared to host the requests themselves.

The Ever-Present Vulnerability Window

Most of us have come to accept the model: declare a policy via YAML, apply it to the API server, and trust that the admission controller will dutifully pick it up. This model, while functional in a stable, running system, is inherently fragile. The stated problem by the Kubernetes SIG API Machinery team is stark: there’s a temporal gap. A gap where the API server is live, accepting traffic, but the critical admission policies designed to validate that traffic are still absent or not yet enforced. This isn’t just a theoretical concern; it’s a tangible risk during cluster restores from backups, or worse, after an etcd corruption event where recovery can be a protracted affair.

But the real sting? The self-protection paradox. Admission webhooks and policies, in their traditional API-bound form, can’t police themselves. Kubernetes design intentionally skips invoking webhooks on their own configuration resources—ValidatingWebhookConfiguration, for instance—to sidestep circular dependencies. A privileged user could, in theory, simply delete the very objects that were meant to stop them, leaving the cluster exposed.

It’s a profound architectural weakness. A privileged user could execute kubectl delete validatingwebhookconfiguration my-critical-webhook and watch their troubles evaporate. And without a mechanism to intercept that deletion, the system is fundamentally broken.

The Static Manifest Approach

So, how do you create policies that truly “can’t be deleted?” You bake them into the system’s foundational startup. The new staticManifestsDir field, an addition to the existing AdmissionConfiguration file you already pass to the API server (--admission-control-config-file), is the key.

Point this field to a directory, drop your policy manifests into it, and the API server — crucially — loads them during its initialization sequence, well before it begins accepting inbound requests. The manifests themselves are just standard Kubernetes resource definitions, with one crucial naming convention: all objects defined within these static manifests must have names ending in .static.k8s.io. This isn’t just for show; it’s a deliberate mechanism to prevent naming collisions with dynamically managed, API-driven configurations and to provide a clear signal in audit logs and metrics about the origin of a particular admission decision.

Consider this snippet:

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/"

And here’s the meat: a complete example for denying privileged containers outside the kube-system namespace.

```yaml 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: [


🧬 Related Insights

Jordan Kim
Written by

Infrastructure reporter. Covers CNCF projects, cloud-native ecosystems, and OSS-backed platforms.

Worth sharing?

Get the best Open Source stories of the week in your inbox — no noise, no spam.

Originally reported by Kubernetes Blog

Stay in the loop

The week's most important stories from Open Source Beat, delivered once a week.