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
- Read more: AI Bills Plummet: Code Graph Slashes Tokens
- Read more: V8’s Hash Riddle: Security vs. Speed