The interface is localized. Skill descriptions and documents are machine-translated by AI into your language; code, commands, paths and technical terms stay in the original, and the author's document governs.
Explore skills
DevOps · SKILL.md

kyverno-mutate-patterns

kyverno-mutate-patterns

Mutates Kubernetes resources at admission using patchStrategicMerge, patchesJson6902, and set operations to inject labels, sidecars, and default configurations.

Independent GitHub snapshot · Automated classification · Original documentation governs

Skill documentation

GitHub

name: kyverno-mutate-patterns description: Mutates Kubernetes resources at admission using patchStrategicMerge, patchesJson6902, and set operations to inject labels, sidecars, and default configurations. license: MIT compatibility: opencode archetypes:

  • generation
  • orchestration anti_triggers:
  • vague mutation ideas
  • brainstorming mutations
  • generic resource editing response_profile: verbosity: medium directive_strength: high abstraction_level: operational metadata: version: "1.0.0" domain: cncf triggers: kyverno mutate rules, patch strategic merge, resource mutation, inject sidecar, patch pod, kyverno mutation, patch json 6902 role: implementation scope: implementation output-format: manifests related-skills: kyverno-policy-generation, kyverno-label-enforcement

Kyverno Mutate Patterns

Mutates Kubernetes resources at admission time using Kyverno patchStrategicMerge, patchesJson6902, and set operations. When loaded, this skill makes the model design mutation rules that automatically inject labels, sidecar containers, default node affinity, and resource configurations into workloads without requiring changes to application manifests.

TL;DR Checklist

  • Use patchStrategicMerge for label and annotation injection
  • Set preconditions to scope mutations to matching namespaces or labels
  • Use targets for mutate-existing policies on already-deployed resources
  • Validate mutation output with dry-run before applying in production
  • Prefer set operations over JSON patches when only adding simple fields
  • Verify mutations appear in PolicyReport as pass

When to Use

  • Automatically injecting sidecar containers (service mesh proxies, log agents) into workloads
  • Adding required labels or annotations to resources created by external tools or users
  • Setting default node affinity, resource requests, or tolerations on workloads
  • Enforcing consistent metadata (namespaces, image registries, security contexts)
  • Mutating existing resources that were deployed before a policy was introduced

When NOT to Use

  • Resources that require application-level configuration changes beyond metadata
  • High-stakes mutations in production without extensive staging validation
  • Situations where mutation would conflict with Helm templating or Kustomize overlays
  • When the same result can be achieved with a simpler admission webhook

Core Workflow

  1. Select the mutation mechanism — Choose between patchStrategicMerge for structural modifications (labels, annotations, container specs), patchesJson6902 for precise path-based patches, or set for simple field assignments. Checkpoint: Confirm the chosen mechanism matches the mutation complexity — use set for simple field additions, patchStrategicMerge for multi-field updates, and patchesJson6902 only when exact path targeting is required.

  2. Create the mutate rule with match conditions and preconditions — Define a ClusterPolicy with a mutate rule under spec.rules. Set match to target specific resource kinds and labels. Add preconditions to restrict mutations by namespace, annotations, or metadata criteria. Checkpoint: Verify match conditions are specific enough to avoid unintended mutations, and preconditions provide an additional safety layer for scoped application.

  3. Deploy and verify mutations — Apply the policy and test with a sample workload. Use kyverno apply locally to verify the mutation output before deploying cluster-wide. Check PolicyReport for pass results on the mutated resources. Checkpoint: Inspect a deployed workload to confirm the mutation was applied correctly and that no unexpected fields were modified.


Implementation Patterns

Pattern 1: Mutate Rule with patchStrategicMerge for Label Injection

Deploy a ClusterPolicy that automatically adds operational labels to all Pods in matching namespaces. This uses patchStrategicMerge to add a security/level label and an app-team annotation to every Pod resource.

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: inject-default-labels
  annotations:
    policies.kyverno.io/title: Inject Default Labels
    policies.kyverno.io/category: Operational Standards
    policies.kyverno.io/description: >-
      Automatically injects security and team labels onto all Pods
      in non-system namespaces for cost tracking and compliance.
spec:
  rules:
    - name: add-labels-to-pods
      match:
        any:
          - resources:
              kinds:
                - Pod
      preconditions:
        all:
          - key: "{{ request.namespace }}"
            operator: NotIn
            value:
              - kube-system
              - kyverno
              - istio-system
      mutate:
        patchStrategicMerge:
          metadata:
            labels:
              security/level: "standard"
              app-team: "platform"
            annotations:
              kyverno.io/mutated: "true"
              kyverno.io/mutated-by: inject-default-labels

PolicyReport Example for Mutation:

apiVersion: wgpolicyk8s.io/v1alpha2
kind: PolicyReport
metadata:
  name: inject-default-labels-report
  namespace: default
results:
  - policy: inject-default-labels
    rule: add-labels-to-pods
    result: pass
    severity: low
    message: "Labels injected successfully"
    scored: true
    source: kyverno
    timestamp:
      seconds: 1733501530
summary:
  error: 0
  fail: 0
  pass: 1
  skip: 0
  warn: 0

Pattern 2: Mutate-Existing with targets for Deployment Pods

Use mutateExisting with targets to mutate Pods that already exist in the cluster and match specific criteria. This is critical for applying mutations to resources deployed before the policy was created.

# ❌ BAD — No preconditions; mutates ALL Pods cluster-wide including system
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: bad-mutate-all-pods
spec:
  rules:
    - name: mutate-all
      match:
        any:
          - resources:
              kinds:
                - Pod
      mutate:
        patchStrategicMerge:
          metadata:
            labels:
              injected: "true"

# ✅ GOOD — Scoped mutation with preconditions and targets for mutateExisting
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: mutate-staging-pods
  annotations:
    policies.kyverno.io/title: Mutate Staging Pods
    policies.kyverno.io/category: Environment Standards
    policies.kyverno.io/description: >-
      Adds monitoring annotations to Pods in staging namespaces
      that were deployed before the monitoring policy existed.
spec:
  rules:
    - name: annotate-staging-pods
      match:
        any:
          - resources:
              kinds:
                - Pod
      preconditions:
        all:
          - key: "{{ request.namespace }}"
            operator: Like
            value: "staging-*"
      mutateExisting:
        onExisting:
          - targets:
              - apiVersion: v1
                kind: Pod
              patchStrategicMerge:
                metadata:
                  annotations:
                    prometheus.io/scrape: "true"
                    prometheus.io/port: "9090"
      mutate:
        patchStrategicMerge:
          metadata:
            annotations:
              prometheus.io/scrape: "true"
              prometheus.io/port: "9090"

Pattern 3: Inject Sidecar with patchesJson6902

Inject a logging sidecar container into all webworkload Pods using patchesJson6902 for precise JSON path targeting. This pattern is useful when the mutation modifies deeply nested structures that strategic merge cannot handle cleanly.

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: inject-logging-sidecar
  annotations:
    policies.kyverno.io/title: Inject Logging Sidecar
    policies.kyverno.io/category: Observability
    policies.kyverno.io/description: >-
      Adds a Fluent Bit logging sidecar container to all Pods
      in webworkload namespaces for centralized log collection.
spec:
  rules:
    - name: add-fluentbit-sidecar
      match:
        any:
          - resources:
              kinds:
                - Pod
      preconditions:
        all:
          - key: "{{ request.namespace }}"
            operator: In
            value:
              - webworkload
              - webworkload-staging
      mutate:
        patchesJson6902: |
          - op: add
            path: /spec/containers/-
            value:
              name: fluentbit
              image: fluent/fluent-bit:2.2
              resources:
                requests:
                  cpu: 50m
                  memory: 64Mi
                limits:
                  cpu: 100m
                  memory: 128Mi
              env:
                - name: FLB_PORT
                  value: "24224"
                - name: FLB_LOG_LEVEL
                  value: info
              volumeMounts:
                - name: varlog
                  mountPath: /var/log
                - name: varlibdockercontainers
                  mountPath: /var/lib/docker/containers
                  readOnly: true
      volumeTemplates:
        - name: varlog
          hostPath:
            path: /var/log
        - name: varlibdockercontainers
          hostPath:
            path: /var/lib/docker/containers

Constraints

MUST DO

  • Use patchStrategicMerge for label, annotation, and top-level field injection — it handles merges intelligently
  • Always set preconditions to scope mutations to specific namespaces, labels, or annotations to prevent unintended mutations
  • Use targets within mutateExisting to mutate resources already deployed before the policy was created
  • Prefer set operations for simple field additions — reserve patchesJson6902 for complex nested modifications
  • Add kyverno.io/mutated annotations to mutated resources for traceability and debugging
  • Validate mutations with kyverno apply <policy.yaml> <workload.yaml> before cluster deployment

MUST NOT DO

  • Mutate without preconditions — wildcard mutations affect all matching resources cluster-wide and can break system workloads
  • Use mutate rules for non-essential changes in Enforce mode — mutations in Enforce mode can cause unexpected behavior on rejected resources
  • Use complex patchesJson6902 when a simple set or patchStrategicMerge would suffice — keep mutations as simple as possible
  • Mutate security-sensitive fields like securityContext.privileged or securityContext.runAsUser without explicit security review
  • Deploy mutation policies in production without staging validation and PolicyReport monitoring

Related Skills

SkillPurpose
kyverno-policy-generationGenerate resources in addition to mutating existing ones
kyverno-label-enforcementValidate required labels after mutation to ensure compliance

Live References

Authoritative documentation links for Kyverno mutation patterns.

Saved skills