11501
views
✓ Answered

Kubernetes v1.36: Immutable Admission Policies via Static Manifests

Asked 2026-05-06 04:25:46 Category: Programming

Kubernetes admission policies are essential for enforcing security and governance across clusters, but they have long suffered from two critical weaknesses: a bootstrap gap where policies aren't active immediately, and vulnerability to deletion by privileged users. The v1.36 release introduces an alpha feature that tackles both issues head-on: manifest-based admission control. This mechanism allows administrators to define admission webhooks and CEL-based policies as static files on disk, loaded by the API server at startup—before any requests are processed. This ensures your policies are active from the very first moment and cannot be removed through the API, closing a major security hole.

What is the bootstrap gap in Kubernetes admission policies?

When a Kubernetes cluster starts or recovers from a failure (like an etcd restore), the API server begins serving requests immediately. However, admission policies—such as ValidatingAdmissionPolicies or webhook configurations—are API objects themselves. They only exist after someone creates them via a request. This creates a window of time when no policies are active, leaving the cluster unprotected. During bootstrap or disaster recovery, this gap can be significant because the policies themselves need to be recreated or restored. Even in steady state, a privileged user could delete critical admission policies, and because Kubernetes skips webhooks on their own configuration types (to avoid circular dependencies), there is no built-in protection. The result: your most important security rules can be turned off without any alert or prevention.

Kubernetes v1.36: Immutable Admission Policies via Static Manifests

How does Kubernetes v1.36 solve the bootstrap and deletion problem?

Kubernetes v1.36 introduces an alpha feature called manifest-based admission control. Instead of relying solely on API objects, you can now store admission policies as YAML files on disk. The API server loads these files from a directory specified in the AdmissionConfiguration file—passed via the --admission-control-config-file flag—before it starts serving any requests. This means policies are active from the instant the server starts, closing the bootstrap gap. Moreover, because these policies are not API objects, they cannot be deleted through the Kubernetes API. Even a cluster admin with full permissions would be unable to remove them without modifying the files on disk. This provides a robust guarantee that critical policies are always enforced.

How do you configure static admission policies in practice?

To use static admission policies, you add a staticManifestsDir field to your existing AdmissionConfiguration file. This file is supplied to the API server with the --admission-control-config-file flag. The value of staticManifestsDir is a path to a directory containing YAML files. For example:

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

Place your standard Kubernetes policy YAML definitions (e.g., ValidatingAdmissionPolicy objects) in that directory. The API server will read all files from the directory and load the policies before it processes any user requests. There is no need for separate API creation steps.

What naming convention must static policy manifest files follow?

All objects defined in the static manifest files must have names ending with the reserved suffix .static.k8s.io. For instance, a ValidatingAdmissionPolicy resource could be named deny-privileged.static.k8s.io. This suffix serves two purposes:

  • Prevents collisions with admission policies that are created via the API (which cannot end with .static.k8s.io), ensuring clear separation.
  • Enables easy identification in metrics, audit logs, and troubleshooting—when you see the suffix, you know the policy came from a static manifest rather than an API object.

This simple convention makes it straightforward to distinguish between policies that are immutable (from disk) and those that can be modified or deleted through the API.

Can you show a complete example of a static admission policy?

Below is a full YAML example of a ValidatingAdmissionPolicy that denies privileged containers outside the kube-system namespace, intended to be placed in the static manifests directory:

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.securityContext.privileged == true && namespace != 'kube-system')"
      message: "Privileged pods are only allowed in the kube-system namespace."

This policy is loaded at API server startup and enforces the rule immediately. Because its name ends with .static.k8s.io, it cannot be overridden or deleted via the API.

What are the key benefits of static admission policies for cluster operators?

Static admission policies offer several compelling advantages:

  1. Elimination of the bootstrap gap – Policies are active before the server processes any user requests, so there is no unprotected window during cluster startup or after disaster recovery.
  2. Immunity to deletion – Because the policies are loaded from disk and not created as API objects, even cluster administrators cannot remove them through normal API calls. This provides a foundational layer of security.
  3. Simplified bootstrapping – You no longer need to orchestrate policy creation after the API server starts; just place the files in the configured directory and they are automatically applied.
  4. Clear audit trails – The .static.k8s.io suffix makes it obvious which policies come from static manifests, aiding debugging and compliance.
  5. Better self-protection – Critical policies like “no one can delete admission webhooks” can now be enforced at a level that cannot be bypassed.

Overall, this feature closes a long-standing architectural gap in Kubernetes admission control, making it more reliable for security-sensitive environments.