diff --git a/cmd/cli/kubectl-kyverno/_testdata/policies/check-image.yaml b/cmd/cli/kubectl-kyverno/_testdata/policies/check-image.yaml index 9e0591404c..5c5179f97f 100644 --- a/cmd/cli/kubectl-kyverno/_testdata/policies/check-image.yaml +++ b/cmd/cli/kubectl-kyverno/_testdata/policies/check-image.yaml @@ -1,25 +1,35 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: check-image annotations: pod-policies.kyverno.io/autogen-controllers: none + name: check-image spec: + admission: true + background: true rules: - - name: verify-signature - match: - resources: + - match: + any: + - resources: kinds: - - Pod - verifyImages: - - imageReferences: - - "*" - attestors: - - count: 1 - entries: - - keys: - publicKeys: |- - -----BEGIN PUBLIC KEY----- - MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFN8gGjQua2g8N+aLx3Eff+/j5HxL - bV+H2z50/0A4d8XyMUvizPQBtcgei43pqLj1850m3wSwI08z2+6zT1QaEg== - -----END PUBLIC KEY----- \ No newline at end of file + - Pod + name: verify-signature + verifyImages: + - attestors: + - count: 1 + entries: + - keys: + publicKeys: |- + -----BEGIN PUBLIC KEY----- + MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFN8gGjQua2g8N+aLx3Eff+/j5HxL + bV+H2z50/0A4d8XyMUvizPQBtcgei43pqLj1850m3wSwI08z2+6zT1QaEg== + -----END PUBLIC KEY----- + signatureAlgorithm: sha256 + imageReferences: + - '*' + mutateDigest: true + required: true + useCache: true + verifyDigest: true + validationFailureAction: Audit diff --git a/cmd/cli/kubectl-kyverno/_testdata/policies/cpol-limit-configmap-for-sa.yaml b/cmd/cli/kubectl-kyverno/_testdata/policies/cpol-limit-configmap-for-sa.yaml index af9a9baeba..c51244e970 100644 --- a/cmd/cli/kubectl-kyverno/_testdata/policies/cpol-limit-configmap-for-sa.yaml +++ b/cmd/cli/kubectl-kyverno/_testdata/policies/cpol-limit-configmap-for-sa.yaml @@ -1,21 +1,22 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: limit-configmap-for-sa annotations: - policies.kyverno.io/title: Limit ConfigMap to ServiceAccounts for a User - policies.kyverno.io/category: Other - policies.kyverno.io/severity: medium + kyverno.io/kubernetes-version: 1.20-1.23 kyverno.io/kyverno-version: 1.6.0 - kyverno.io/kubernetes-version: "1.20-1.23" + policies.kyverno.io/category: Other + policies.kyverno.io/description: This policy shows how to restrict certain operations + on specific ConfigMaps by ServiceAccounts. + policies.kyverno.io/severity: medium policies.kyverno.io/subject: ConfigMap, ServiceAccount - policies.kyverno.io/description: This policy shows how to restrict certain operations on specific ConfigMaps by ServiceAccounts. + policies.kyverno.io/title: Limit ConfigMap to ServiceAccounts for a User + name: limit-configmap-for-sa spec: + admission: true background: false - validationFailureAction: audit rules: - - name: limit-configmap-for-sa-developer - match: + - match: any: - resources: kinds: @@ -31,25 +32,28 @@ spec: - kind: ServiceAccount name: another-developer namespace: another-namespace + name: limit-configmap-for-sa-developer preconditions: all: - - key: "{{request.object.metadata.namespace}}" - operator: In + - key: '{{request.object.metadata.namespace}}' + operator: AllIn value: - - "any-namespace" - - "another-namespace" - - key: "{{request.object.metadata.name}}" - operator: In + - any-namespace + - another-namespace + - key: '{{request.object.metadata.name}}' + operator: AllIn value: - - "any-configmap-name-good" - - "another-configmap-name" + - any-configmap-name-good + - another-configmap-name validate: - message: "{{request.object.metadata.namespace}}/{{request.object.kind}}/{{request.object.metadata.name}} resource is protected. Admin or allowed users can change the resource" deny: conditions: all: - - key: "{{request.operation}}" - operator: "In" + - key: '{{request.operation}}' + operator: In value: - - "UPDATE" - - "CREATE" + - UPDATE + - CREATE + message: '{{request.object.metadata.namespace}}/{{request.object.kind}}/{{request.object.metadata.name}} + resource is protected. Admin or allowed users can change the resource' + validationFailureAction: Audit diff --git a/cmd/cli/kubectl-kyverno/_testdata/policies/cpol-pod-requirements.yaml b/cmd/cli/kubectl-kyverno/_testdata/policies/cpol-pod-requirements.yaml index 0f05c872ac..b225d5c0ff 100644 --- a/cmd/cli/kubectl-kyverno/_testdata/policies/cpol-pod-requirements.yaml +++ b/cmd/cli/kubectl-kyverno/_testdata/policies/cpol-pod-requirements.yaml @@ -1,40 +1,44 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: pod-requirements annotations: pod-policies.kyverno.io/autogen-controllers: none - policies.kyverno.io/severity: medium policies.kyverno.io/category: Pod Security Standards (Restricted) + policies.kyverno.io/severity: medium + name: pod-requirements spec: + admission: true background: false - validationFailureAction: audit rules: - - name: pods-require-account - match: - resources: - kinds: - - Pod + - match: + any: + - resources: + kinds: + - Pod + name: pods-require-account validate: message: User pods must include an account for charging pattern: metadata: labels: - account: "*?" - - name: pods-require-limits - match: - resources: - kinds: - - Pod + account: '*?' + - match: + any: + - resources: + kinds: + - Pod + name: pods-require-limits validate: message: CPU and memory resource requests and limits are required for user pods pattern: spec: containers: - resources: - requests: - memory: "?*" - cpu: "?*" limits: - memory: "?*" - cpu: "?*" + cpu: ?* + memory: ?* + requests: + cpu: ?* + memory: ?* + validationFailureAction: Audit diff --git a/cmd/cli/kubectl-kyverno/_testdata/policies/pol-pod-requirements.yaml b/cmd/cli/kubectl-kyverno/_testdata/policies/pol-pod-requirements.yaml index bcbb2d67da..6ebd08a81b 100644 --- a/cmd/cli/kubectl-kyverno/_testdata/policies/pol-pod-requirements.yaml +++ b/cmd/cli/kubectl-kyverno/_testdata/policies/pol-pod-requirements.yaml @@ -1,41 +1,45 @@ +--- apiVersion: kyverno.io/v1 kind: Policy metadata: - name: pod-requirements - namespace: test annotations: pod-policies.kyverno.io/autogen-controllers: none - policies.kyverno.io/severity: medium policies.kyverno.io/category: Pod Security Standards (Restricted) + policies.kyverno.io/severity: medium + name: pod-requirements + namespace: test spec: + admission: true background: false - validationFailureAction: audit rules: - - name: pods-require-account - match: - resources: - kinds: - - Pod + - match: + any: + - resources: + kinds: + - Pod + name: pods-require-account validate: message: User pods must include an account for charging pattern: metadata: labels: - account: "*?" - - name: pods-require-limits - match: - resources: - kinds: - - Pod + account: '*?' + - match: + any: + - resources: + kinds: + - Pod + name: pods-require-limits validate: message: CPU and memory resource requests and limits are required for user pods pattern: spec: containers: - resources: - requests: - memory: "?*" - cpu: "?*" limits: - memory: "?*" - cpu: "?*" + cpu: ?* + memory: ?* + requests: + cpu: ?* + memory: ?* + validationFailureAction: Audit diff --git a/test/best_practices/add_network_policy.yaml b/test/best_practices/add_network_policy.yaml index 89f7fa403d..89b2acaa97 100644 --- a/test/best_practices/add_network_policy.yaml +++ b/test/best_practices/add_network_policy.yaml @@ -1,39 +1,44 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: add-networkpolicy annotations: policies.kyverno.io/category: Workload Management - policies.kyverno.io/description: By default, Kubernetes allows communications across - all pods within a cluster. Network policies and, a CNI that supports network policies, - must be used to restrict communinications. A default NetworkPolicy should be configured - for each namespace to default deny all ingress traffic to the pods in the namespace. - Application teams can then configure additional NetworkPolicy resources to allow - desired traffic to application pods from select sources. + policies.kyverno.io/description: By default, Kubernetes allows communications + across all pods within a cluster. Network policies and, a CNI that supports + network policies, must be used to restrict communinications. A default NetworkPolicy + should be configured for each namespace to default deny all ingress traffic + to the pods in the namespace. Application teams can then configure additional + NetworkPolicy resources to allow desired traffic to application pods from select + sources. + name: add-networkpolicy spec: - validationFailureAction: audit + admission: true + background: true rules: - - name: default-deny-ingress - match: - resources: - kinds: - - Namespace - name: "*" - exclude: - resources: - namespaces: - - "kube-system" - - "default" - - "kube-public" - - "kyverno" - generate: - kind: NetworkPolicy - name: default-deny-ingress - namespace: "{{request.object.metadata.name}}" - synchronize : true + - exclude: + any: + - resources: + namespaces: + - kube-system + - default + - kube-public + - kyverno + generate: data: spec: - # select all pods in the namespace podSelector: {} - policyTypes: - - Ingress \ No newline at end of file + policyTypes: + - Ingress + kind: NetworkPolicy + name: default-deny-ingress + namespace: '{{request.object.metadata.name}}' + synchronize: true + match: + any: + - resources: + kinds: + - Namespace + name: '*' + name: default-deny-ingress + validationFailureAction: Audit diff --git a/test/best_practices/add_ns_quota.yaml b/test/best_practices/add_ns_quota.yaml index e82f5e448c..0f34040f50 100644 --- a/test/best_practices/add_ns_quota.yaml +++ b/test/best_practices/add_ns_quota.yaml @@ -1,50 +1,46 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: add-ns-quota annotations: policies.kyverno.io/category: Workload Isolation - policies.kyverno.io/description: To limit the number of objects, as well as the - total amount of compute that may be consumed by a single namespace, create - a default resource quota for each namespace. + policies.kyverno.io/description: To limit the number of objects, as well as the + total amount of compute that may be consumed by a single namespace, create a + default resource quota for each namespace. + name: add-ns-quota spec: + admission: true + background: true rules: - - name: generate-resourcequota - match: - resources: - kinds: - - Namespace - exclude: - resources: - namespaces: - - "kube-system" - - "default" - - "kube-public" - - "kyverno" + - exclude: + any: + - resources: + namespaces: + - kube-system + - default + - kube-public + - kyverno generate: apiVersion: v1 - kind: ResourceQuota - name: default-resourcequota - synchronize : true - namespace: "{{request.object.metadata.name}}" data: spec: hard: - requests.cpu: '4' - requests.memory: '16Gi' - limits.cpu: '4' - limits.memory: '16Gi' - - name: generate-limitrange + limits.cpu: "4" + limits.memory: 16Gi + requests.cpu: "4" + requests.memory: 16Gi + kind: ResourceQuota + name: default-resourcequota + namespace: '{{request.object.metadata.name}}' + synchronize: true match: - resources: - kinds: - - Namespace - generate: + any: + - resources: + kinds: + - Namespace + name: generate-resourcequota + - generate: apiVersion: v1 - kind: LimitRange - name: default-limitrange - synchronize : true - namespace: "{{request.object.metadata.name}}" data: spec: limits: @@ -55,3 +51,14 @@ spec: cpu: 200m memory: 256Mi type: Container + kind: LimitRange + name: default-limitrange + namespace: '{{request.object.metadata.name}}' + synchronize: true + match: + any: + - resources: + kinds: + - Namespace + name: generate-limitrange + validationFailureAction: Audit diff --git a/test/best_practices/add_safe_to_evict.yaml b/test/best_practices/add_safe_to_evict.yaml index 9c1ae82f3e..3bbb2c3a7a 100644 --- a/test/best_practices/add_safe_to_evict.yaml +++ b/test/best_practices/add_safe_to_evict.yaml @@ -1,38 +1,45 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy -metadata: - name: add-safe-to-evict +metadata: annotations: policies.kyverno.io/category: Workload Management - policies.kyverno.io/description: The Kubernetes cluster autoscaler does not evict pods that - use hostPath or emptyDir volumes. To allow eviction of these pods, the annotation - cluster-autoscaler.kubernetes.io/safe-to-evict=true must be added to the pods. -spec: - rules: - - name: annotate-empty-dir - match: - resources: - kinds: - - Pod - mutate: + policies.kyverno.io/description: The Kubernetes cluster autoscaler does not evict + pods that use hostPath or emptyDir volumes. To allow eviction of these pods, + the annotation cluster-autoscaler.kubernetes.io/safe-to-evict=true must be added + to the pods. + name: add-safe-to-evict +spec: + admission: true + background: true + rules: + - match: + any: + - resources: + kinds: + - Pod + mutate: patchStrategicMerge: metadata: annotations: +(cluster-autoscaler.kubernetes.io/safe-to-evict): "true" - spec: - volumes: + spec: + volumes: - <(emptyDir): {} - - name: annotate-host-path - match: - resources: - kinds: - - Pod - mutate: + name: annotate-empty-dir + - match: + any: + - resources: + kinds: + - Pod + mutate: patchStrategicMerge: metadata: annotations: +(cluster-autoscaler.kubernetes.io/safe-to-evict): "true" - spec: - volumes: + spec: + volumes: - hostPath: - <(path): "*" + <(path): '*' + name: annotate-host-path + validationFailureAction: Audit diff --git a/test/best_practices/disallow_bind_mounts.yaml b/test/best_practices/disallow_bind_mounts.yaml index 8c26e27d47..1ec3410726 100644 --- a/test/best_practices/disallow_bind_mounts.yaml +++ b/test/best_practices/disallow_bind_mounts.yaml @@ -1,26 +1,31 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy -metadata: - name: disallow-bind-mounts +metadata: annotations: policies.kyverno.io/category: Workload Isolation - policies.kyverno.io/description: The volume of type `hostPath` allows pods to use host bind - mounts (i.e. directories and volumes mounted to a host path) in containers. Using host - resources can be used to access shared data or escalate privileges. Also, this couples pods - to a specific host and data persisted in the `hostPath` volume is coupled to the life of the - node leading to potential pod scheduling failures. It is highly recommended that applications - are designed to be decoupled from the underlying infrastructure (in this case, nodes). -spec: - validationFailureAction: audit - rules: - - name: validate-hostPath - match: - resources: - kinds: - - Pod - validate: - message: "Host path volumes are not allowed" - pattern: - spec: - =(volumes): + policies.kyverno.io/description: The volume of type `hostPath` allows pods to + use host bind mounts (i.e. directories and volumes mounted to a host path) in + containers. Using host resources can be used to access shared data or escalate + privileges. Also, this couples pods to a specific host and data persisted in + the `hostPath` volume is coupled to the life of the node leading to potential + pod scheduling failures. It is highly recommended that applications are designed + to be decoupled from the underlying infrastructure (in this case, nodes). + name: disallow-bind-mounts +spec: + admission: true + background: true + rules: + - match: + any: + - resources: + kinds: + - Pod + name: validate-hostPath + validate: + message: Host path volumes are not allowed + pattern: + spec: + =(volumes): - X(hostPath): "null" + validationFailureAction: Audit diff --git a/test/best_practices/disallow_host_network_port.yaml b/test/best_practices/disallow_host_network_port.yaml index d71d5b1bc5..de3a8a0c9d 100644 --- a/test/best_practices/disallow_host_network_port.yaml +++ b/test/best_practices/disallow_host_network_port.yaml @@ -1,34 +1,40 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: disallow-host-network-port annotations: policies.kyverno.io/category: Workload Isolation - policies.kyverno.io/description: Using 'hostPort' and 'hostNetwork' allows pods to share - the host network stack, allowing potential snooping of network traffic from an application pod. + policies.kyverno.io/description: Using 'hostPort' and 'hostNetwork' allows pods + to share the host network stack, allowing potential snooping of network traffic + from an application pod. + name: disallow-host-network-port spec: - validationFailureAction: audit + admission: true + background: true rules: - - name: validate-host-network - match: - resources: - kinds: - - Pod + - match: + any: + - resources: + kinds: + - Pod + name: validate-host-network validate: - message: "Use of hostNetwork is not allowed" + message: Use of hostNetwork is not allowed pattern: spec: =(hostNetwork): false - - name: validate-host-port - match: - resources: - kinds: - - Pod + - match: + any: + - resources: + kinds: + - Pod + name: validate-host-port validate: - message: "Use of hostPort is not allowed" + message: Use of hostPort is not allowed pattern: spec: containers: - - name: "*" - =(ports): - - X(hostPort): "null" + - =(ports): + - X(hostPort): "null" + name: '*' + validationFailureAction: Audit diff --git a/test/best_practices/disallow_host_pid_ipc.yaml b/test/best_practices/disallow_host_pid_ipc.yaml index 0b49e09e03..596eeb8c92 100644 --- a/test/best_practices/disallow_host_pid_ipc.yaml +++ b/test/best_practices/disallow_host_pid_ipc.yaml @@ -1,24 +1,29 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: disallow-host-pid-ipc annotations: policies.kyverno.io/category: Workload Isolation - policies.kyverno.io/description: Sharing the host's PID namespace allows visibility of process - on the host, potentially exposing process information. Sharing the host's IPC namespace allows - the container process to communicate with processes on the host. To avoid pod container from - having visibility to host process space, validate that 'hostPID' and 'hostIPC' are set to 'false'. + policies.kyverno.io/description: Sharing the host's PID namespace allows visibility + of process on the host, potentially exposing process information. Sharing the + host's IPC namespace allows the container process to communicate with processes + on the host. To avoid pod container from having visibility to host process space, + validate that 'hostPID' and 'hostIPC' are set to 'false'. + name: disallow-host-pid-ipc spec: - validationFailureAction: audit + admission: true + background: true rules: - - name: validate-hostPID-hostIPC - match: - resources: - kinds: - - Pod + - match: + any: + - resources: + kinds: + - Pod + name: validate-hostPID-hostIPC validate: - message: "Use of host PID and IPC namespaces is not allowed" + message: Use of host PID and IPC namespaces is not allowed pattern: spec: - =(hostPID): "false" =(hostIPC): "false" + =(hostPID): "false" + validationFailureAction: Audit diff --git a/test/best_practices/disallow_latest_tag.yaml b/test/best_practices/disallow_latest_tag.yaml index 1080f5eb65..da58650002 100644 --- a/test/best_practices/disallow_latest_tag.yaml +++ b/test/best_practices/disallow_latest_tag.yaml @@ -1,35 +1,40 @@ -apiVersion : kyverno.io/v1 +--- +apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: disallow-latest-tag annotations: - policies.kyverno.io/category: Workload Isolation - policies.kyverno.io/description: The ':latest' tag is mutable and can lead to - unexpected errors if the image changes. A best practice is to use an immutable - tag that maps to a specific version of an application pod. pod-policies.kyverno.io/autogen-controllers: none + policies.kyverno.io/category: Workload Isolation + policies.kyverno.io/description: The ':latest' tag is mutable and can lead to + unexpected errors if the image changes. A best practice is to use an immutable + tag that maps to a specific version of an application pod. + name: disallow-latest-tag spec: - validationFailureAction: audit + admission: true + background: true rules: - - name: require-image-tag - match: - resources: - kinds: - - Pod + - match: + any: + - resources: + kinds: + - Pod + name: require-image-tag validate: - message: "An image tag is required" + message: An image tag is required pattern: spec: containers: - - image: "*:*" - - name: validate-image-tag - match: - resources: - kinds: - - Pod + - image: '*:*' + - match: + any: + - resources: + kinds: + - Pod + name: validate-image-tag validate: - message: "Using a mutable image tag e.g. 'latest' is not allowed" + message: Using a mutable image tag e.g. 'latest' is not allowed pattern: spec: containers: - - image: "!*:latest" \ No newline at end of file + - image: '!*:latest' + validationFailureAction: Audit diff --git a/test/best_practices/disallow_privileged.yaml b/test/best_practices/disallow_privileged.yaml index 9ff8178bf5..f9fd8f4298 100644 --- a/test/best_practices/disallow_privileged.yaml +++ b/test/best_practices/disallow_privileged.yaml @@ -1,39 +1,42 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: disallow-privileged annotations: policies.kyverno.io/category: Security - policies.kyverno.io/description: Privileged containers are defined as any - container where the container uid 0 is mapped to the host’s uid 0. - A process within a privileged container can get unrestricted host access. - With `securityContext.allowPrivilegeEscalation` enabled, a process can - gain privileges from its parent. + policies.kyverno.io/description: Privileged containers are defined as any container + where the container uid 0 is mapped to the host’s uid 0. A process within a + privileged container can get unrestricted host access. With `securityContext.allowPrivilegeEscalation` + enabled, a process can gain privileges from its parent. + name: disallow-privileged spec: - validationFailureAction: audit + admission: true + background: true rules: - - name: validate-privileged - match: - resources: - kinds: - - Pod + - match: + any: + - resources: + kinds: + - Pod + name: validate-privileged validate: - message: "Privileged mode is not allowed. Set privileged to false" + message: Privileged mode is not allowed. Set privileged to false pattern: spec: containers: - =(securityContext): =(privileged): false - - name: validate-allowPrivilegeEscalation - match: - resources: - kinds: - - Pod + - match: + any: + - resources: + kinds: + - Pod + name: validate-allowPrivilegeEscalation validate: - message: "Privileged mode is not allowed. Set allowPrivilegeEscalation to false" + message: Privileged mode is not allowed. Set allowPrivilegeEscalation to false pattern: spec: containers: - securityContext: allowPrivilegeEscalation: false - + validationFailureAction: Audit diff --git a/test/best_practices/disallow_sysctls.yaml b/test/best_practices/disallow_sysctls.yaml index f1ede133df..6c85dd854b 100644 --- a/test/best_practices/disallow_sysctls.yaml +++ b/test/best_practices/disallow_sysctls.yaml @@ -1,23 +1,28 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: disallow-sysctls annotations: policies.kyverno.io/category: Security - policies.kyverno.io/description: The Sysctl interface allows modifications to kernel parameters - at runtime. In a Kubernetes pod these parameters can be specified under `securityContext.sysctls`. - Kernel parameter modifications can be used for exploits and should be restricted. + policies.kyverno.io/description: The Sysctl interface allows modifications to + kernel parameters at runtime. In a Kubernetes pod these parameters can be specified + under `securityContext.sysctls`. Kernel parameter modifications can be used + for exploits and should be restricted. + name: disallow-sysctls spec: - validationFailureAction: audit + admission: true + background: true rules: - - name: validate-sysctls - match: - resources: - kinds: - - Pod + - match: + any: + - resources: + kinds: + - Pod + name: validate-sysctls validate: - message: "Changes to kernel parameters are not allowed" + message: Changes to kernel parameters are not allowed pattern: spec: =(securityContext): - X(sysctls): null \ No newline at end of file + X(sysctls): null + validationFailureAction: Audit diff --git a/test/best_practices/require_certain_labels.yaml b/test/best_practices/require_certain_labels.yaml index 4bab7a50c8..d90d68caca 100644 --- a/test/best_practices/require_certain_labels.yaml +++ b/test/best_practices/require_certain_labels.yaml @@ -1,21 +1,26 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: require-certain-labels spec: - validationFailureAction: audit + admission: true + background: true rules: - - name: validate-certain-labels - match: - resources: - kinds: - - Pod + - match: + any: + - resources: + kinds: + - Pod + name: validate-certain-labels validate: - message: "The label `app.kubernetes.io/name` or `app.kubernetes.io/component` is required." anyPattern: - metadata: labels: - app.kubernetes.io/name: "?*" + app.kubernetes.io/name: ?* - metadata: labels: - app.kubernetes.io/component: "?*" \ No newline at end of file + app.kubernetes.io/component: ?* + message: The label `app.kubernetes.io/name` or `app.kubernetes.io/component` + is required. + validationFailureAction: Audit diff --git a/test/best_practices/require_labels.yaml b/test/best_practices/require_labels.yaml index fce4d5b88c..89ee63d54b 100644 --- a/test/best_practices/require_labels.yaml +++ b/test/best_practices/require_labels.yaml @@ -1,20 +1,22 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: require-labels spec: - validationFailureAction: audit + admission: true + background: true rules: - - name: check-for-labels - match: - resources: - kinds: - - Pod + - match: + any: + - resources: + kinds: + - Pod + name: check-for-labels validate: - message: "The label `app.kubernetes.io/name` is required." + message: The label `app.kubernetes.io/name` is required. pattern: metadata: labels: - app.kubernetes.io/name: "?*" - # You can add more labels if you wish the policy to validate more than just one is present. Uncomment the below line, or add new ones. - #app.kubernetes.io/component: "?* \ No newline at end of file + app.kubernetes.io/name: ?* + validationFailureAction: Audit diff --git a/test/best_practices/require_pod_requests_limits.yaml b/test/best_practices/require_pod_requests_limits.yaml index 0940f454b2..b6295fa401 100644 --- a/test/best_practices/require_pod_requests_limits.yaml +++ b/test/best_practices/require_pod_requests_limits.yaml @@ -1,29 +1,34 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: require-pod-requests-limits annotations: policies.kyverno.io/category: Workload Management - policies.kyverno.io/description: As application workloads share cluster resources, it is important - to limit resources requested and consumed by each pod. It is recommended to require - 'resources.requests' and 'resources.limits.memory' per pod. If a namespace level request or limit is - specified, defaults will automatically be applied to each pod based on the 'LimitRange' configuration. + policies.kyverno.io/description: As application workloads share cluster resources, + it is important to limit resources requested and consumed by each pod. It is + recommended to require 'resources.requests' and 'resources.limits.memory' per + pod. If a namespace level request or limit is specified, defaults will automatically + be applied to each pod based on the 'LimitRange' configuration. + name: require-pod-requests-limits spec: - validationFailureAction: audit + admission: true + background: true rules: - - name: validate-resources - match: - resources: - kinds: - - Pod + - match: + any: + - resources: + kinds: + - Pod + name: validate-resources validate: - message: "CPU and memory resource requests and limits are required" + message: CPU and memory resource requests and limits are required pattern: spec: containers: - resources: - requests: - memory: "?*" - cpu: "?*" limits: - memory: "?*" \ No newline at end of file + memory: ?* + requests: + cpu: ?* + memory: ?* + validationFailureAction: Audit diff --git a/test/best_practices/select-secrets.yaml b/test/best_practices/select-secrets.yaml index 46de36bbe9..c393377241 100644 --- a/test/best_practices/select-secrets.yaml +++ b/test/best_practices/select-secrets.yaml @@ -1,28 +1,34 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: select-secrets spec: + admission: true background: false - validationFailureAction: enforce rules: - - name: select-secrets-from-volumes + - context: + - apiCall: + jmesPath: metadata.labels.foo + method: GET + urlPath: /api/v1/namespaces/{{request.object.metadata.namespace}}/secrets/{{request.object.spec.volumes[0].secret.secretName}} + name: volsecret match: - resources: - kinds: - - Pod - context: - - name: volsecret - apiCall: - urlPath: "/api/v1/namespaces/{{request.object.metadata.namespace}}/secrets/{{request.object.spec.volumes[0].secret.secretName}}" - jmesPath: "metadata.labels.foo" + any: + - resources: + kinds: + - Pod + name: select-secrets-from-volumes preconditions: - - key: "{{ request.operation }}" - operator: Equals - value: "CREATE" + all: + - key: '{{ request.operation }}' + operator: Equals + value: CREATE validate: - message: "The Secret named {{request.object.spec.volumes[0].secret.secretName}} is restricted and may not be used." + message: The Secret named {{request.object.spec.volumes[0].secret.secretName}} + is restricted and may not be used. pattern: spec: containers: - - image: "registry.domain.com/*" \ No newline at end of file + - image: registry.domain.com/* + validationFailureAction: Enforce diff --git a/test/cli/apply/policies/policy.yaml b/test/cli/apply/policies/policy.yaml index b3df63354e..19f0e79edf 100644 --- a/test/cli/apply/policies/policy.yaml +++ b/test/cli/apply/policies/policy.yaml @@ -1,56 +1,60 @@ -apiVersion: kyverno.io/v1 -kind: ClusterPolicy -metadata: - name: disallow-latest-tag - annotations: - policies.kyverno.io/category: Best Practices - policies.kyverno.io/description: >- - The ':latest' tag is mutable and can lead to unexpected errors if the - image changes. A best practice is to use an immutable tag that maps to - a specific version of an application pod. -spec: - validationFailureAction: audit - rules: - - name: validate-image-tag - match: - resources: - kinds: - - Pod - validate: - message: "Using a mutable image tag e.g. 'latest' is not allowed." - pattern: - spec: - containers: - - image: "!*:latest" --- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: drop-all-capabilities + annotations: + policies.kyverno.io/category: Best Practices + policies.kyverno.io/description: The ':latest' tag is mutable and can lead to + unexpected errors if the image changes. A best practice is to use an immutable + tag that maps to a specific version of an application pod. + name: disallow-latest-tag +spec: + admission: true + background: true + rules: + - match: + any: + - resources: + kinds: + - Pod + name: validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + containers: + - image: '!*:latest' + validationFailureAction: Audit +--- +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: annotations: policies.kyverno.io/scored: "false" + name: drop-all-capabilities spec: - validationFailureAction: audit + admission: true + background: true rules: - - name: require-drop-all - match: - any: - - resources: - kinds: - - Pod - preconditions: - all: - - key: "{{ request.operation }}" - operator: NotEquals - value: DELETE - validate: - message: >- - Containers must drop `ALL` capabilities. - foreach: - - list: request.object.spec.[ephemeralContainers, initContainers, containers][] - deny: - conditions: - all: - - key: ALL - operator: AnyNotIn - value: "{{ element.securityContext.capabilities.drop || '' }}" + - match: + any: + - resources: + kinds: + - Pod + name: require-drop-all + preconditions: + all: + - key: '{{ request.operation }}' + operator: NotEquals + value: DELETE + validate: + foreach: + - deny: + conditions: + all: + - key: ALL + operator: AnyNotIn + value: '{{ element.securityContext.capabilities.drop || '''' }}' + list: request.object.spec.[ephemeralContainers, initContainers, containers][] + message: Containers must drop `ALL` capabilities. + validationFailureAction: Audit diff --git a/test/cli/scenarios_to_cli/other/scenario_validate_default_proc_mount/policy.yaml b/test/cli/scenarios_to_cli/other/scenario_validate_default_proc_mount/policy.yaml index 6d6c719bb6..316ef02466 100644 --- a/test/cli/scenarios_to_cli/other/scenario_validate_default_proc_mount/policy.yaml +++ b/test/cli/scenarios_to_cli/other/scenario_validate_default_proc_mount/policy.yaml @@ -1,21 +1,23 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: validate-default-proc-mount spec: - validationFailureAction: "audit" + admission: true + background: true rules: - - name: validate-default-proc-mount - match: + - match: all: - - resources: - kinds: - - Pod + - resources: + kinds: + - Pod + name: validate-default-proc-mount validate: - message: "Default proc mount should set to Unmasked" + message: Default proc mount should set to Unmasked pattern: spec: containers: - securityContext: procMount: Unmasked -# used by rootless containers + validationFailureAction: Audit diff --git a/test/cli/scenarios_to_cli/other/scenario_validate_selinux_context/policy.yaml b/test/cli/scenarios_to_cli/other/scenario_validate_selinux_context/policy.yaml index d481936748..fd72d55863 100644 --- a/test/cli/scenarios_to_cli/other/scenario_validate_selinux_context/policy.yaml +++ b/test/cli/scenarios_to_cli/other/scenario_validate_selinux_context/policy.yaml @@ -1,24 +1,24 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: validate-selinux-options spec: - validationFailureAction: "audit" + admission: true + background: true rules: - - name: validate-selinux-options - match: - any: - - resources: - kinds: - - Pod + - match: + any: + - resources: + kinds: + - Pod + name: validate-selinux-options validate: - message: "SELinux level is required" + message: SELinux level is required pattern: spec: containers: - securityContext: seLinuxOptions: - level: "?*" -# level: "s0:c25,c968" -# If SELinux security module is loaded on the host operating system, -# we can make sure pods only have access to specified configured level \ No newline at end of file + level: ?* + validationFailureAction: Audit diff --git a/test/cli/scenarios_to_cli/other/scenario_validate_volume_whitelist/policy.yaml b/test/cli/scenarios_to_cli/other/scenario_validate_volume_whitelist/policy.yaml index 83d29af5b7..d005b24178 100644 --- a/test/cli/scenarios_to_cli/other/scenario_validate_volume_whitelist/policy.yaml +++ b/test/cli/scenarios_to_cli/other/scenario_validate_volume_whitelist/policy.yaml @@ -1,25 +1,28 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: validate-volumes-whitelist spec: - validationFailureAction: "audit" + admission: true + background: true rules: - - name: validate-volumes-whitelist - match: + - match: any: - - resources: - kinds: - - Pod + - resources: + kinds: + - Pod + name: validate-volumes-whitelist validate: - message: "Volume type is not of type hostPath, emptyDir, or configMap." anyPattern: - spec: volumes: - - hostPath: "*" + - hostPath: '*' - spec: volumes: - - emptyDir: "*" + - emptyDir: '*' - spec: volumes: - - configMap: "*" + - configMap: '*' + message: Volume type is not of type hostPath, emptyDir, or configMap. + validationFailureAction: Audit diff --git a/test/cli/test-mutate/bug-demo/policy.yaml b/test/cli/test-mutate/bug-demo/policy.yaml index 685ef1aa88..91c93ec64e 100644 --- a/test/cli/test-mutate/bug-demo/policy.yaml +++ b/test/cli/test-mutate/bug-demo/policy.yaml @@ -1,29 +1,26 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: bug-demo annotations: - pod-policies.kyverno.io/autogen-controllers: "none" + pod-policies.kyverno.io/autogen-controllers: none + name: bug-demo spec: + admission: true background: false - validationFailureAction: enforce - rules: - - - name: mutate1 - match: + - match: all: - resources: kinds: - v1/Pod mutate: foreach: - - list: |- - request.object.spec.containers || `[]` - context: + - context: - name: container_path variable: - value: "/spec/containers/{{ elementIndex }}" + value: /spec/containers/{{ elementIndex }} + list: request.object.spec.containers || `[]` patchesJson6902: |- {{ [ @@ -82,3 +79,5 @@ spec: | to_string(@) }} + name: mutate1 + validationFailureAction: Enforce diff --git a/test/cli/test-mutate/connection-draining/policy.yaml b/test/cli/test-mutate/connection-draining/policy.yaml index 102bcc40b3..6a1404bdf6 100644 --- a/test/cli/test-mutate/connection-draining/policy.yaml +++ b/test/cli/test-mutate/connection-draining/policy.yaml @@ -1,50 +1,52 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: disable-connection-draining annotations: - policies.kyverno.io/title: Configure Connection Draining policies.kyverno.io/category: Best Practices policies.kyverno.io/subject: Service + policies.kyverno.io/title: Configure Connection Draining + name: disable-connection-draining spec: + admission: true background: true rules: - - name: clb - match: - resources: - kinds: - - Service - context: + - context: - name: connection_draining_check variable: - default: "empty" + default: empty jmesPath: request.object.metadata.annotations."service.beta.kubernetes.io/aws-load-balancer-connection-draining-enabled" - name: nlb_check variable: default: "false" jmesPath: request.object.metadata.annotations."service.beta.kubernetes.io/aws-load-balancer-type" - preconditions: - all: - - key: "{{ request.object.spec.type }}" - operator: Equals - value: "LoadBalancer" - - key: "{{ connection_draining_check }}" - operator: AnyIn - value: ["true", "empty"] - - key: "{{ nlb_check }}" - operator: AnyNotIn - value: ["external", "nlb"] + match: + any: + - resources: + kinds: + - Service mutate: patchStrategicMerge: metadata: annotations: service.beta.kubernetes.io/aws-load-balancer-connection-draining-enabled: "false" - - name: nlb-no-attributes - match: - resources: - kinds: - - Service - context: + name: clb + preconditions: + all: + - key: '{{ request.object.spec.type }}' + operator: Equals + value: LoadBalancer + - key: '{{ connection_draining_check }}' + operator: AnyIn + value: + - "true" + - empty + - key: '{{ nlb_check }}' + operator: AnyNotIn + value: + - external + - nlb + - context: - name: nlb_check variable: default: "false" @@ -53,19 +55,26 @@ spec: variable: default: "false" jmesPath: request.object.metadata.annotations."service.beta.kubernetes.io/aws-load-balancer-target-group-attributes" - preconditions: - all: - - key: "{{ request.object.spec.type }}" - operator: Equals - value: "LoadBalancer" - - key: "{{ nlb_check }}" - operator: Equals - value: "external" - - key: "{{ tg_attributes }}" - operator: Equals - value: "false" + match: + any: + - resources: + kinds: + - Service mutate: patchStrategicMerge: metadata: annotations: - service.beta.kubernetes.io/aws-load-balancer-target-group-attributes: "deregistration_delay.connection_termination.enabled=true,deregistration_delay.timeout_seconds=0" \ No newline at end of file + service.beta.kubernetes.io/aws-load-balancer-target-group-attributes: deregistration_delay.connection_termination.enabled=true,deregistration_delay.timeout_seconds=0 + name: nlb-no-attributes + preconditions: + all: + - key: '{{ request.object.spec.type }}' + operator: Equals + value: LoadBalancer + - key: '{{ nlb_check }}' + operator: Equals + value: external + - key: '{{ tg_attributes }}' + operator: Equals + value: "false" + validationFailureAction: Audit diff --git a/test/cli/test-mutate/foreach/addIfNotPresent/policies.yaml b/test/cli/test-mutate/foreach/addIfNotPresent/policies.yaml index 6c0849f32d..268928e6ab 100644 --- a/test/cli/test-mutate/foreach/addIfNotPresent/policies.yaml +++ b/test/cli/test-mutate/foreach/addIfNotPresent/policies.yaml @@ -1,22 +1,27 @@ -apiVersion: kyverno.io/v1 -kind: ClusterPolicy -metadata: - name: mutate-emptydir -spec: - rules: - - name: setDefault - match: - resources: - kinds: - - Deployment - mutate: - foreach: - - list: "request.object.spec.template.spec.volumes" - patchStrategicMerge: - spec: - template: - spec: - volumes: - - name: "{{ element.name }}" - (emptyDir): - +(sizeLimit): "20Mi" \ No newline at end of file +--- +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: mutate-emptydir +spec: + admission: true + background: true + rules: + - match: + any: + - resources: + kinds: + - Deployment + mutate: + foreach: + - list: request.object.spec.template.spec.volumes + patchStrategicMerge: + spec: + template: + spec: + volumes: + - (emptyDir): + +(sizeLimit): 20Mi + name: '{{ element.name }}' + name: setDefault + validationFailureAction: Audit diff --git a/test/cli/test-mutate/foreach/cumulativePatch/policies.yaml b/test/cli/test-mutate/foreach/cumulativePatch/policies.yaml index 7beea26d92..de7e0f426e 100644 --- a/test/cli/test-mutate/foreach/cumulativePatch/policies.yaml +++ b/test/cli/test-mutate/foreach/cumulativePatch/policies.yaml @@ -1,26 +1,30 @@ -apiVersion : kyverno.io/v1 +--- +apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: add-default-resources annotations: - pod-policies.kyverno.io/autogen-controllers: "none" + pod-policies.kyverno.io/autogen-controllers: none + name: add-default-resources spec: + admission: true background: false rules: - - name: add-default-requests - match: - resources: + - match: + any: + - resources: kinds: - - Pod - mutate: - foreach: - - list: "request.object.spec.containers" - patchesJson6902: |- - - path: /spec/containers/{{elementIndex}}/resources/requests/memory - op: add - value: "100Mi" - - list: "request.object.spec.containers" - patchesJson6902: |- - - path: /spec/containers/{{elementIndex}}/resources/requests/cpu - op: add - value: "100m" + - Pod + mutate: + foreach: + - list: request.object.spec.containers + patchesJson6902: |- + - path: /spec/containers/{{elementIndex}}/resources/requests/memory + op: add + value: "100Mi" + - list: request.object.spec.containers + patchesJson6902: |- + - path: /spec/containers/{{elementIndex}}/resources/requests/cpu + op: add + value: "100m" + name: add-default-requests + validationFailureAction: Audit diff --git a/test/cli/test-mutate/foreach/policies.yaml b/test/cli/test-mutate/foreach/policies.yaml index 4e308180af..387d307561 100644 --- a/test/cli/test-mutate/foreach/policies.yaml +++ b/test/cli/test-mutate/foreach/policies.yaml @@ -1,47 +1,56 @@ -apiVersion: kyverno.io/v1 -kind: ClusterPolicy -metadata: - name: foreach-json-patch - annotations: - pod-policies.kyverno.io/autogen-controllers: none -spec: - rules: - - name: add-security-context - match: - resources: - kinds: - - Pod - preconditions: - - key: "{{ request.operation }}" - operator: Equals - value: "CREATE" - mutate: - foreach: - - list: "request.object.spec.containers" - patchesJson6902: |- - - path: /spec/containers/{{elementIndex}}/securityContext - op: add - value: {"runAsNonRoot" : true} --- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: mutate-images annotations: pod-policies.kyverno.io/autogen-controllers: none + name: foreach-json-patch spec: - background: false + admission: true + background: true rules: - - name: test - match: - resources: - kinds: - - Pod + - match: + any: + - resources: + kinds: + - Pod mutate: foreach: - - list: "request.object.spec.containers" + - list: request.object.spec.containers + patchesJson6902: |- + - path: /spec/containers/{{elementIndex}}/securityContext + op: add + value: {"runAsNonRoot" : true} + name: add-security-context + preconditions: + all: + - key: '{{ request.operation }}' + operator: Equals + value: CREATE + validationFailureAction: Audit +--- +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + annotations: + pod-policies.kyverno.io/autogen-controllers: none + name: mutate-images +spec: + admission: true + background: false + rules: + - match: + any: + - resources: + kinds: + - Pod + mutate: + foreach: + - list: request.object.spec.containers patchStrategicMerge: spec: containers: - - name: "{{ element.name }}" - image: registry.digitalocean.com/runlevl4/{{ images.containers."{{element.name}}".name}}:{{images.containers."{{element.name}}".tag}} + - image: registry.digitalocean.com/runlevl4/{{ images.containers."{{element.name}}".name}}:{{images.containers."{{element.name}}".tag}} + name: '{{ element.name }}' + name: test + validationFailureAction: Audit diff --git a/test/cli/test-mutate/patched-resource/policy.yaml b/test/cli/test-mutate/patched-resource/policy.yaml index 834524c4bd..0e1164c84d 100644 --- a/test/cli/test-mutate/patched-resource/policy.yaml +++ b/test/cli/test-mutate/patched-resource/policy.yaml @@ -1,29 +1,32 @@ -apiVersion : kyverno.io/v1 +--- +apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: add-default-resources spec: + admission: true background: false rules: - - name: add-default-requests - match: + - match: any: - resources: kinds: - Pod - preconditions: - any: - - key: "{{request.operation}}" - operator: In - value: - - CREATE - - UPDATE mutate: patchStrategicMerge: spec: containers: - - (name): "*" - resources: - requests: - +(memory): "100Mi" - +(cpu): "100m" + - (name): '*' + resources: + requests: + +(cpu): 100m + +(memory): 100Mi + name: add-default-requests + preconditions: + any: + - key: '{{request.operation}}' + operator: AllIn + value: + - CREATE + - UPDATE + validationFailureAction: Audit diff --git a/test/cli/test-mutate/policy.yaml b/test/cli/test-mutate/policy.yaml index f616f5f985..5ae8d7a10e 100644 --- a/test/cli/test-mutate/policy.yaml +++ b/test/cli/test-mutate/policy.yaml @@ -1,100 +1,107 @@ -# Below there are both type of policies: ClusterPolicy and Policy(Namespaced-Policy) - -#ClusterPolicy +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: add-label annotations: - policies.kyverno.io/title: Add nodeSelector policies.kyverno.io/category: Sample + policies.kyverno.io/description: Labels are used as an important source of metadata + describing objects in various ways or triggering other functionality. Labels + are also a very basic concept and should be used throughout Kubernetes. This + policy performs a simple mutation which adds a label `color=orange` to Pods, + Services, ConfigMaps, and Secrets. policies.kyverno.io/subject: Pod - policies.kyverno.io/description: >- - Labels are used as an important source of metadata describing objects in various ways - or triggering other functionality. Labels are also a very basic concept and should be - used throughout Kubernetes. This policy performs a simple mutation which adds a label - `color=orange` to Pods, Services, ConfigMaps, and Secrets. + policies.kyverno.io/title: Add nodeSelector + name: add-label spec: + admission: true background: false rules: - - name: add-label - match: - resources: - kinds: - - Pod + - match: + any: + - resources: + kinds: + - Pod mutate: patchStrategicMerge: metadata: labels: color: orange - - name: "impossible-rule" - match: - resources: - kinds: + name: add-label + - match: + any: + - resources: + kinds: - Pod - preconditions: - all: - - key: "not-the-name" # This precondition should always fail! - operator: In - value: "{{ request.object.metadata.labels | keys(@) }}" mutate: patchStrategicMerge: metadata: labels: - something: "something" - + something: something + name: impossible-rule + preconditions: + all: + - key: not-the-name + operator: AllIn + value: '{{ request.object.metadata.labels | keys(@) }}' + validationFailureAction: Audit --- - -# Policy ( In testing namespace ) apiVersion: kyverno.io/v1 kind: Policy metadata: + annotations: + policies.kyverno.io/category: Sample + policies.kyverno.io/description: The ndots value controls where DNS lookups are + first performed in a cluster and needs to be set to a lower value than the default + of 5 in some cases. This policy mutates all Pods to add the ndots option with + a value of 1. + policies.kyverno.io/subject: Pod + policies.kyverno.io/title: Add ndots name: add-ndots namespace: testing - annotations: - policies.kyverno.io/title: Add ndots - policies.kyverno.io/category: Sample - policies.kyverno.io/subject: Pod - policies.kyverno.io/description: >- - The ndots value controls where DNS lookups are first performed in a cluster - and needs to be set to a lower value than the default of 5 in some cases. - This policy mutates all Pods to add the ndots option with a value of 1. spec: + admission: true background: false rules: - - name: add-ndots - match: - resources: - kinds: - - Pod + - match: + any: + - resources: + kinds: + - Pod mutate: patchStrategicMerge: spec: dnsConfig: options: - - name: ndots - value: "1" + - name: ndots + value: "1" + name: add-ndots + validationFailureAction: Audit --- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: example spec: + admission: true + background: true rules: - - name: object_from_lists - context: - - name: annotations - variable: - jmesPath: items(request.object.metadata.annotations, 'key', 'value')[?starts_with(key, 'key')] - - name: annotations - variable: - jmesPath: object_from_lists(annotations[].key, annotations[].value) + - context: + - name: annotations + variable: + jmesPath: items(request.object.metadata.annotations, 'key', 'value')[?starts_with(key, + 'key')] + - name: annotations + variable: + jmesPath: object_from_lists(annotations[].key, annotations[].value) match: - resources: - kinds: - - Pod + any: + - resources: + kinds: + - Pod mutate: patchesJson6902: |- - path: "/metadata/annotations" op: replace value: {{ annotations }} + name: object_from_lists + validationFailureAction: Audit diff --git a/test/more/add_default_labels.yaml b/test/more/add_default_labels.yaml index 15225d2484..37d1207e2c 100644 --- a/test/more/add_default_labels.yaml +++ b/test/more/add_default_labels.yaml @@ -1,19 +1,23 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: add-default-labels spec: + admission: true background: false rules: - - name: add-default-labels - match: - resources: - kinds: - - Pod - - Service - - Namespace + - match: + any: + - resources: + kinds: + - Pod + - Service + - Namespace mutate: patchStrategicMerge: metadata: labels: - custom-foo-label: my-bar-default \ No newline at end of file + custom-foo-label: my-bar-default + name: add-default-labels + validationFailureAction: Audit diff --git a/test/more/add_pod_default_seccompprofile.yaml b/test/more/add_pod_default_seccompprofile.yaml index 13b75941cd..047ef28d32 100644 --- a/test/more/add_pod_default_seccompprofile.yaml +++ b/test/more/add_pod_default_seccompprofile.yaml @@ -1,34 +1,39 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: add-pod-default-seccompprofile annotations: policies.kyverno.io/category: Security - policies.kyverno.io/description: Seccomp Profiles restrict the system calls that can be made - from a process. The Linux kernel has a few hundred system calls, but most of them are not - needed by any given process. If a process can be compromised and tricked into making other - system calls, though, it may lead to a security vulnerability that could result in the - compromise of the whole system. By restricting what system calls can be made, seccomp is - a key component for building application sandboxes. + policies.kyverno.io/description: Seccomp Profiles restrict the system calls that + can be made from a process. The Linux kernel has a few hundred system calls, + but most of them are not needed by any given process. If a process can be compromised + and tricked into making other system calls, though, it may lead to a security + vulnerability that could result in the compromise of the whole system. By restricting + what system calls can be made, seccomp is a key component for building application + sandboxes. + name: add-pod-default-seccompprofile spec: + admission: true background: false - validationFailureAction: audit rules: - - name: add-pod-default-seccompprofile + - exclude: + any: + - resources: + namespaces: + - kube-system + - kube-public + - default + - kyverno match: - resources: - kinds: - - Pod - exclude: - resources: - namespaces: - - "kube-system" - - "kube-public" - - "default" - - "kyverno" + any: + - resources: + kinds: + - Pod mutate: patchStrategicMerge: spec: securityContext: seccompProfile: - type: RuntimeDefault \ No newline at end of file + type: RuntimeDefault + name: add-pod-default-seccompprofile + validationFailureAction: Audit diff --git a/test/more/create_pod_antiaffinity.yaml b/test/more/create_pod_antiaffinity.yaml index beb26bf03a..219dbb7a52 100644 --- a/test/more/create_pod_antiaffinity.yaml +++ b/test/more/create_pod_antiaffinity.yaml @@ -1,35 +1,38 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: insert-podantiaffinity spec: + admission: true + background: true rules: - - name: insert-podantiaffinity - match: - resources: + - match: + any: + - resources: kinds: - - Deployment - preconditions: - # This precondition ensures that the label `app` is applied to Pods within the Deployment resource. - - key: "{{request.object.metadata.labels.app}}" + - Deployment + mutate: + patchStrategicMerge: + spec: + template: + spec: + +(affinity): + +(podAntiAffinity): + +(preferredDuringSchedulingIgnoredDuringExecution): + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: app + operator: In + values: + - '{{request.object.metadata.labels.app}}' + topologyKey: kubernetes.io/hostname + weight: 1 + name: insert-podantiaffinity + preconditions: + all: + - key: '{{request.object.metadata.labels.app}}' operator: NotEquals value: "" - # Mutates the Deployment resource to add fields. - mutate: - patchStrategicMerge: - spec: - template: - spec: - # Add the `affinity` key and others if not already specified in the Deployment manifest. - +(affinity): - +(podAntiAffinity): - +(preferredDuringSchedulingIgnoredDuringExecution): - - weight: 1 - podAffinityTerm: - topologyKey: "kubernetes.io/hostname" - labelSelector: - matchExpressions: - - key: app - operator: In - values: - - "{{request.object.metadata.labels.app}}" \ No newline at end of file + validationFailureAction: Audit diff --git a/test/more/disallow_secrets_from_env_vars.yaml b/test/more/disallow_secrets_from_env_vars.yaml index 1136a11afa..dd28dd4603 100644 --- a/test/more/disallow_secrets_from_env_vars.yaml +++ b/test/more/disallow_secrets_from_env_vars.yaml @@ -1,22 +1,25 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: secrets-not-from-env-vars spec: + admission: true background: false - validationFailureAction: audit rules: - - name: secrets-not-from-env-vars - match: - resources: - kinds: - - Pod + - match: + any: + - resources: + kinds: + - Pod + name: secrets-not-from-env-vars validate: - message: "Secrets must be mounted as volumes, not as environment variables." + message: Secrets must be mounted as volumes, not as environment variables. pattern: spec: containers: - - name: "*" - =(env): + - =(env): - =(valueFrom): - X(secretKeyRef): "null" \ No newline at end of file + X(secretKeyRef): "null" + name: '*' + validationFailureAction: Audit diff --git a/test/more/ensure_probes_different.yaml b/test/more/ensure_probes_different.yaml index e91576b414..fa0ed7ac69 100644 --- a/test/more/ensure_probes_different.yaml +++ b/test/more/ensure_probes_different.yaml @@ -1,66 +1,64 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: validate-probes annotations: - # Only applies to pods originating from DaemonSet, Deployment, or StatefulSet. pod-policies.kyverno.io/autogen-controllers: DaemonSet,Deployment,StatefulSet + name: validate-probes spec: - validationFailureAction: enforce + admission: true background: false rules: - # Checks the first container in a Pod. - - name: validate-probes-c0 - match: - resources: + - match: + any: + - resources: kinds: - - Pod - validate: - message: "Liveness and readiness probes cannot be the same." - # A `deny` rule is different in structure than a `validate` rule and inverts the check. It uses `conditions` written in JMESPath notation upon which to base its decisions. - deny: - conditions: - # In this condition, it checks the entire map structure of the `readinessProbe` against that of the `livenessProbe`. If both are found to be equal, the Pod creation - # request will be denied. - - key: "{{ request.object.spec.containers[0].readinessProbe }}" - operator: Equals - value: "{{ request.object.spec.containers[0].livenessProbe }}" - # Checks the second container in a Pod. - - name: validate-probes-c1 - match: - resources: + - Pod + name: validate-probes-c0 + validate: + deny: + conditions: + - key: '{{ request.object.spec.containers[0].readinessProbe }}' + operator: Equals + value: '{{ request.object.spec.containers[0].livenessProbe }}' + message: Liveness and readiness probes cannot be the same. + - match: + any: + - resources: kinds: - - Pod - validate: - message: "Liveness and readiness probes cannot be the same." - deny: - conditions: - - key: "{{ request.object.spec.containers[1].readinessProbe }}" - operator: Equals - value: "{{ request.object.spec.containers[1].livenessProbe }}" - # Checks the third container in a Pod. - - name: validate-probes-c2 - match: - resources: + - Pod + name: validate-probes-c1 + validate: + deny: + conditions: + - key: '{{ request.object.spec.containers[1].readinessProbe }}' + operator: Equals + value: '{{ request.object.spec.containers[1].livenessProbe }}' + message: Liveness and readiness probes cannot be the same. + - match: + any: + - resources: kinds: - - Pod - validate: - message: "Liveness and readiness probes cannot be the same." - deny: - conditions: - - key: "{{ request.object.spec.containers[2].readinessProbe }}" - operator: Equals - value: "{{ request.object.spec.containers[2].livenessProbe }}" - # Checks the fourth container in a Pod. - - name: validate-probes-c3 - match: - resources: + - Pod + name: validate-probes-c2 + validate: + deny: + conditions: + - key: '{{ request.object.spec.containers[2].readinessProbe }}' + operator: Equals + value: '{{ request.object.spec.containers[2].livenessProbe }}' + message: Liveness and readiness probes cannot be the same. + - match: + any: + - resources: kinds: - - Pod - validate: - message: "Liveness and readiness probes cannot be the same." - deny: - conditions: - - key: "{{ request.object.spec.containers[3].readinessProbe }}" - operator: Equals - value: "{{ request.object.spec.containers[3].livenessProbe }}" \ No newline at end of file + - Pod + name: validate-probes-c3 + validate: + deny: + conditions: + - key: '{{ request.object.spec.containers[3].readinessProbe }}' + operator: Equals + value: '{{ request.object.spec.containers[3].livenessProbe }}' + message: Liveness and readiness probes cannot be the same. + validationFailureAction: Enforce diff --git a/test/more/require_deployments_have_multiple_replicas.yaml b/test/more/require_deployments_have_multiple_replicas.yaml index a0d411159a..66714e84c4 100644 --- a/test/more/require_deployments_have_multiple_replicas.yaml +++ b/test/more/require_deployments_have_multiple_replicas.yaml @@ -1,24 +1,29 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: deployment-has-multiple-replicas spec: - validationFailureAction: audit + admission: true + background: true rules: - - name: deployment-has-multiple-replicas - match: - resources: - kinds: - - Deployment - exclude: - resources: + - exclude: + any: + - resources: namespaces: - kyverno - kube-system - kube-node-lease - kube-public - validate: - message: "Deployments must have more than one replica to ensure availability." - pattern: - spec: - replicas: ">1" \ No newline at end of file + match: + any: + - resources: + kinds: + - Deployment + name: deployment-has-multiple-replicas + validate: + message: Deployments must have more than one replica to ensure availability. + pattern: + spec: + replicas: '>1' + validationFailureAction: Audit diff --git a/test/more/require_drop_all.yaml b/test/more/require_drop_all.yaml index 5b906449b1..0803cea94e 100644 --- a/test/more/require_drop_all.yaml +++ b/test/more/require_drop_all.yaml @@ -1,33 +1,40 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: drop-all-capabilities spec: - validationFailureAction: audit + admission: true + background: true rules: - - name: drop-all-containers - match: - resources: - kinds: - - Pod + - match: + any: + - resources: + kinds: + - Pod + name: drop-all-containers validate: - message: "Drop all must be defined for every container in the Pod." + message: Drop all must be defined for every container in the Pod. pattern: spec: containers: - securityContext: capabilities: - drop: ["ALL"] - - name: drop-all-initcontainers - match: - resources: - kinds: - - Pod + drop: + - ALL + - match: + any: + - resources: + kinds: + - Pod + name: drop-all-initcontainers validate: - message: "Drop all must be defined for every container in the Pod." + message: Drop all must be defined for every container in the Pod. pattern: spec: initContainers: - securityContext: capabilities: - drop: ["ALL"] \ No newline at end of file + drop: + - ALL + validationFailureAction: Audit diff --git a/test/more/restrict_automount_sa_token.yaml b/test/more/restrict_automount_sa_token.yaml index 202a8dae80..7635037d12 100644 --- a/test/more/restrict_automount_sa_token.yaml +++ b/test/more/restrict_automount_sa_token.yaml @@ -1,22 +1,27 @@ -apiVersion : kyverno.io/v1 +--- +apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: restrict-automount-sa-token annotations: policies.kyverno.io/category: Security - policies.kyverno.io/description: Kubernetes automatically mounts service account - credentials in each pod. The service account may be assigned roles allowing pods - to access API resources. To restrict access, opt out of auto-mounting tokens by - setting automountServiceAccountToken to false. + policies.kyverno.io/description: Kubernetes automatically mounts service account + credentials in each pod. The service account may be assigned roles allowing + pods to access API resources. To restrict access, opt out of auto-mounting tokens + by setting automountServiceAccountToken to false. + name: restrict-automount-sa-token spec: + admission: true + background: true rules: - - name: validate-automountServiceAccountToken - match: - resources: - kinds: - - Pod + - match: + any: + - resources: + kinds: + - Pod + name: validate-automountServiceAccountToken validate: - message: "Auto-mounting of Service Account tokens is not allowed" + message: Auto-mounting of Service Account tokens is not allowed pattern: spec: - automountServiceAccountToken: false \ No newline at end of file + automountServiceAccountToken: false + validationFailureAction: Audit diff --git a/test/more/restrict_ingress_classes.yaml b/test/more/restrict_ingress_classes.yaml index 973ad3e01c..1efc90a9a4 100644 --- a/test/more/restrict_ingress_classes.yaml +++ b/test/more/restrict_ingress_classes.yaml @@ -1,22 +1,27 @@ -apiVersion : kyverno.io/v1 +--- +apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: restrict-ingress-classes annotations: policies.kyverno.io/category: Workload Management - policies.kyverno.io/description: It can be useful to restrict Ingress resources to a set of - known ingress classes that are allowed in the cluster. You can customize this policy to - allow ingress classes that are configured in the cluster. + policies.kyverno.io/description: It can be useful to restrict Ingress resources + to a set of known ingress classes that are allowed in the cluster. You can customize + this policy to allow ingress classes that are configured in the cluster. + name: restrict-ingress-classes spec: + admission: true + background: true rules: - - name: validate-ingress - match: - resources: - kinds: - - Ingress + - match: + any: + - resources: + kinds: + - Ingress + name: validate-ingress validate: - message: "Unknown ingress class" + message: Unknown ingress class pattern: metadata: annotations: - kubernetes.io/ingress.class: "F5 | nginx" + kubernetes.io/ingress.class: F5 | nginx + validationFailureAction: Audit diff --git a/test/more/restrict_loadbalancer.yaml b/test/more/restrict_loadbalancer.yaml index 408b1175e5..fe0fb12e32 100644 --- a/test/more/restrict_loadbalancer.yaml +++ b/test/more/restrict_loadbalancer.yaml @@ -1,17 +1,21 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: no-loadbalancers spec: - validationFailureAction: audit + admission: true + background: true rules: - - name: no-LoadBalancer - match: - resources: - kinds: - - Service + - match: + any: + - resources: + kinds: + - Service + name: no-LoadBalancer validate: - message: "Service of type LoadBalancer is not allowed." + message: Service of type LoadBalancer is not allowed. pattern: spec: - type: "!LoadBalancer" \ No newline at end of file + type: '!LoadBalancer' + validationFailureAction: Audit diff --git a/test/more/restrict_usergroup_fsgroup_id.yaml b/test/more/restrict_usergroup_fsgroup_id.yaml index 5106351230..a57db0f022 100644 --- a/test/more/restrict_usergroup_fsgroup_id.yaml +++ b/test/more/restrict_usergroup_fsgroup_id.yaml @@ -1,45 +1,53 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: validate-userid-groupid-fsgroup annotations: policies.kyverno.io/category: Security Context - policies.kyverno.io/description: All processes inside the pod can be made to run with specific user - and groupID by setting 'runAsUser' and 'runAsGroup' respectively. 'fsGroup' can be specified - to make sure any file created in the volume with have the specified groupID. These options can be - used to validate the IDs used for user and group. + policies.kyverno.io/description: All processes inside the pod can be made to run + with specific user and groupID by setting 'runAsUser' and 'runAsGroup' respectively. + 'fsGroup' can be specified to make sure any file created in the volume with + have the specified groupID. These options can be used to validate the IDs used + for user and group. + name: validate-userid-groupid-fsgroup spec: + admission: true + background: true rules: - - name: validate-userid - match: - resources: - kinds: - - Pod + - match: + any: + - resources: + kinds: + - Pod + name: validate-userid validate: - message: "User ID should be 1000" + message: User ID should be 1000 pattern: spec: securityContext: - runAsUser: '1000' - - name: validate-groupid - match: - resources: - kinds: - - Pod + runAsUser: "1000" + - match: + any: + - resources: + kinds: + - Pod + name: validate-groupid validate: - message: "Group ID should be 3000" + message: Group ID should be 3000 pattern: spec: securityContext: - runAsGroup: '3000' - - name: validate-fsgroup - match: - resources: - kinds: - - Pod + runAsGroup: "3000" + - match: + any: + - resources: + kinds: + - Pod + name: validate-fsgroup validate: - message: "fsgroup should be 2000" + message: fsgroup should be 2000 pattern: spec: securityContext: - fsGroup: '2000' \ No newline at end of file + fsGroup: "2000" + validationFailureAction: Audit diff --git a/test/more/spread_pods_across_topology.yaml b/test/more/spread_pods_across_topology.yaml index 94cfbcc95b..2a0a78ef0c 100644 --- a/test/more/spread_pods_across_topology.yaml +++ b/test/more/spread_pods_across_topology.yaml @@ -1,29 +1,31 @@ +--- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: spread-pods spec: + admission: true + background: true rules: - - name: spread-pods-across-nodes - # Matches any Deployment with the label `distributed=required` - match: - resources: + - match: + any: + - resources: kinds: - Deployment selector: matchLabels: distributed: required - # Mutates the incoming Deployment. - mutate: - patchStrategicMerge: - spec: - template: - spec: - # Adds the topologySpreadConstraints field if non-existent in the request. - +(topologySpreadConstraints): - - maxSkew: 1 - topologyKey: zone - whenUnsatisfiable: DoNotSchedule - labelSelector: - matchLabels: - distributed: required \ No newline at end of file + mutate: + patchStrategicMerge: + spec: + template: + spec: + +(topologySpreadConstraints): + - labelSelector: + matchLabels: + distributed: required + maxSkew: 1 + topologyKey: zone + whenUnsatisfiable: DoNotSchedule + name: spread-pods-across-nodes + validationFailureAction: Audit