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