diff --git a/astro.config.mjs b/astro.config.mjs index faf3e1ded..e5de65397 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -89,6 +89,7 @@ export default defineConfig({ 'docs/policy-types/cluster-policy/match-exclude', 'docs/policy-types/cluster-policy/validate', 'docs/policy-types/cluster-policy/mutate', + 'docs/policy-types/cluster-policy/mutate-existing', 'docs/policy-types/cluster-policy/generate', { label: 'Verify Image Rules', diff --git a/src/content/docs/docs/policy-types/cel-libraries.mdx b/src/content/docs/docs/policy-types/cel-libraries.mdx index 5f22d6f7c..e3e5cfbe9 100644 --- a/src/content/docs/docs/policy-types/cel-libraries.mdx +++ b/src/content/docs/docs/policy-types/cel-libraries.mdx @@ -472,7 +472,7 @@ The **Hash library** introduces the ability to run hash functions on arbitrary v The following policy ensures that the hash of the image name in a certain deployment matches the required value which represents `nginx:latest`: ```yaml -apiVersion: policies.kyverno.io/v1beta1 +apiVersion: policies.kyverno.io/v1 kind: ValidatingPolicy metadata: name: check-hash diff --git a/src/content/docs/docs/policy-types/cluster-policy/mutate-existing.md b/src/content/docs/docs/policy-types/cluster-policy/mutate-existing.md new file mode 100644 index 000000000..42b703b30 --- /dev/null +++ b/src/content/docs/docs/policy-types/cluster-policy/mutate-existing.md @@ -0,0 +1,209 @@ +--- +title: Mutate Existing Resources +description: Retroactively apply mutations to existing resources in your cluster using background policies. +sidebar: + order: 5 +--- + +In addition to standard mutations applied during the AdmissionReview process, Kyverno supports mutating existing resources already present in the cluster. This feature, often called **background mutation**, allows for retroactive changes or cross-resource synchronization where a change in one resource triggers a mutation in another. + +## Overview + +Unlike standard mutate rules, "mutate existing" rules are applied asynchronously by the Kyverno background controller. This decoupling provides several unique capabilities: + +1. **Cross-Resource Mutation**: Trigger a mutation on a `Secret` when a `ConfigMap` is updated. +2. **Retroactive Application**: Apply new policies to resources that were created before the policy existed. +3. **Policy-Driven Updates**: Optionally trigger mutations on all matching resources when the policy itself is created or updated. + +### Key Implications + +- **Asynchronous Processing**: There is a variable delay between the trigger event and the actual mutation of the target resource. +- **Permissions Management**: Since these mutations occur in the background, the Kyverno background controller requires explicit RBAC permissions for the target resources. + +## Triggers + +A background mutation is initiated in three ways: + +1. **Admission Events**: When a resource matching the rule's `match` block is created or updated. +2. **Policy Events**: When the policy is created or updated (if `mutateExistingOnPolicyUpdate` is set to `true`). +3. **Background Scanning**: By default, Kyverno performs a "force reconciliation" every hour to ensure all resources comply with the latest policies. + +## Targets + +The `mutate.targets` field defines which resources should be modified. This is separate from the `match` block, which defines what _triggers_ the rule. + +```yaml +mutate: + targets: + - apiVersion: v1 + kind: Secret + name: my-secret + namespace: '{{ request.namespace }}' +``` + +### Selection Methods + +- **By Name**: Specify the exact `name` and `namespace`. +- **By Selector**: Use a label selector to match multiple resources. +- **Wildcards**: Omitting the `name` field implies a wildcard (`*`), targeting all resources of that kind in the specified namespace. + +:::caution[Note] +All target resources within a single rule must share the same OpenAPI V3 schema (except `metadata`). Mutating both a `Pod` and a `Deployment` in the same rule will fail. +::: + +## Permissions + +Kyverno requires additional permissions to modify existing resources. By default, it does not have `update` permissions for all resource types. + +Prior to installing a mutate-existing rule, you must grant the Kyverno background controller's ServiceAccount the necessary RBAC permissions. Use the [customizing permissions](/docs/installation/customization#customizing-permissions) guide for details. + +Kyverno validates these permissions when the policy is installed. If permissions are missing, policy creation will fail. + +## Policy Update Behavior + +Use the `mutateExistingOnPolicyUpdate` attribute to control whether the policy should be applied to existing resources immediately upon policy creation or modification. + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: mutate-existing-secret +spec: + rules: + - name: mutate-secret-on-configmap-event + match: + any: + - resources: + kinds: + - ConfigMap + names: + - dictionary-1 + namespaces: + - staging + mutate: + mutateExistingOnPolicyUpdate: true + targets: + - apiVersion: v1 + kind: Secret + name: secret-1 + namespace: '{{ request.object.metadata.namespace }}' + patchStrategicMerge: + metadata: + labels: + foo: bar +``` + +If set to `true`, Kyverno will generate `UpdateRequests` for all matching targets as soon as the policy is admitted. + +## Examples + +### Synchronizing Labels + +This policy updates a `Secret` whenever a specific `ConfigMap` is changed. + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: sync-secret-labels +spec: + rules: + - name: sync-labels + match: + any: + - resources: + kinds: + - ConfigMap + names: + - dictionary-1 + namespaces: + - staging + mutate: + targets: + - apiVersion: v1 + kind: Secret + name: secret-1 + namespace: '{{ request.namespace }}' + patchStrategicMerge: + metadata: + labels: + sync-status: updated +``` + +### Restarting Deployments on Secret Change + +A common use case is to "roll" a Deployment when its configuration Secret changes. + +```yaml +apiVersion: kyverno.io/v2beta1 +kind: ClusterPolicy +metadata: + name: restart-deployment-on-secret-change +spec: + rules: + - name: refresh-env + match: + any: + - resources: + kinds: + - Secret + selector: + matchLabels: + kyverno.io/watch: 'true' + operations: + - UPDATE + mutate: + targets: + - apiVersion: apps/v1 + kind: Deployment + namespace: '{{request.namespace}}' + preconditions: + all: + - key: '{{target.metadata.name}}' + operator: Equals + value: 'testing-*' + patchStrategicMerge: + spec: + template: + metadata: + annotations: + kyverno.io/last-updated: '{{ time_now() }}' +``` + +## Troubleshooting + +### UpdateRequests + +Kyverno uses a Custom Resource called `UpdateRequest` (UR) to manage background tasks. If a mutation fails, check the UR status: + +```bash +kubectl get ur -n kyverno +``` + +To see the detailed error message: + +```bash +kubectl describe ur -n kyverno +``` + +Common error states: + +- **Failed**: Typically indicates missing RBAC permissions or a malformed patch. +- **Pending**: The request is queued for processing. + +### Success Events + +Once a mutation is successful, Kyverno can emit an event on the target resource (if not disabled in configuration): + +```bash +kubectl describe +``` + +Look for a `Normal` event with the reason `PolicyApplied` from the `kyverno-mutate` source. + +## Best Practices + +- **Consolidate Rules**: If you need to mutate the same resource multiple times, combine them into a single rule to reduce the number of `UpdateRequests`. +- **Use Preconditions**: Use `preconditions` within the `targets` block to avoid unnecessary mutations on resources that already comply. +- **Sandbox Testing**: Always test background policies in a staging environment, as they can potentially modify many resources at once. +- **Resource Filters**: Note that targets are **not** subject to Kyverno's default [resource filters](/docs/installation/customization#resource-filters). diff --git a/src/content/docs/docs/policy-types/cluster-policy/mutate.md b/src/content/docs/docs/policy-types/cluster-policy/mutate.md index e094200e4..4242ae616 100644 --- a/src/content/docs/docs/policy-types/cluster-policy/mutate.md +++ b/src/content/docs/docs/policy-types/cluster-policy/mutate.md @@ -421,338 +421,9 @@ Set `spec.emitWarning` to `true` to enable API response warnings for mutate poli ## Mutate Existing resources -In addition to standard mutations, Kyverno also supports mutation on existing resources with `patchStrategicMerge` and `patchesJson6902`. Unlike regular mutate policies that are applied through the AdmissionReview process, mutate existing policies are applied in the background (via the background controller) which update existing resources in the cluster. These "mutate existing" policies, like traditional mutate policies, are still triggered via the AdmissionReview process but apply to existing resources. This decoupling also allows triggering on one resource and mutating a totally different one. They may also optionally be configured to apply upon updates to the policy itself. This has two important implications: +Kyverno supports mutating existing resources already present in the cluster. This is an asynchronous process performed in the background, allowing for retroactive changes or cross-resource synchronization. -1. Mutation for existing resources is an asynchronous process. This means there will be a variable amount of delay between the period where the trigger was observed and the existing resource was mutated. -2. Custom permissions are almost always required. Because these mutations occur on existing resources and not an AdmissionReview (which does not yet exist), Kyverno may need additional permissions which it does not have by default. See the section on [customizing permissions](/docs/installation/customization#customizing-permissions) on how to grant additional permission to the Kyverno background controller's ServiceAccount to determine, prior to installing mutate existing rules, if additional permissions are required. Kyverno will perform these permissions checks at the time a mutate existing policy is installed. Missing or incorrect permissions will result in failure to create the policy. - -To define a "mutate existing" policy, trigger resources need to be specified in the `match` block. The target resources--resources targeted for mutation--are specified in each mutate rule under `mutate.targets`. Mutate existing rules differ from standard mutate rules when these targets are defined. Note that all target resources within a single rule must share the same definition schema. For example, a mutate existing rule fails if this rule mutates both `Pod` and `Deployment` as they do not share the same OpenAPI V3 schema (except `metadata`). - -Because the `match` and `mutate.targets[]` stanzas have two separate scopes, when wishing to match on and mutate the same kind of resources any exclusionary conditions must be placed in the correct scope. Match filter criteria do not implicitly function as the input filter for target selection. For example, wishing to match on and mutate existing Ingress resources which have the annotation `corp.org/facing=internal` should at least have the annotation as a selection criteria in the targets section and may use either anchors or preconditions as described further below. Placing this annotation in the `match` clause will only result in Kyverno triggering upon those resources and not necessarily mutating them. - -:::caution[Note] -Mutation of existing Pods is limited to mutable fields only. See the Kubernetes [documentation here](https://kubernetes.io/docs/concepts/workloads/pods/#pod-update-and-replacement) for more details. -::: - -This policy, which matches when the trigger resource named `dictionary-1` in the `staging` Namespace changes, writes a label `foo=bar` to the target resource named `secret-1` also in the `staging` Namespace. - -```yaml -apiVersion: kyverno.io/v1 -kind: ClusterPolicy -metadata: - name: mutate-existing-secret -spec: - rules: - - name: mutate-secret-on-configmap-event - match: - any: - - resources: - kinds: - - ConfigMap - names: - - dictionary-1 - namespaces: - - staging - mutate: - targets: - - apiVersion: v1 - kind: Secret - name: secret-1 - namespace: '{{ request.object.metadata.namespace }}' - patchStrategicMerge: - metadata: - labels: - foo: bar -``` - -By default, the above policy will not be applied when it is installed. This behavior can be configured via `mutateExistingOnPolicyUpdate` attribute. If you set `mutateExistingOnPolicyUpdate` to `true`, Kyverno will mutate the existing secret on policy CREATE and UPDATE AdmissionReview events. -When `mutateExistingOnPolicyUpdate` is specified as `true`, `mutate.targets` must be specified. - -```yaml -apiVersion: kyverno.io/v1 -kind: ClusterPolicy -metadata: - name: mutate-existing-secret -spec: - rules: - - name: mutate-secret-on-configmap-event - match: - any: - - resources: - kinds: - - ConfigMap - names: - - dictionary-1 - namespaces: - - staging - mutate: - mutateExistingOnPolicyUpdate: true - # ... - targets: - - apiVersion: v1 - kind: Secret - name: secret-1 - namespace: '{{ request.object.metadata.namespace }}' - # ... -``` - -:::caution[Note] -Installation of a mutate existing policy affects the `ValidatingWebhookConfiguration` Kyverno manages as opposed to traditional mutate rules affecting the `MutatingWebhookConfiguration`. -::: - -When defining a list of `targets[]`, the fields `name` and `namespace` are not strictly required but encouraged. If omitted, it implies a wildcard (`"*"`) for the omitted field which can have unintended impact on other resources. - -Target resources can also be selected using label selectors. The below policy example shows a policy that matches `ConfigMaps` with a label `should-match=yes` on `Secret` events. - -```yaml -apiVersion: kyverno.io/v1 -kind: ClusterPolicy -metadata: - name: mutate-existing-configmap -spec: - rules: - - name: mutate-configmap-on-secret-event - match: - any: - - resources: - kinds: - - Secret - mutate: - targets: - - apiVersion: v1 - kind: ConfigMap - selector: - matchLabels: - should-match: 'yes' - patchStrategicMerge: - metadata: - labels: - foo: bar -``` - -In order to more precisely control the target resources, mutate existing rules support both [context variables](/docs/policy-types/cluster-policy/external-data-sources) and [preconditions](/docs/policy-types/cluster-policy/preconditions). Preconditions which occur inside the `targets[]` array must use the target prefix as described [below](#variables-referencing-target-resources). - -This sample below illustrates how to combine preconditions and conditional anchors within `targets[]` to precisely select the desired existing resources for mutation. This policy restarts existing Deployments if they are consuming a Secret that has been updated assigned label `kyverno.io/watch: "true"` AND have a name beginning with `testing-`. - -```yaml -apiVersion: kyverno.io/v2beta1 -kind: ClusterPolicy -metadata: - name: refresh-env-var-in-pods -spec: - rules: - - name: refresh-from-secret-env - match: - any: - - resources: - kinds: - - Secret - selector: - matchLabels: - kyverno.io/watch: 'true' - operations: - - UPDATE - mutate: - mutateExistingOnPolicyUpdate: false - targets: - - apiVersion: apps/v1 - kind: Deployment - namespace: '{{request.namespace}}' - preconditions: - all: - - key: '{{target.metadata.name}}' - operator: Equals - value: testing-* - patchStrategicMerge: - spec: - template: - metadata: - annotations: - corp.org/random: "{{ random('[0-9a-z]{8}') }}" - spec: - containers: - - env: - - valueFrom: - secretKeyRef: - <(name): '{{ request.object.metadata.name }}' -``` - -:::caution[Note] -The targets matched by a mutate existing rule are not subject to Kyverno's [resource filters](/docs/installation/customization#resource-filters). Always develop and test rules in a sandboxed cluster to ensure the scope is correctly confined. -::: - -Mutate existing rules are force reconciled every hour by default regardless of the `mutateExistingOnPolicyUpdate` value. The reconciliation interval can be customized through use of the environment variable `BACKGROUND_SCAN_INTERVAL` set on the background controller. - -Starting from kyverno `v1.11.2`, mutate existing rules that trigger on deletion of a resource will be skipped unless explicitly specified that the `DELETE` operation should match - -For example,the following policy should add a label to a configmap when a deployment is created or updated - -```yaml -apiVersion: kyverno.io/v1 -kind: Policy -metadata: - name: mutate-configmap-on-undefined-deployment-operation -spec: - background: false - rules: - - name: mutate-configmap-on-undefined-deployment-operation - match: - all: - - resources: - kinds: - - Deployment - mutate: - targets: - - apiVersion: v1 - kind: ConfigMap - name: example - namespace: example - patchesJson6902: |- - - path: "/metadata/labels/modified-by-kyverno" - op: add - value: "true" -``` - -To have it also run the mutation when the deployment is deleted, the policy should be modified as such - -```yaml -apiVersion: kyverno.io/v1 -kind: Policy -metadata: - name: mutate-configmap-on-undefined-deployment-operation -spec: - background: false - rules: - - name: mutate-configmap-on-undefined-deployment-operation - match: - all: - - resources: - kinds: - - Deployment - operations: - # add other operations if needed - - DELETE - mutate: - targets: - - apiVersion: v1 - kind: ConfigMap - name: example - namespace: example - patchesJson6902: |- - - path: "/metadata/labels/modified-by-kyverno" - op: add - value: "true" -``` - -### Variables Referencing Target Resources - -To reference data in target resources, you can define the variable `target` followed by the path to the desired attribute. For example, using `target.metadata.labels.env` references the label `env` in the target resource. - -This policy copies the ConfigMaps' value `target.data.key` to their label with the key `env`. - -```yaml -apiVersion: kyverno.io/v1 -kind: ClusterPolicy -metadata: - name: sync-cms -spec: - rules: - - name: concat-cm - match: - any: - - resources: - kinds: - - ConfigMap - names: - - cmone - namespaces: - - foo - mutate: - mutateExistingOnPolicyUpdate: false - targets: - - apiVersion: v1 - kind: ConfigMap - name: cmtwo - namespace: bar - - apiVersion: v1 - kind: ConfigMap - name: cmthree - namespace: bar - patchesJson6902: |- - - op: add - path: "/metadata/labels/env" - value: "{{ target.data.key }}" -``` - -The `{{ @ }}` special variable is added to reference the in-line value of the target resource. - -This policy adds the value of `keyone` from the trigger ConfigMap named `cmone` in the `foo` Namespace as the prefix to target ConfigMaps in their data with `keynew`. - -```yaml -apiVersion: kyverno.io/v1 -kind: ClusterPolicy -metadata: - name: sync-cms -spec: - rules: - - name: concat-cm - match: - any: - - resources: - kinds: - - ConfigMap - names: - - cmone - namespaces: - - foo - mutate: - mutateExistingOnPolicyUpdate: false - targets: - - apiVersion: v1 - kind: ConfigMap - name: cmtwo - namespace: bar - - apiVersion: v1 - kind: ConfigMap - name: cmthree - namespace: bar - patchStrategicMerge: - data: - keynew: '{{request.object.data.keyone}}-{{@}}' -``` - -Once a mutate existing policy is applied successfully, an event can be emitted if `omitEvents` allows it (by default, Kyverno omits success and skipped events): - -```sh -$ kubectl describe deploy foobar -... -Events: - Type Reason Age From Message - ---- ------ ---- ---- ------- - Normal PolicyApplied 29s (x2 over 31s) kyverno-mutate policy add-sec/add-sec-rule applied -``` - -To troubleshoot policy application failure, inspect the `UpdateRequest` Custom Resource to get details. Successful `UpdateRequests` may be automatically cleaned up by Kyverno. - -For example, if the corresponding permission is not granted to Kyverno, you should see a value of `Failed` in the `updaterequest.status` field, however a permission check is performed when a policy is installed. - -``` -$ kubectl get ur -n kyverno -NAME POLICY RULETYPE RESOURCEKIND RESOURCENAME RESOURCENAMESPACE STATUS AGE -ur-swsdg add-sec mutate Deployment foobar default Failed 84s - -$ kubectl describe ur ur-swsdg -n kyverno -Name: ur-swsdg -Namespace: kyverno -... -Status: - Message: deployments.apps "foobar" is forbidden: User "system:serviceaccount:kyverno:kyverno-service-account" cannot update resource "deployments" in API group "apps" in the namespace "default" - State: Failed -``` - -### Mutate Existing Tips - -Combine multiple generate existing rules into a single rule when they mutate the same resource. When these rules are combined, only a single mutation happens which is quicker and more efficient. Otherwise, by using separate rules, multiple UpdateRequests may be created as Kyverno attempts to reconcile changes from both rules simultaneously. This can take longer, require more processing resources, and in some extreme instances can fail. +For detailed information, examples, and troubleshooting, see the dedicated [Mutate Existing Resources](/docs/policy-types/cluster-policy/mutate-existing) page. ## Mutate Rule Ordering (Cascading) diff --git a/src/content/docs/docs/policy-types/image-validating-policy.mdx b/src/content/docs/docs/policy-types/image-validating-policy.mdx index b231b4609..fd639cfb3 100644 --- a/src/content/docs/docs/policy-types/image-validating-policy.mdx +++ b/src/content/docs/docs/policy-types/image-validating-policy.mdx @@ -15,7 +15,7 @@ The Kyverno `ImageValidatingPolicy` type is a Kyverno policy type designed for v ## Additional Fields -The `ImageValidatingPolicy` extends the [Kyverno ValidatingPolicy](/docs/policy-types/validating-policy) with the following additional fields for image verification features. A complete reference is provided in the [API specification](https://htmlpreview.github.io/?https://github.com/kyverno/kyverno/blob/release-1.14/docs/user/crd/index.html#policies.kyverno.io/v1alpha1.ImageValidatingPolicy). +The `ImageValidatingPolicy` extends the [Kyverno ValidatingPolicy](/docs/policy-types/validating-policy) with the following additional fields for image verification features. A complete reference is provided in the [API specification](https://htmlpreview.github.io/?https://github.com/kyverno/kyverno/blob/main/docs/user/crd/index.html#policies.kyverno.io/v1.ImageValidatingPolicy). ### images @@ -34,7 +34,6 @@ spec: images: - name: imagerefs expression: '[object.imageReference]' - # ... ``` ### matchImageReferences @@ -47,10 +46,9 @@ kind: ImageValidatingPolicy metadata: name: check-images spec: - matchImageReferences: # At least one sub-field is required + matchImageReferences: - glob: 'ghcr.io/kyverno/*' # Match images using glob pattern - expression: "image.registry == 'ghcr.io'" # Match using CEL expression - # ... ``` ### attestors @@ -78,7 +76,7 @@ spec: attestors: - name: cosign # A unique name to identify this attestor cosign: - key: # Public key-based verification and At least one sub-field is required + key: expression: variables.cm.data.pubKey # CEL expression that resolves to the public key kms: 'gcpkms://...' # KMS URI for key verification (e.g., GCP KMS, AWS KMS) hashAlgorithm: 'sha256' # Optional hash algorithm used with the key @@ -94,8 +92,7 @@ spec: issuer: 'https://token.actions.githubusercontent.com' subjectRegExp: ".*github\\.com/.*/.*/.github/workflows/.*" # Optional regex for subject matching issuerRegExp: "https://token\\.actions\\.githubusercontent\\.com" # Optional regex for issuer matching - roots: - | # Roots is an optional set of PEM encoded trusted root certificates. If not provided, the system roots are used. + roots: | -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- @@ -118,19 +115,19 @@ spec: insecureIgnoreTlog: false # Skip TLog verification (for testing only) insecureIgnoreSCT: false # Skip Signed Certificate Timestamp (for testing only) - certificate: # Certificate-based verification and At least one sub-field is required + certificate: cert: - value: | # Inline signing certificate + value: | -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- - expression: variables.cm.data.cert # CEL expression resolving to certificate - certChain: # At least one sub-field is required - value: | # Certificate chain associated with the signer o + expression: variables.cm.data.cert + certChain: + value: | -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- - expression: variables.cm.data.certChain # CEL expression resolving to certificate + expression: variables.cm.data.certChain source: # Optional metadata to constrain image source (optional) repository: 'ghcr.io/myorg/myimage' # Limit to specific image repo @@ -144,8 +141,6 @@ spec: data: | # Optional base64-encoded TUF root metadata (optional) eyJzaWduZWQiOiB7Li4ufSwgInNpZ25hdHVyZXMiOiBbLi4uXX0= mirror: 'https://tuf.example.org' # Sigstore TUF mirror URL (optional) - - # ... ``` **Notary attestors:** These use certificates and optional Time Stamp Authority (TSA) certificates for image signature verification. diff --git a/src/content/docs/docs/policy-types/mutating-policy.mdx b/src/content/docs/docs/policy-types/mutating-policy.mdx index 3e399f211..54c3e395e 100644 --- a/src/content/docs/docs/policy-types/mutating-policy.mdx +++ b/src/content/docs/docs/policy-types/mutating-policy.mdx @@ -60,7 +60,7 @@ The table below compares major features across the Kubernetes `MutatingAdmission ## Additional Fields -The `MutatingPolicy` extends the [Kubernetes MutatingAdmissionPolicy](https://kubernetes.io/docs/reference/access-authn-authz/mutating-admission-policy/) with the following additional fields for Kyverno features. A complete reference is provided in the [API specification](https://htmlpreview.github.io/?https://github.com/kyverno/kyverno/blob/main/docs/user/crd/index.html#policies.kyverno.io%2fv1alpha1). +The `MutatingPolicy` extends the [Kubernetes MutatingAdmissionPolicy](https://kubernetes.io/docs/reference/access-authn-authz/mutating-admission-policy/) with the following additional fields for Kyverno features. A complete reference is provided in the [API specification](https://htmlpreview.github.io/?https://github.com/kyverno/kyverno/blob/main/docs/user/crd/index.html#policies.kyverno.io/v1.MutatingPolicy). ### evaluation @@ -76,15 +76,14 @@ spec: admission: enabled: true mutateExisting: - enabled: false - # ... + enabled: true ``` - **`admission.enabled`**: When set to `true`, the policy is applied during admission requests (CREATE, UPDATE operations). This is the primary use case for mutating resources as they are being created or updated. - **`mutateExisting.enabled`**: When set to `true`, the policy is applied to existing resources in the cluster through background processing. This allows you to mutate resources that already exist without requiring them to be recreated or updated. -Refer to the [API Reference](https://htmlpreview.github.io/?https://github.com/kyverno/kyverno/blob/main/docs/user/crd/index.html#policies.kyverno.io/v1alpha1.EvaluationConfiguration) for details. +Refer to the [API Reference](https://htmlpreview.github.io/?https://github.com/kyverno/kyverno/blob/main/docs/user/crd/index.html#policies.kyverno.io/v1.EvaluationConfiguration) for details. ### webhookConfiguration @@ -98,12 +97,11 @@ metadata: spec: webhookConfiguration: timeoutSeconds: 15 - # ... ``` In the policy above, `webhookConfiguration.timeoutSeconds` is set to `15`, which defines how long the admission request waits for policy evaluation. The default is `10` seconds, and the allowed range is `1` to `30` seconds. After this timeout, the request will fail or ignore the result based on the failure policy. Kyverno reflects this setting in the generated `MutatingWebhookConfiguration`. -Refer to the [API Reference](https://htmlpreview.github.io/?https://github.com/kyverno/kyverno/blob/main/docs/user/crd/index.html#policies.kyverno.io/v1alpha1.WebhookConfiguration) for details. +Refer to the [API Reference](https://htmlpreview.github.io/?https://github.com/kyverno/kyverno/blob/main/docs/user/crd/index.html#policies.kyverno.io/v1.WebhookConfiguration) for details. ### autogen @@ -130,7 +128,7 @@ spec: Generating a `MutatingAdmissionPolicy` from a `MutatingPolicy` provides the benefits of faster and more resilient execution during admission controls while leveraging all features of Kyverno. -Refer to the [API Reference](https://htmlpreview.github.io/?https://github.com/kyverno/kyverno/blob/main/docs/user/crd/index.html#policies.kyverno.io/v1alpha1.AutogenConfiguration) for details. +Refer to the [API Reference](https://htmlpreview.github.io/?https://github.com/kyverno/kyverno/blob/main/docs/user/crd/index.html#policies.kyverno.io/v1.AutogenConfiguration) for details. ## Policy Scope @@ -225,15 +223,21 @@ spec: - patchType: ApplyConfiguration applyConfiguration: expression: | - has(object.metadata.labels) && has(object.metadata.labels.environment) ? Object{ metadata: Object.metadata{ - labels: {"managed": "true"} + labels: { + "environment": "prod" + } } - } : + } + - patchType: ApplyConfiguration + applyConfiguration: + expression: | Object{ metadata: Object.metadata{ - labels: {"environment": "dev", "managed": "true"} + labels: { + "tier": "frontend" + } } } ``` @@ -262,23 +266,9 @@ spec: - CREATE mutations: - patchType: JSONPatch - jsonPatch: - expression: | - has(object.metadata.labels) ? - [ - JSONPatch{ - op: "add", - path: "/metadata/labels/managed", - value: "true" - } - ] : - [ - JSONPatch{ - op: "add", - path: "/metadata/labels", - value: {"managed": "true"} - } - ] + patchJson6902: | + - path: "/metadata/labels/purpose" + op: remove ``` ### Multiple JSONPatch Operations @@ -336,17 +326,17 @@ spec: - pods operations: - CREATE - mutations: - - patchType: JSONPatch - jsonPatch: - expression: | - [ - JSONPatch{ - op: "add", - path: "/metadata/labels/" + jsonpatch.escapeKey("app.kubernetes.io/name"), - value: "my-app" - } - ] + mutations: + - patchType: JSONPatch + jsonPatch: + expression: | + [ + JSONPatch{ + op: "add", + path: "/metadata/labels/" + jsonpatch.escapeKey("app.kubernetes.io/name"), + value: "my-app" + } + ] ``` ## Looping with CEL Functions @@ -425,6 +415,8 @@ MutatingPolicy supports background processing to mutate existing resources in th 2. **Custom Permissions**: Custom permissions are almost always required. Because these mutations occur on existing resources and not during an AdmissionReview, Kyverno may need additional permissions which it does not have by default. See the section on [customizing permissions](/docs/installation/customization#customizing-permissions) for how to grant additional permissions to the Kyverno background controller's ServiceAccount. Kyverno will perform these permissions checks when a mutate existing policy is installed. +3. **Testing**: As of Kyverno 1.18, the [Kyverno CLI](/docs/subprojects/kyverno-cli) (`kyverno apply` and `kyverno test`) includes full support for `mutateExisting` rules within `MutatingPolicy` resources, allowing them to be tested locally. + ### Same Trigger and Target When the trigger and target are the same resource type, the policy will mutate ALL existing resources of that type when a trigger occurs: @@ -468,7 +460,7 @@ This means if you have 10 existing namespaces and create a new one, all 11 names You can specify different trigger and target resources using `targetMatchConstraints`. When a trigger occurs, Kyverno will mutate ALL existing resources that match the target criteria. -You have access to properties of the triggering resource via `request.object` and `request.oldObject` in variable expressions. In mutation expressions, `Object` references the target resource from `targetMatchConstraints`. In order to use `request.object` or `request.oldObject` in mutations expressions you have to passing them to the mutation context as a variable first: +You have access to properties of the triggering resource via `request.object` and `request.oldObject` in variable expressions. In mutation expressions, `Object` references the target resource from `targetMatchConstraints`. In order to use `request.object` or `request.oldObject` in mutation expressions, you have to pass them to the mutation context as a variable first: ```yaml apiVersion: policies.kyverno.io/v1 @@ -500,11 +492,11 @@ spec: mutations: - patchType: ApplyConfiguration applyConfiguration: - expression: > + expression: | Object{ metadata: Object.metadata{ - labels: Object.metadata.labels{ - trigger: variables.triggerNamespace + labels: { + "trigger": string(variables.triggerNamespace) } } } @@ -517,12 +509,12 @@ In this example: This means if you have 5 ConfigMaps in matching namespaces and update the trigger namespace, all 5 ConfigMaps will be mutated. -As of kyverno 1.17, its possible to select mutation targets with a CEL expression. The expression must use the resource library because it must evaluate to a kubernetes object. The expression can be defined under the `targetMatchConstraints.expression` field which takes a string CEL expression. +As of Kyverno 1.17, it's possible to select mutation targets with a CEL expression. The expression must use the resource library because it must evaluate to a Kubernetes object. The expression can be defined under the `targetMatchConstraints.expression` field which takes a string CEL expression. The following policy will target a configmap resource called `test-cm-1` in the same namespace as the trigger object. ```yaml -apiVersion: policies.kyverno.io/v1beta1 +apiVersion: policies.kyverno.io/v1 kind: MutatingPolicy metadata: name: test-mpol-different-trigger-target-expression @@ -625,15 +617,15 @@ spec: apiVersions: ['v1'] resources: ['pods'] operations: ['CREATE'] -mutations: - - patchType: ApplyConfiguration - applyConfiguration: - expression: | - Object{ - metadata: Object.metadata{ - labels: {"stage": "initial"} + mutations: + - patchType: ApplyConfiguration + applyConfiguration: + expression: | + Object{ + metadata: Object.metadata{ + labels: {"stage": "initial"} + } } - } ``` **Reinvocation Policy Options:** @@ -643,8 +635,24 @@ mutations: ## GitOps Considerations -While GitOps is great at managing configurations, some changes such as label propagations are best handled using mutating policies. +It is common to use Kyverno in a GitOps approach where policies and resources are deployed via tools like Argo CD or Flux. When using mutations, divergence from the state in git can cause "fighting" between Kyverno and the GitOps controller. + +### Flux + +Flux natively accommodates mutating admission controllers like Kyverno by using server-side apply in dry-run mode. The resource returned to Flux already includes mutations, so Flux usually requires no extra configuration. However, this may increase load on Kyverno as mutations are performed during each diff calculation. -Kyverno's MutatingPolicies are designed to interoperate nicely with GitOps solutions. +### Argo CD + +For Argo CD (v2.10+), using **ServerSideDiff** is recommended as it delegates the comparison to Kubernetes, resolving OutOfSync warnings. + +For older versions (v2.9 and below), you may need to configure `ignoreDifferences` in the `Application` resource: + +```yaml +ignoreDifferences: + - group: apps + kind: Deployment + jqPathExpressions: + - .metadata.labels.foo +``` -For comprehensive guidance on GitOps integration, including specific configurations for Flux and ArgoCD, see the [GitOps Considerations section](/docs/policy-types/cluster-policy/mutate#gitops-considerations) in the ClusterPolicy mutate documentation. +It is also helpful to configure `managedFieldsManagers` with a value of `kyverno` to allow Kyverno to own the mutated fields. diff --git a/src/content/docs/docs/policy-types/validating-policy.mdx b/src/content/docs/docs/policy-types/validating-policy.mdx index ff6ba6e5b..0dd70dc2f 100644 --- a/src/content/docs/docs/policy-types/validating-policy.mdx +++ b/src/content/docs/docs/policy-types/validating-policy.mdx @@ -52,7 +52,7 @@ The table below compares major features across the Kubernetes `ValidatingAdmissi ## Additional Fields -The `ValidatingPolicy` extends the [Kubernetes ValidatingAdmissionPolicy](https://kubernetes.io/docs/reference/access-authn-authz/validating-admission-policy/) with the following additional fields for Kyverno features. A complete reference is provided in the [API specification](https://htmlpreview.github.io/?https://github.com/kyverno/kyverno/blob/release-1.14/docs/user/crd/index.html#policies.kyverno.io/v1alpha1.ValidatingPolicy). +The `ValidatingPolicy` extends the [Kubernetes ValidatingAdmissionPolicy](https://kubernetes.io/docs/reference/access-authn-authz/validating-admission-policy/) with the following additional fields for Kyverno features. A complete reference is provided in the [API specification](https://htmlpreview.github.io/?https://github.com/kyverno/kyverno/blob/main/docs/user/crd/index.html#policies.kyverno.io/v1.ValidatingPolicy). ### evaluation @@ -70,12 +70,11 @@ spec: background: enabled: true mode: Kubernetes - # ... ``` The `mode` can be set to `JSON` for non-Kubernetes payloads. -Refer to the [API Reference](https://htmlpreview.github.io/?https://github.com/kyverno/kyverno/blob/release-1.14/docs/user/crd/index.html#policies.kyverno.io/v1alpha1.EvaluationConfiguration) for details. +Refer to the [API Reference](https://htmlpreview.github.io/?https://github.com/kyverno/kyverno/blob/main/docs/user/crd/index.html#policies.kyverno.io/v1.EvaluationConfiguration) for details. ### webhookConfiguration @@ -89,12 +88,11 @@ metadata: spec: webhookConfiguration: timeoutSeconds: 15 - # ... ``` In the policy above, `webhookConfiguration.timeoutSeconds` is set to `15`, which defines how long the admission request waits for policy evaluation. The default is `10` seconds, and the allowed range is `1` to `30` seconds. After this timeout, the request may fail or ignore the result based on the failure policy. Kyverno reflects this setting in the generated `ValidatingWebhookConfiguration`. -Refer to the [API Reference](https://htmlpreview.github.io/?https://github.com/kyverno/kyverno/blob/release-1.14/docs/user/crd/index.html#policies.kyverno.io/v1alpha1.WebhookConfiguration) for details. +Refer to the [API Reference](https://htmlpreview.github.io/?https://github.com/kyverno/kyverno/blob/main/docs/user/crd/index.html#policies.kyverno.io/v1.WebhookConfiguration) for details. ### autogen @@ -121,7 +119,7 @@ spec: Generating a `ValidatingAdmissionPolicy` from a `ValidatingPolicy` provides the benefits of faster and more resilient execution during admission controls while leveraging all features of Kyverno. -Refer to the [API Reference](https://htmlpreview.github.io/?https://github.com/kyverno/kyverno/blob/release-1.14/docs/user/crd/index.html#policies.kyverno.io/v1alpha1.AutogenConfiguration) for details. +Refer to the [API Reference](https://htmlpreview.github.io/?https://github.com/kyverno/kyverno/blob/main/docs/user/crd/index.html#policies.kyverno.io/v1.AutogenConfiguration) for details. ## Policy Scope