Kubernetes: Using Mutating Admission Policy in Kubernetes v1.32

Kubernetes MutatingAdmissionPolicy MutatingAdmissionPolicyBinding

3 min read | by Jordi Prats

Starting with Kubernetes v1.32, we now have MutatingAdmissionPolicy object, a built-in alternative to mutating admission webhooks. This alpha feature allows for inline resource mutation using Common Expression Language (CEL), making it easier to modify Kubernetes objects at admission time.

Since this is an alpha feature, we'll have to use the feature gates to enable it. In a kind cluster, we can enable the feature gates and the alpha API using a configuration file that we can pass to the kind create cluster command using the --config option.

To create and apply a MutatingAdmissionPolicy in Kubernetes, we'll need to create two objects:

First, we'll create a MutatingAdmissionPolicy object that defines the mutation rules. In this example, we are going to add a label to all Pods created (or updated) in the cluster:

apiVersion: admissionregistration.k8s.io/v1alpha1
kind: MutatingAdmissionPolicy
metadata:
  name: add-mad-label
spec:
  matchConstraints:
    resourceRules:
      - apiGroups: [""]
        apiVersions: ["v1"]
        operations: ["CREATE", "UPDATE"]
        resources: ["pods"]
  failurePolicy: Fail
  reinvocationPolicy: IfNeeded
  mutations:
    - patchType: "ApplyConfiguration"
      applyConfiguration:
        expression: >
          Object{
            metadata: Object.metadata{
              labels: Object.metadata.labels{
                mad: "true"
              }
            }
          }

This object is just defining what do we want to do with the Pods, but it won't be applied until we create a MutatingAdmissionPolicyBinding object that binds the policy to the resources.

In the MutatingAdmissionPolicyBinding object, we'll specify the policy name and the resources to which the policy will be applied. In this case, we are going to apply the policy to all namespaces and all objects:

apiVersion: admissionregistration.k8s.io/v1alpha1
kind: MutatingAdmissionPolicyBinding
metadata:
  name: add-mad-label-binding
spec:
  policyName: add-mad-label
  matchResources:
    namespaceSelector: {}
    objectSelector: {}

To test it, we just need to apply both objects to the cluster and create a new Pod:

$ kubctl apply -f mad-all.yaml
mutatingadmissionpolicy.admissionregistration.k8s.io/add-mad-label created
mutatingadmissionpolicybinding.admissionregistration.k8s.io/add-mad-label-binding unchanged
$ kubectl run demo --image nginx
pod/demo created

Now, if we check the Pod, we should see the label mad: "true":

$ kubectl get pods demo -o yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: "2025-02-15T14:40:48Z"
  labels:
    mad: "true"
    run: demo
  name: demo
  namespace: default
  resourceVersion: "848"
  uid: 38af839a-7a00-4095-bd68-72370081e4bc
(...)

Posted on 21/02/2025