path), what to do (op), and what value to use (value). JSON Patch is ideal when you must modify a specific element in a list (for example, update the second container), remove a particular field, or when a merge strategy is insufficient.
Remember: mutations always run before validation. Kyverno will first apply mutations and then validate the final, mutated resource against any validation rules.

JSON Patch structure
A JSON Patch is a list of operations. In Kyverno you place these operations under amutate block using patchesJson6902, which contains a multi-line string with the patch list. Each operation is an object with the following key fields:
op: the operation to perform. Common values:add,replace,remove.path: a JSON Pointer indicating the target location (starts from the root, using/to separate keys).value: the new value to insert (used withaddandreplace).
Notes about
add vs replace:
- Use
addwhen you want to insert or overwrite a value (it creates the member if missing for objects). - Use
replacewhen you must ensure the target exists and you only want to change existing values — otherwise the operation will fail.
Example: Adding or replacing ConfigMap data
Goal: Ensure a ConfigMap namedconfig-game contains two specific keys under data.
- The first
addinjects a multi-line value into/data/ship.properties. If that key already exists, thisaddwill replace it. - The second
addwrites a simple string value to/data/newKey1.
Example: Removing a label from Secrets
Goal: Remove an unwanted labelpurpose from all Secrets.
remove does not use a value field.
Working with lists and arrays
JSON Patch gives you precise control when working with arrays. You can target a specific index or append to the end.
containers list. Lists are zero-indexed, so /spec/containers/1 targets the second element:
busybox container at position 1 and shifts existing containers at that position and beyond.
Appending to the end of an array is more robust than targeting a fixed index. Use - at the end of the path to append:
- works whether the list is empty or already contains items and avoids errors when a specific index does not exist.
Handling special characters in JSON Pointer paths
Keys in Kubernetes annotations or labels may contain special characters such as/ or ~. The JSON Pointer standard requires escaping:
~becomes~0/becomes~1

/:
/ in config.linkerd.io/skip-outbound-ports is encoded as ~1 in the JSON Pointer.
When constructing JSON Pointer paths, always escape
~ and / per RFC 6901. A wrong escape will cause the patch to target an incorrect path or fail entirely.Limitations and best practices
JSON Patch is powerful for precise operations (replacing specific fields, removing labels, or inserting elements into arrays), but keep these important limitations in mind:- Autogen does not work for JSON patches. Because JSON Patch paths are exact, Kyverno cannot automatically translate pod-level patches to controller resources (Deployments, StatefulSets, DaemonSets, etc.). If you need to mutate pods created by controllers, write explicit rules for each controller kind.
- Conditional anchors (inline conditions inside patch fragments) are not supported. If a patch should only apply under certain conditions, use a
preconditionsblock at the rule level to control execution.
- Prefer appending with
-for arrays when possible to avoid index errors. - Use
addwhen you want create-or-update behavior for object members. - Use
replacewhen you must fail if the target path does not exist (safety check). - Test patches against representative manifests before applying them cluster-wide.

Remember: mutations occur before validation. Ensure your patches produce a valid final resource that will pass any subsequent validation rules.