Kubernetes v1.36: Static Admission Policies That Cannot Be Removed

Kubernetes administrators have long struggled with a fundamental paradox: the very policies meant to secure your cluster are themselves vulnerable to deletion or circumvention during critical moments. Admission policies, whether they're validating webhooks or CEL-based rules, are API objects that only come into existence after a user creates them—and any user with sufficient permissions can remove them. This creates two dangerous gaps: one during cluster startup when no policies exist yet, and another when a privileged actor deletes essential policies. Kubernetes v1.36 introduces an alpha feature that solves both problems at once: manifest-based admission control. By loading policy configurations directly from disk before the API server accepts any requests, these policies become effectively immutable and always active.

What problem does manifest-based admission control solve?

Traditional Kubernetes admission policies rely on the API itself—you create a ValidatingAdmissionPolicy or a webhook configuration as an API object, and the admission controller picks it up. While this works fine in a steady state, it creates two critical vulnerabilities. First, during cluster bootstrap, there's an unavoidable window between when the API server starts serving requests and when your policies are created and active. If you're recovering from an etcd backup or restoring a cluster, that window can be painfully long. Second, admission policies cannot protect themselves. Kubernetes deliberately skips invoking webhooks on configuration resources like ValidatingWebhookConfiguration to avoid circular dependencies. This means a sufficiently privileged user can delete your critical admission policies, and no admission chain can stop them. Manifest-based admission control closes both gaps by loading policies from disk at startup, before any API requests are served, making them always present and effectively non-deletable.

Kubernetes v1.36: Static Admission Policies That Cannot Be Removed

How does manifest-based admission control work?

The mechanism is straightforward. You add a staticManifestsDir field to your existing AdmissionConfiguration file—the one you already pass to the API server via the --admission-control-config-file flag. Point this field at a directory containing your policy YAML files, and the API server loads those manifests during initialization, before it begins accepting any client requests. Here's an example configuration 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/"

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

What is the naming requirement for static policies?

All manifest-based policies must have names ending with the reserved suffix .static.k8s.io. For example, deny-privileged.static.k8s.io. This suffix serves two important purposes. First, it guarantees uniqueness: no API-created policy can use that suffix, so there's no risk of name collisions between static and dynamic policies. Second, it makes auditing transparent. When you examine admission metrics or review audit logs, you can immediately tell that a particular admission decision came from a static manifest rather than an API-based object. This clarity is invaluable for troubleshooting and compliance. The suffix is enforced by the API server during validation—if you omit it, the manifest will be rejected.

Can static policies be deleted or modified through the API?

No. That's the whole point. Because static policies are loaded from disk before the API server starts serving requests, they are not part of the Kubernetes API object model. You cannot delete, update, or patch them via kubectl, the REST API, or any client. They live outside the API's reach. If you need to change a static policy, you must modify the YAML file on the server's filesystem and restart the API server. This immutability guarantees that even a cluster administrator with full permissions cannot accidentally or maliciously remove a critical admission policy. The only way to disable a static policy is to remove its manifest file from the designated directory and restart the API server. This design fundamentally changes the security posture for clusters that require hardened policy enforcement.

What kind of policies can be declared as static manifests?

The alpha feature in v1.36 supports both ValidatingAdmissionPolicy (CEL-based) and ValidatingWebhookConfiguration objects. In other words, you can define policy rules using Common Expression Language (CEL) directly in YAML files, or you can point to external webhook endpoints that perform validation. The static manifest approach works identically for both types—you place the YAML definitions in the configured directory, and the API server loads them at startup. For CEL-based policies, you write the rule logic inline within the policy definition. For webhooks, you specify the webhook server URL and configuration. This flexibility means you can enforce security rules like “deny privileged containers outside kube-system” or “require specific pod security standards” without relying on any API calls. The example from the Kubernetes project shows a policy that denies privileged pods in any namespace except kube-system, using the name deny-privileged.static.k8s.io.

Are there any limitations or risks with static admission policies?

Because this is an alpha feature, there are several important caveats. First, it requires explicit opt-in via the --admission-control-config-file flag and configuration of the staticManifestsDir field. Second, as with any alpha feature, the API and behavior may change in future releases—do not rely on it for production clusters without understanding the upgrade implications. Third, since static policies are external to the API, you lose the ability to dynamically update them without restarting the API server. This means policy changes require a server restart, which can be disruptive in high-availability setups. Fourth, you must carefully manage the filesystem permissions on the manifest directory to prevent unauthorized modification. Finally, because static policies are loaded before the API server serves requests, they must be syntactically correct—any error in the YAML will cause the API server to fail to start. Always validate your manifest files using tools like kubeconform or dry-run against a test cluster before placing them in production.

How does this feature improve cluster security and bootstrap resilience?

The static admission policy feature directly addresses two of the most frustrating security gaps in Kubernetes clusters. During bootstrap, when you're starting a fresh cluster or recovering from an etcd failure, there is often a chaotic period where no admission policies are active. Attackers or misconfigurations can exploit this window to deploy privileged workloads before any policy enforcement kicks in. With static manifests, your policies are present from the very first request, closing that window completely. Similarly, the self-protection problem is eliminated: no user, even with cluster-admin privileges, can delete or alter a static policy through the API. This prevents insider threats and accidental deletions from causing security drift. For organizations subject to compliance requirements (like PCI-DSS or SOC2), this feature provides a verifiable way to enforce that certain policies are “always on” and never bypassed. The reserved naming suffix also enhances auditability, making it clear which policies are immutable.

Tags:

Recommended

Discover More

10 Crucial Facts About the Increasingly Competitive NIH Grant LandscapeCloudflare Unveils Optimized Global Network for Large Language Model Inference10 Essential Insights About the DJI Osmo 360: The Ultimate Action Camera AlternativeManufacturing Enters Simulation-First Era as OpenUSD Bridges Digital and Physical WorldsBeyond the Jolt: How Coffee Transforms Your Gut and Brain