# Manifest-Based Admission Control

LLMS index: [llms.txt](/llms.txt)

---

<!-- overview -->








  <div class="feature-state-notice feature-alpha" title="Feature Gate: ManifestBasedAdmissionControlConfig">
              <span class="feature-state-name">FEATURE STATE:</span> 
              <code>Kubernetes v1.36 [alpha]</code>(disabled by default)</div>


This page provides an overview of manifest-based admission control configuration.
Manifest-based admission control lets you load
[admission webhooks](/docs/reference/access-authn-authz/extensible-admission-controllers/)
and CEL-based admission policies from static files on disk, rather than from the
Kubernetes API. These policies are active from API server startup, operate
independently of <a class='glossary-tooltip' title='Consistent and highly-available key value store used as backing store of Kubernetes for all cluster data.' data-bs-toggle='tooltip' data-bs-placement='top' href='/docs/tasks/administer-cluster/configure-upgrade-etcd/' target='_blank' aria-label='etcd'>etcd</a>, and can
protect API-based admission resources from modification.

To use the feature, enable the `ManifestBasedAdmissionControlConfig`
[feature gate](/docs/reference/command-line-tools-reference/feature-gates/#ManifestBasedAdmissionControlConfig) and
configure the `staticManifestsDir` field in the
[AdmissionConfiguration](/docs/reference/config-api/apiserver-config.v1/#apiserver-k8s-io-v1-AdmissionConfiguration)
file passed to the kube-apiserver via `--admission-control-config-file`.

<!-- body -->

## Why use manifest-based admission control?

Admission policies and webhooks registered through the Kubernetes API (such as
ValidatingAdmissionPolicy, MutatingAdmissionPolicy,
ValidatingWebhookConfiguration, and MutatingWebhookConfiguration) have several
inherent limitations:

- **Bootstrap gap**: REST-based policy enforcement requires the API objects to be
  created and loaded by the dynamic admission controller. Until that happens,
  policies are not enforced.
- **Self-protection gap**: Admission configuration resources (such as
  ValidatingWebhookConfiguration) are not themselves subject to webhook
  admission, to prevent circular dependencies. A user with sufficient privileges
  can delete or modify critical admission policies.
- **etcd dependency**: REST-based admission configurations depend on etcd
  availability. If etcd is unavailable or corrupted, admission policies may not
  load correctly.

Manifest-based admission control addresses these limitations by loading
configurations from files on disk. These configurations are:

- Active as soon as the API server is ready to serve requests
- Not visible or changeable through the Kubernetes API
- Independent of etcd availability
- Able to intercept operations on API-based admission resources themselves

## Supported resource types

You can include the following resource types in manifest files. Only the
`admissionregistration.k8s.io/v1` API version is supported.



 





<table><caption style="display: none;">Supported resource types for manifest-based admission control</caption>
	<thead>
			<tr>
					<th style="text-align: left">Plugin name</th>
					<th style="text-align: left">Supported resource types</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td style="text-align: left"><code>ValidatingAdmissionWebhook</code></td>
					<td style="text-align: left">ValidatingWebhookConfiguration</td>
			</tr>
			<tr>
					<td style="text-align: left"><code>MutatingAdmissionWebhook</code></td>
					<td style="text-align: left">MutatingWebhookConfiguration</td>
			</tr>
			<tr>
					<td style="text-align: left"><code>ValidatingAdmissionPolicy</code></td>
					<td style="text-align: left">ValidatingAdmissionPolicy, ValidatingAdmissionPolicyBinding</td>
			</tr>
			<tr>
					<td style="text-align: left"><code>MutatingAdmissionPolicy</code></td>
					<td style="text-align: left">MutatingAdmissionPolicy, MutatingAdmissionPolicyBinding</td>
			</tr>
	</tbody>
</table>


You can also use `v1.List` to wrap multiple resources of the same plugin type
in a single document.

Each admission plugin's `staticManifestsDir` must only contain resource types
allowed for that plugin. For example, a directory configured for the
`ValidatingAdmissionPolicy` plugin can only contain ValidatingAdmissionPolicy
and ValidatingAdmissionPolicyBinding resources.

## Configuring manifest-based admission control {#configuration}

To enable manifest-based admission control, you need:

1. The `ManifestBasedAdmissionControlConfig` feature gate enabled on the
   kube-apiserver.
1. An `AdmissionConfiguration` file with `staticManifestsDir` fields pointing
   to directories containing your manifest files.
1. The manifest files themselves on disk, accessible to the kube-apiserver
   process.

### AdmissionConfiguration

Add `staticManifestsDir` to the plugin configuration for each admission plugin
that should load manifests from disk. Each plugin requires its own directory.


















<div class="highlight code-sample">
    <div class="copy-code-icon">
    <a href="https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/access/manifest-admission-control/admission-configuration.yaml" download="access/manifest-admission-control/admission-configuration.yaml"><code>access/manifest-admission-control/admission-configuration.yaml</code>
    </a><img src="/images/copycode.svg" class="icon-copycode" onclick="copyCode('access-manifest-admission-control-admission-configuration-yaml')" title="Copy access/manifest-admission-control/admission-configuration.yaml to clipboard"></img></div>
    <div class="includecode" id="access-manifest-admission-control-admission-configuration-yaml"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c"># This is an example AdmissionConfiguration that configures all four admission</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c"># plugins to load manifest-based admission control from static files on disk.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">apiserver.config.k8s.io/v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">AdmissionConfiguration</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">plugins</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl">- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">ValidatingAdmissionWebhook</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">configuration</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">apiserver.config.k8s.io/v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">WebhookAdmissionConfiguration</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">kubeConfigFile</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;&lt;path-to-kubeconfig&gt;&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">staticManifestsDir</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/etc/kubernetes/admission/validating-webhooks/&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl">- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">MutatingAdmissionWebhook</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">configuration</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">apiserver.config.k8s.io/v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">WebhookAdmissionConfiguration</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">kubeConfigFile</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;&lt;path-to-kubeconfig&gt;&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">staticManifestsDir</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/etc/kubernetes/admission/mutating-webhooks/&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl">- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">ValidatingAdmissionPolicy</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">configuration</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">apiserver.config.k8s.io/v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">ValidatingAdmissionPolicyConfiguration</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">staticManifestsDir</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/etc/kubernetes/admission/validating-policies/&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl">- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">MutatingAdmissionPolicy</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">configuration</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">apiserver.config.k8s.io/v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">MutatingAdmissionPolicyConfiguration</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">staticManifestsDir</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/etc/kubernetes/admission/mutating-policies/&#34;</span><span class="w">
</span></span></span></code></pre></div></div>
</div>

The `staticManifestsDir` field accepts an absolute path to a directory. All
direct-children files with `.yaml`, `.yml`, or `.json` extensions in the
directory are loaded. Subdirectories and files with other extensions are ignored.
Glob patterns and relative paths are not supported.

Pass this file to the kube-apiserver with the `--admission-control-config-file`
flag.

### Configuration types

Each admission plugin uses a specific configuration kind:



 





<table><caption style="display: none;">Configuration types for each admission plugin</caption>
	<thead>
			<tr>
					<th style="text-align: left">Plugin</th>
					<th style="text-align: left">apiVersion</th>
					<th style="text-align: left">kind</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td style="text-align: left"><code>ValidatingAdmissionWebhook</code></td>
					<td style="text-align: left"><code>apiserver.config.k8s.io/v1</code></td>
					<td style="text-align: left"><code>WebhookAdmissionConfiguration</code></td>
			</tr>
			<tr>
					<td style="text-align: left"><code>MutatingAdmissionWebhook</code></td>
					<td style="text-align: left"><code>apiserver.config.k8s.io/v1</code></td>
					<td style="text-align: left"><code>WebhookAdmissionConfiguration</code></td>
			</tr>
			<tr>
					<td style="text-align: left"><code>ValidatingAdmissionPolicy</code></td>
					<td style="text-align: left"><code>apiserver.config.k8s.io/v1</code></td>
					<td style="text-align: left"><code>ValidatingAdmissionPolicyConfiguration</code></td>
			</tr>
			<tr>
					<td style="text-align: left"><code>MutatingAdmissionPolicy</code></td>
					<td style="text-align: left"><code>apiserver.config.k8s.io/v1</code></td>
					<td style="text-align: left"><code>MutatingAdmissionPolicyConfiguration</code></td>
			</tr>
	</tbody>
</table>


## Writing manifest files {#manifest-files}

Manifest files contain standard Kubernetes resource definitions. You can include
multiple resources in a single file using YAML document separators (`---`).

### Naming convention {#naming}

All objects in manifest files must have names ending with the `.static.k8s.io`
suffix. For example: `deny-privileged.static.k8s.io`.

When the `ManifestBasedAdmissionControlConfig` feature gate is enabled, creation
of API-based admission objects with names ending in `.static.k8s.io` is blocked.
When the feature gate is disabled, a warning is returned instead.


<div class="alert alert-info" role="note"><h4 class="alert-heading">Note:</h4>If two manifest files define objects of the same type with the same name, the
API server fails to start, displaying a descriptive error.</div>


### Restrictions

Manifest-based admission configurations exist in isolation and cannot
reference API resources. The following restrictions apply:

- **Webhooks**: Must use `clientConfig.url`. The `clientConfig.service` field is
  not allowed because the service network may not be available at API server
  startup.
- **Policies**: The `spec.paramKind` field is not allowed. Policies cannot
  reference ConfigMaps or other cluster objects for parameters.
- **Bindings**: The `spec.paramRef` field is not allowed. The `spec.policyName`
  must reference a policy defined in the same manifest file set and must end
  with `.static.k8s.io`.

Manifest files are decoded using the strict decoder, which rejects files
containing duplicate fields or unknown fields. Each object undergoes the same
defaulting and validation that the REST API applies.

## Examples {#examples}

### Protecting API-based admission resources {#protecting-admission-resources}

A key capability of manifest-based admission control is the ability to intercept
operations on admission configuration resources themselves
(ValidatingAdmissionPolicy, MutatingAdmissionPolicy,
ValidatingWebhookConfiguration, MutatingWebhookConfiguration, and their
bindings). REST-based admission webhooks and policies are not invoked on these
resource types to prevent circular dependencies, but manifest-based policies
can enforce rules on them because they do not have that circular dependency.

The following example prevents deletion or modification of admission resources
that carry the `platform.example.com/protected: "true"` label:


















<div class="highlight code-sample">
    <div class="copy-code-icon">
    <a href="https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/access/manifest-admission-control/protect-admission-resources.yaml" download="access/manifest-admission-control/protect-admission-resources.yaml"><code>access/manifest-admission-control/protect-admission-resources.yaml</code>
    </a><img src="/images/copycode.svg" class="icon-copycode" onclick="copyCode('access-manifest-admission-control-protect-admission-resources-yaml')" title="Copy access/manifest-admission-control/protect-admission-resources.yaml to clipboard"></img></div>
    <div class="includecode" id="access-manifest-admission-control-protect-admission-resources-yaml"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c"># This is an example ValidatingAdmissionPolicy that prevents deletion or</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c"># modification of API-based admission resources with the</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c"># &#34;platform.example.com/protected: true&#34; label.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">admissionregistration.k8s.io/v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">ValidatingAdmissionPolicy</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">metadata</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;example-protect-admission-resources.static.k8s.io&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">annotations</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">kubernetes.io/description</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Prevent modification or deletion of protected admission resources&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">spec</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">failurePolicy</span><span class="p">:</span><span class="w"> </span><span class="l">Fail</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">matchConstraints</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">resourceRules</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">apiGroups</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;admissionregistration.k8s.io&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">apiVersions</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;*&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">operations</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;DELETE&#34;</span><span class="p">,</span><span class="w"> </span><span class="s2">&#34;UPDATE&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">resources</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;validatingadmissionpolicies&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;validatingadmissionpolicybindings&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;mutatingadmissionpolicies&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;mutatingadmissionpolicybindings&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;validatingwebhookconfigurations&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;mutatingwebhookconfigurations&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">validations</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">expression</span><span class="p">:</span><span class="w"> </span><span class="p">&gt;-</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">      !has(oldObject.metadata.labels) ||
</span></span></span><span class="line"><span class="cl"><span class="sd">      !(&#39;platform.example.com/protected&#39; in oldObject.metadata.labels) ||
</span></span></span><span class="line"><span class="cl"><span class="sd">      oldObject.metadata.labels[&#39;platform.example.com/protected&#39;] != &#39;true&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">message</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Protected admission resources cannot be modified or deleted&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nn">---</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">admissionregistration.k8s.io/v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">ValidatingAdmissionPolicyBinding</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">metadata</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;example-protect-admission-resources-binding.static.k8s.io&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">annotations</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">kubernetes.io/description</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Bind protect-admission-resources policy to all admission resources&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">spec</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">policyName</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;example-protect-admission-resources.static.k8s.io&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">validationActions</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="l">Deny</span><span class="w">
</span></span></span></code></pre></div></div>
</div>

### Enforcing a ValidatingAdmissionPolicy from disk

The following example defines a policy that denies privileged containers in all
namespaces except `kube-system`:


















<div class="highlight code-sample">
    <div class="copy-code-icon">
    <a href="https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/access/manifest-admission-control/deny-privileged-policy.yaml" download="access/manifest-admission-control/deny-privileged-policy.yaml"><code>access/manifest-admission-control/deny-privileged-policy.yaml</code>
    </a><img src="/images/copycode.svg" class="icon-copycode" onclick="copyCode('access-manifest-admission-control-deny-privileged-policy-yaml')" title="Copy access/manifest-admission-control/deny-privileged-policy.yaml to clipboard"></img></div>
    <div class="includecode" id="access-manifest-admission-control-deny-privileged-policy-yaml"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c"># This is an example ValidatingAdmissionPolicy that denies privileged containers</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c"># in all namespaces except kube-system.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">admissionregistration.k8s.io/v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">ValidatingAdmissionPolicy</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">metadata</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;example-deny-privileged.static.k8s.io&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">annotations</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">kubernetes.io/description</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Deny privileged containers outside kube-system&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">spec</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">failurePolicy</span><span class="p">:</span><span class="w"> </span><span class="l">Fail</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">matchConstraints</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">resourceRules</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">apiGroups</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">apiVersions</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;v1&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">operations</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;CREATE&#34;</span><span class="p">,</span><span class="w"> </span><span class="s2">&#34;UPDATE&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">resources</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;pods&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">variables</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">allContainers</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">expression</span><span class="p">:</span><span class="w"> </span><span class="p">&gt;-</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">      object.spec.containers +
</span></span></span><span class="line"><span class="cl"><span class="sd">      (has(object.spec.initContainers) ? object.spec.initContainers : []) +
</span></span></span><span class="line"><span class="cl"><span class="sd">      (has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : [])</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">validations</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">expression</span><span class="p">:</span><span class="w"> </span><span class="p">&gt;-</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">      !variables.allContainers.exists(c,
</span></span></span><span class="line"><span class="cl"><span class="sd">      has(c.securityContext) &amp;&amp; has(c.securityContext.privileged) &amp;&amp;
</span></span></span><span class="line"><span class="cl"><span class="sd">      c.securityContext.privileged == true)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">message</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Privileged containers are not allowed&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nn">---</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">admissionregistration.k8s.io/v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">ValidatingAdmissionPolicyBinding</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">metadata</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;example-deny-privileged-binding.static.k8s.io&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">annotations</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">kubernetes.io/description</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Bind deny-privileged policy to all namespaces except kube-system&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">spec</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">policyName</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;example-deny-privileged.static.k8s.io&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">validationActions</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="l">Deny</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">matchResources</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">namespaceSelector</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">matchExpressions</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">key</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;kubernetes.io/metadata.name&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">operator</span><span class="p">:</span><span class="w"> </span><span class="l">NotIn</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">values</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;kube-system&#34;</span><span class="p">]</span><span class="w">
</span></span></span></code></pre></div></div>
</div>

Place this file in the directory configured as `staticManifestsDir` for the
`ValidatingAdmissionPolicy` plugin. The policy and its binding are loaded
together atomically.

### Configuring a ValidatingWebhookConfiguration from disk

The following example configures a validating webhook that calls an external URL:


















<div class="highlight code-sample">
    <div class="copy-code-icon">
    <a href="https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/access/manifest-admission-control/validating-webhook.yaml" download="access/manifest-admission-control/validating-webhook.yaml"><code>access/manifest-admission-control/validating-webhook.yaml</code>
    </a><img src="/images/copycode.svg" class="icon-copycode" onclick="copyCode('access-manifest-admission-control-validating-webhook-yaml')" title="Copy access/manifest-admission-control/validating-webhook.yaml to clipboard"></img></div>
    <div class="includecode" id="access-manifest-admission-control-validating-webhook-yaml"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c"># This is an example ValidatingWebhookConfiguration that calls an external</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c"># URL-based webhook endpoint to validate pod creation and updates.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">admissionregistration.k8s.io/v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">ValidatingWebhookConfiguration</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">metadata</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;example-security-webhook.static.k8s.io&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">annotations</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">kubernetes.io/description</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Validate pod creation and updates via external webhook&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">webhooks</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl">- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;security.platform.example.com&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">clientConfig</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">url</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;https://security-webhook.platform.example.com:443/validate&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">caBundle</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;&lt;base64-encoded-CA-bundle&gt;&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">rules</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">apiGroups</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">apiVersions</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;v1&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">operations</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;CREATE&#34;</span><span class="p">,</span><span class="w"> </span><span class="s2">&#34;UPDATE&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">resources</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;pods&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">admissionReviewVersions</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;v1&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">sideEffects</span><span class="p">:</span><span class="w"> </span><span class="l">None</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">failurePolicy</span><span class="p">:</span><span class="w"> </span><span class="l">Fail</span><span class="w">
</span></span></span></code></pre></div></div>
</div>


<div class="alert alert-info" role="note"><h4 class="alert-heading">Note:</h4>Webhook URLs must be reachable from the kube-apiserver at startup. Only
URL-based endpoints are supported; service references are not allowed in
manifest-based webhook configurations.</div>


### Using the List format

You can use `v1.List` to group related resources together in a single document:


















<div class="highlight code-sample">
    <div class="copy-code-icon">
    <a href="https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/access/manifest-admission-control/list-format-policy.yaml" download="access/manifest-admission-control/list-format-policy.yaml"><code>access/manifest-admission-control/list-format-policy.yaml</code>
    </a><img src="/images/copycode.svg" class="icon-copycode" onclick="copyCode('access-manifest-admission-control-list-format-policy-yaml')" title="Copy access/manifest-admission-control/list-format-policy.yaml to clipboard"></img></div>
    <div class="includecode" id="access-manifest-admission-control-list-format-policy-yaml"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c"># This is an example of using the v1.List format to group a</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c"># ValidatingAdmissionPolicy and its binding in a single document.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">List</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">items</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl">- <span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">admissionregistration.k8s.io/v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">ValidatingAdmissionPolicy</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">metadata</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;example-require-labels.static.k8s.io&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">annotations</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">kubernetes.io/description</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Require app.kubernetes.io/name label on all pods&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">spec</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">failurePolicy</span><span class="p">:</span><span class="w"> </span><span class="l">Fail</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">matchConstraints</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">resourceRules</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">apiGroups</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">apiVersions</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;v1&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">operations</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;CREATE&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">resources</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;pods&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">validations</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">expression</span><span class="p">:</span><span class="w"> </span><span class="p">&gt;-</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">        has(object.metadata.labels) &amp;&amp;
</span></span></span><span class="line"><span class="cl"><span class="sd">        &#39;app.kubernetes.io/name&#39; in object.metadata.labels</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">message</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;All pods must have the &#39;app.kubernetes.io/name&#39; label&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl">- <span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">admissionregistration.k8s.io/v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">ValidatingAdmissionPolicyBinding</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">metadata</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;example-require-labels-binding.static.k8s.io&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">annotations</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">kubernetes.io/description</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Bind require-labels policy to all namespaces except kube-system&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">spec</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">policyName</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;example-require-labels.static.k8s.io&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">validationActions</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">Deny</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">matchResources</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">namespaceSelector</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">matchExpressions</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="nt">key</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;kubernetes.io/metadata.name&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">operator</span><span class="p">:</span><span class="w"> </span><span class="l">NotIn</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">values</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;kube-system&#34;</span><span class="p">]</span><span class="w">
</span></span></span></code></pre></div></div>
</div>

## Evaluation order

Manifest-based configurations are evaluated before API-based configurations.
This ensures that platform-level policies enforced via static configuration take
precedence over API-based policies.

For admission configuration resources themselves (ValidatingAdmissionPolicy,
MutatingAdmissionPolicy, ValidatingAdmissionPolicyBinding,
MutatingAdmissionPolicyBinding, ValidatingWebhookConfiguration,
MutatingWebhookConfiguration), only manifest-based admission hooks are
evaluated. API-based hooks are skipped for these resource types to prevent
circular dependencies.

## File watching and dynamic reloading {#dynamic-reloading}

The kube-apiserver watches the configured directories for changes:

1. **Initial load**: At startup, all configured paths are read and validated.
   The API server does not become ready until all manifests are loaded
   successfully. Invalid manifests cause startup failure.

1. **Runtime reloading**: Changes to manifest files trigger a reload cycle:
   - File modifications are detected using
     [fsnotify](https://github.com/fsnotify/fsnotify) with a polling fallback
     (default 1 minute interval), similar to other config file reloading in
     kube-apiserver.
   - A content hash of all manifest files is computed on each check. If the hash
     is unchanged, no reload occurs.
   - New configurations are validated before being applied.
   - If validation fails, the error is logged, metrics are updated, and the
     previous valid configuration is retained.
   - Successful reloads atomically replace the previous configuration.

<!-- -->

1. **Atomic file updates**: To avoid partial reads during file writes, make
   changes atomically (for example, write to a temporary file and rename it).
   This is especially important when updating mounted ConfigMaps or Secrets in
   containerized environments.

<div class="alert alert-caution" role="note"><h4 class="alert-heading">Caution:</h4>If an invalid manifest file is present at startup, the API server does not
start. At runtime, if a reload fails due to validation errors, the previous
valid configuration is retained and the error is logged.</div>


## Observability {#observability}

### Metrics

Manifest-based admission control provides the following metrics for monitoring
reload health:



 





<table><caption style="display: none;">Metrics for manifest-based admission control</caption>
	<thead>
			<tr>
					<th style="text-align: left">Type</th>
					<th style="text-align: left">Description</th>
					<th style="text-align: left">Metric</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td style="text-align: left">Counter</td>
					<td style="text-align: left">Total number of reload attempts, with <code>status</code> (<code>success</code> or <code>failure</code>), <code>plugin</code>, and <code>apiserver_id_hash</code> labels.</td>
					<td style="text-align: left"><code>apiserver_manifest_admission_config_controller_automatic_reloads_total</code></td>
			</tr>
			<tr>
					<td style="text-align: left">Gauge</td>
					<td style="text-align: left">Timestamp of the last reload attempt, with <code>status</code>, <code>plugin</code>, and <code>apiserver_id_hash</code> labels.</td>
					<td style="text-align: left"><code>apiserver_manifest_admission_config_controller_automatic_reload_last_timestamp_seconds</code></td>
			</tr>
			<tr>
					<td style="text-align: left">Gauge</td>
					<td style="text-align: left">Current configuration information (value is always 1), with <code>plugin</code>, <code>apiserver_id_hash</code>, and <code>hash</code> labels. Use the <code>hash</code> label to detect configuration drift across API servers.</td>
					<td style="text-align: left"><code>apiserver_manifest_admission_config_controller_last_config_info</code></td>
			</tr>
	</tbody>
</table>


The `plugin` label identifies which admission plugin the metric applies to:
`ValidatingAdmissionWebhook`, `MutatingAdmissionWebhook`,
`ValidatingAdmissionPolicy`, or `MutatingAdmissionPolicy`.

Since manifest-based objects have names ending in `.static.k8s.io`, existing
admission metrics (such as `apiserver_admission_webhook_rejection_count`) can
identify manifest-based decisions by filtering on the `name` label.

### Audit annotations

Existing audit annotations (such as
`validation.policy.admission.k8s.io/validation_failure` and
`mutation.webhook.admission.k8s.io/round_0_index_0`) include the object name.
You can identify manifest-based admission decisions by filtering for names
ending in `.static.k8s.io`.

## High availability considerations {#ha-considerations}

Each kube-apiserver instance loads its own manifest files independently. In
high availability setups with multiple API server instances:

- Each API server must be configured individually. There is no cross-apiserver
  synchronization of manifest-based configurations.
- Use external configuration management tools (such as Ansible, Puppet, or
  shared storage mounts) to keep manifest files consistent across instances.
- The `apiserver_manifest_admission_config_controller_last_config_info` metric
  exposes a `hash` label that you can use to detect configuration drift across
  API server instances.

This behavior is similar to other file-based kube-apiserver configurations such as
[encryption at rest](/docs/tasks/administer-cluster/encrypt-data/) and
[authentication](/docs/reference/access-authn-authz/authentication/).

## Upgrade and downgrade {#upgrade-downgrade}

**Upgrade**: Enabling the feature and providing manifest configuration is
opt-in. Existing clusters without manifest configuration see no behavioral
change.

**Downgrade**: Before downgrading to a version without this feature:

1. Remove `staticManifestsDir` entries from the `AdmissionConfiguration` file.
1. If relying on manifest-based policies, recreate them as API objects where
   possible.
1. Restart the kube-apiserver.

<div class="alert alert-danger" role="note"><h4 class="alert-heading">Warning:</h4>Downgrading without removing the <code>staticManifestsDir</code> configuration causes the
API server to fail to start due to unknown configuration fields.</div>


## Troubleshooting {#troubleshooting}



 





<table><caption style="display: none;">Common issues and their resolution</caption>
	<thead>
			<tr>
					<th style="text-align: left">Symptom</th>
					<th style="text-align: left">Possible cause</th>
					<th style="text-align: left">Resolution</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td style="text-align: left">API server fails to start</td>
					<td style="text-align: left">Invalid manifest file at startup</td>
					<td style="text-align: left">Check API server logs for validation errors. Fix the manifest file and restart.</td>
			</tr>
			<tr>
					<td style="text-align: left">API server fails to start</td>
					<td style="text-align: left">Duplicate object names across manifest files</td>
					<td style="text-align: left">Ensure all object names within a plugin's <code>staticManifestsDir</code> are unique.</td>
			</tr>
			<tr>
					<td style="text-align: left">Policies not enforced after file update</td>
					<td style="text-align: left">Reload validation failure</td>
					<td style="text-align: left">Check <code>automatic_reloads_total{status=&quot;failure&quot;}</code> metric and API server logs. Fix the manifest and wait for the next reload cycle.</td>
			</tr>
			<tr>
					<td style="text-align: left">Webhook requests failing</td>
					<td style="text-align: left">Webhook URL not reachable</td>
					<td style="text-align: left">Verify that the URL specified in <code>clientConfig.url</code> is accessible from the kube-apiserver.</td>
			</tr>
			<tr>
					<td style="text-align: left">Cannot create API objects with <code>.static.k8s.io</code> suffix</td>
					<td style="text-align: left">Name suffix reserved by feature gate</td>
					<td style="text-align: left">The <code>.static.k8s.io</code> suffix is reserved for manifest-based configurations when the feature gate is enabled. Use a different name for API-based objects.</td>
			</tr>
	</tbody>
</table>


## What's next

- Learn about [ValidatingAdmissionPolicy](/docs/reference/access-authn-authz/validating-admission-policy/)
  for CEL-based validation policies.
- Learn about [MutatingAdmissionPolicy](/docs/reference/access-authn-authz/mutating-admission-policy/)
  for CEL-based mutation policies.
- Learn about [Dynamic Admission Control](/docs/reference/access-authn-authz/extensible-admission-controllers/)
  for webhook-based admission control.
- Read the [KEP-5793](https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/5793-manifest-based-admission-control-config)
  design document.
