diff --git a/content/en/docs/CRDs/_index.md b/content/en/docs/CRDs/_index.md index 449412812..406970570 100644 --- a/content/en/docs/CRDs/_index.md +++ b/content/en/docs/CRDs/_index.md @@ -64,4 +64,4 @@ FIELDS: seconds. ``` -Kyverno's support for structural schemas also enables integrated help in Kubernetes enabled Integrated Development Environments (IDEs) like [VS Code](https://code.visualstudio.com/) with the [Kubernetes Extension](https://code.visualstudio.com/docs/azure/kubernetes) installed. +Kyverno's support for structural schemas also enables integrated help in Kubernetes enabled Integrated Development Environments (IDEs) like [VS Code](https://code.visualstudio.com/) with the [Kubernetes Extension](https://code.visualstudio.com/docs/azure/kubernetes#_install-the-kubernetes-extension) installed. diff --git a/content/en/policies/argo-cel/application-prevent-default-project/application-prevent-default-project.md b/content/en/policies/argo-cel/application-prevent-default-project/application-prevent-default-project.md index bf4336668..94e65f41a 100644 --- a/content/en/policies/argo-cel/application-prevent-default-project/application-prevent-default-project.md +++ b/content/en/policies/argo-cel/application-prevent-default-project/application-prevent-default-project.md @@ -42,7 +42,7 @@ spec: validate: cel: expressions: - - expression: "has(object.spec.project) && object.spec.project != 'default'" + - expression: "object.spec.?project.orValue('') != 'default'" message: "The default project may not be used in an Application." diff --git a/content/en/policies/argo/application-field-validation/application-field-validation.md b/content/en/policies/argo/application-field-validation/application-field-validation.md index fc9b92511..d17c2f850 100644 --- a/content/en/policies/argo/application-field-validation/application-field-validation.md +++ b/content/en/policies/argo/application-field-validation/application-field-validation.md @@ -29,7 +29,7 @@ metadata: Path or chart must be specified but never both. And destination.name or destination.server must be specified but never both. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: source-path-chart diff --git a/content/en/policies/argo/application-prevent-default-project/application-prevent-default-project.md b/content/en/policies/argo/application-prevent-default-project/application-prevent-default-project.md index 6341ea0e6..012569b29 100644 --- a/content/en/policies/argo/application-prevent-default-project/application-prevent-default-project.md +++ b/content/en/policies/argo/application-prevent-default-project/application-prevent-default-project.md @@ -27,7 +27,7 @@ metadata: policies.kyverno.io/description: >- This policy prevents the use of the default project in an Application. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: default-project diff --git a/content/en/policies/argo/application-prevent-updates-project/application-prevent-updates-project.md b/content/en/policies/argo/application-prevent-updates-project/application-prevent-updates-project.md index 917c6cdfc..6c87a5dda 100644 --- a/content/en/policies/argo/application-prevent-updates-project/application-prevent-updates-project.md +++ b/content/en/policies/argo/application-prevent-updates-project/application-prevent-updates-project.md @@ -27,7 +27,7 @@ metadata: policies.kyverno.io/description: >- This policy prevents updates to the project field after an Application is created. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: project-updates diff --git a/content/en/policies/argo/applicationset-name-matches-project/applicationset-name-matches-project.md b/content/en/policies/argo/applicationset-name-matches-project/applicationset-name-matches-project.md index 491dd8b9e..73c2b4a38 100644 --- a/content/en/policies/argo/applicationset-name-matches-project/applicationset-name-matches-project.md +++ b/content/en/policies/argo/applicationset-name-matches-project/applicationset-name-matches-project.md @@ -28,7 +28,7 @@ metadata: This policy ensures that the name of the ApplicationSet is the same value provided in the project. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: match-name diff --git a/content/en/policies/argo/appproject-clusterresourceblacklist/appproject-clusterresourceblacklist.md b/content/en/policies/argo/appproject-clusterresourceblacklist/appproject-clusterresourceblacklist.md index b3fb6b8f2..25c63e3fa 100644 --- a/content/en/policies/argo/appproject-clusterresourceblacklist/appproject-clusterresourceblacklist.md +++ b/content/en/policies/argo/appproject-clusterresourceblacklist/appproject-clusterresourceblacklist.md @@ -31,7 +31,7 @@ metadata: enforce that all AppProjects specify clusterResourceBlacklist and that their group and kind have wildcards as values. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: has-wildcard diff --git a/content/en/policies/argo/argo-cluster-generation-from-rancher-capi/argo-cluster-generation-from-rancher-capi.md b/content/en/policies/argo/argo-cluster-generation-from-rancher-capi/argo-cluster-generation-from-rancher-capi.md index b4297e31b..17f7a8e29 100644 --- a/content/en/policies/argo/argo-cluster-generation-from-rancher-capi/argo-cluster-generation-from-rancher-capi.md +++ b/content/en/policies/argo/argo-cluster-generation-from-rancher-capi/argo-cluster-generation-from-rancher-capi.md @@ -25,7 +25,7 @@ metadata: policies.kyverno.io/minversion: 1.7.0 kyverno.io/kubernetes-version: "1.23" policies.kyverno.io/description: >- - This policy generates and synchronizes Argo CD cluster secrets from Rancher + This policy generates and synchronizes Argo CD cluster secrets from Rancher managed cluster.provisioning.cattle.io/v1 resources and their corresponding CAPI secrets. In this solution, Argo CD integrates with Rancher managed clusters via the central Rancher authentication proxy which shares the network endpoint of the Rancher API/GUI. @@ -33,6 +33,7 @@ metadata: "Cluster-API cluster auto-registration" and Rancher issue https://github.com/rancher/rancher/issues/38053 "Fix type and labels Rancher v2 provisioner specifies when creating CAPI Cluster Secret". spec: + generateExisting: true rules: - name: source-rancher-non-local-cluster-and-capi-secret match: @@ -98,7 +99,6 @@ spec: } jmesPath: 'to_string(@)' generate: - generateExisting: true synchronize: true apiVersion: v1 kind: Secret diff --git a/content/en/policies/aws-cel/require-encryption-aws-loadbalancers/require-encryption-aws-loadbalancers.md b/content/en/policies/aws-cel/require-encryption-aws-loadbalancers/require-encryption-aws-loadbalancers.md index 7bfa0549d..a30a5180d 100644 --- a/content/en/policies/aws-cel/require-encryption-aws-loadbalancers/require-encryption-aws-loadbalancers.md +++ b/content/en/policies/aws-cel/require-encryption-aws-loadbalancers/require-encryption-aws-loadbalancers.md @@ -48,8 +48,7 @@ spec: cel: expressions: - expression: >- - has(object.metadata.annotations) && - 'service.beta.kubernetes.io/aws-load-balancer-ssl-cert' in object.metadata.annotations && object.metadata.annotations['service.beta.kubernetes.io/aws-load-balancer-ssl-cert'] != '' + object.metadata.?annotations[?'service.beta.kubernetes.io/aws-load-balancer-ssl-cert'].orValue('') != '' message: "Service of type LoadBalancer must carry the annotation service.beta.kubernetes.io/aws-load-balancer-ssl-cert." diff --git a/content/en/policies/aws/require-aws-node-irsa/require-aws-node-irsa.md b/content/en/policies/aws/require-aws-node-irsa/require-aws-node-irsa.md index be232fb02..f4c5c6f29 100644 --- a/content/en/policies/aws/require-aws-node-irsa/require-aws-node-irsa.md +++ b/content/en/policies/aws/require-aws-node-irsa/require-aws-node-irsa.md @@ -33,7 +33,7 @@ metadata: the `aws-node` DaemonSet to use IRSA. This policy ensures that the `aws-node` DaemonSet running in the `kube-system` Namespace is not still using the `aws-node` ServiceAccount. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: validate-node-daemonset-irsa diff --git a/content/en/policies/aws/require-encryption-aws-loadbalancers/require-encryption-aws-loadbalancers.md b/content/en/policies/aws/require-encryption-aws-loadbalancers/require-encryption-aws-loadbalancers.md index 651c0c873..b5bb513f8 100644 --- a/content/en/policies/aws/require-encryption-aws-loadbalancers/require-encryption-aws-loadbalancers.md +++ b/content/en/policies/aws/require-encryption-aws-loadbalancers/require-encryption-aws-loadbalancers.md @@ -30,7 +30,7 @@ metadata: that Services of type LoadBalancer contain the annotation service.beta.kubernetes.io/aws-load-balancer-ssl-cert with some value. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: aws-loadbalancer-has-ssl-cert diff --git a/content/en/policies/best-practices-cel/check-deprecated-apis/check-deprecated-apis.md b/content/en/policies/best-practices-cel/check-deprecated-apis/check-deprecated-apis.md new file mode 100644 index 000000000..38d31b62f --- /dev/null +++ b/content/en/policies/best-practices-cel/check-deprecated-apis/check-deprecated-apis.md @@ -0,0 +1,111 @@ +--- +title: "Check deprecated APIs in CEL expressions" +category: Best Practices in CEL +version: +subject: Kubernetes APIs +policyType: "validate" +description: > + Kubernetes APIs are sometimes deprecated and removed after a few releases. As a best practice, older API versions should be replaced with newer versions. This policy validates for APIs that are deprecated or scheduled for removal. Note that checking for some of these resources may require modifying the Kyverno ConfigMap to remove filters. PodSecurityPolicy is removed in v1.25 so therefore the validate-v1-25-removals rule may not completely work on 1.25+. +--- + +## Policy Definition +/best-practices-cel/check-deprecated-apis/check-deprecated-apis.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: check-deprecated-apis + annotations: + policies.kyverno.io/title: Check deprecated APIs in CEL expressions + policies.kyverno.io/category: Best Practices in CEL + policies.kyverno.io/subject: Kubernetes APIs + kyverno.io/kyverno-version: 1.12.1 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/description: >- + Kubernetes APIs are sometimes deprecated and removed after a few releases. + As a best practice, older API versions should be replaced with newer versions. + This policy validates for APIs that are deprecated or scheduled for removal. + Note that checking for some of these resources may require modifying the Kyverno + ConfigMap to remove filters. PodSecurityPolicy is removed in v1.25 + so therefore the validate-v1-25-removals rule may not completely work on 1.25+. +spec: + validationFailureAction: Audit + background: true + rules: + - name: validate-v1-25-removals + match: + any: + - resources: + # NOTE: PodSecurityPolicy is completely removed in 1.25. + kinds: + - batch/*/CronJob + - discovery.k8s.io/*/EndpointSlice + - events.k8s.io/*/Event + - policy/*/PodDisruptionBudget + - policy/*/PodSecurityPolicy + - node.k8s.io/*/RuntimeClass + celPreconditions: + - name: "allowed-api-versions" + expression: "object.apiVersion in ['batch/v1beta1', 'discovery.k8s.io/v1beta1', 'events.k8s.io/v1beta1', 'policy/v1beta1', 'node.k8s.io/v1beta1']" + validate: + cel: + expressions: + - expression: "false" + messageExpression: >- + object.apiVersion + '/' + object.kind + ' is deprecated and will be removed in v1.25. + See: https://kubernetes.io/docs/reference/using-api/deprecation-guide/' + - name: validate-v1-26-removals + match: + any: + - resources: + kinds: + - flowcontrol.apiserver.k8s.io/*/FlowSchema + - flowcontrol.apiserver.k8s.io/*/PriorityLevelConfiguration + - autoscaling/*/HorizontalPodAutoscaler + celPreconditions: + - name: "allowed-api-versions" + expression: "object.apiVersion in ['flowcontrol.apiserver.k8s.io/v1beta1', 'autoscaling/v2beta2']" + validate: + cel: + expressions: + - expression: "false" + messageExpression: >- + object.apiVersion + '/' + object.kind + ' is deprecated and will be removed in v1.26. + See: https://kubernetes.io/docs/reference/using-api/deprecation-guide/' + - name: validate-v1-27-removals + match: + any: + - resources: + kinds: + - storage.k8s.io/*/CSIStorageCapacity + celPreconditions: + - name: "allowed-api-versions" + expression: "object.apiVersion in ['storage.k8s.io/v1beta1']" + validate: + cel: + expressions: + - expression: "false" + messageExpression: >- + object.apiVersion + '/' + object.kind + ' is deprecated and will be removed in v1.27. + See: https://kubernetes.io/docs/reference/using-api/deprecation-guide/' + - name: validate-v1-29-removals + match: + any: + - resources: + kinds: + - flowcontrol.apiserver.k8s.io/*/FlowSchema + - flowcontrol.apiserver.k8s.io/*/PriorityLevelConfiguration + celPreconditions: + - name: "object.apiVersion" + expression: "object.apiVersion in ['flowcontrol.apiserver.k8s.io/v1beta2']" + validate: + cel: + expressions: + - expression: "false" + messageExpression: >- + object.apiVersion + '/' + object.kind + ' is deprecated and will be removed in v1.29. + See: https://kubernetes.io/docs/reference/using-api/deprecation-guide/' + + +``` diff --git a/content/en/policies/best-practices-cel/disallow-empty-ingress-host/disallow-empty-ingress-host.md b/content/en/policies/best-practices-cel/disallow-empty-ingress-host/disallow-empty-ingress-host.md index 56bef4a86..52d1c41ea 100644 --- a/content/en/policies/best-practices-cel/disallow-empty-ingress-host/disallow-empty-ingress-host.md +++ b/content/en/policies/best-practices-cel/disallow-empty-ingress-host/disallow-empty-ingress-host.md @@ -44,8 +44,7 @@ spec: cel: expressions: - expression: >- - !has(object.spec.rules) || - object.spec.rules.all(rule, has(rule.host) && has(rule.http)) + object.spec.?rules.orValue([]).all(rule, has(rule.host) && has(rule.http)) message: "The Ingress host name must be defined, not empty." diff --git a/content/en/policies/best-practices-cel/require-drop-all/require-drop-all.md b/content/en/policies/best-practices-cel/require-drop-all/require-drop-all.md index 6f9a8eec4..6728875e5 100644 --- a/content/en/policies/best-practices-cel/require-drop-all/require-drop-all.md +++ b/content/en/policies/best-practices-cel/require-drop-all/require-drop-all.md @@ -46,14 +46,11 @@ spec: cel: variables: - name: allContainers - expression: "(object.spec.containers + (has(object.spec.initContainers) ? object.spec.initContainers : []) + (has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []))" + expression: "object.spec.containers + object.spec.?initContainers.orValue([]) + object.spec.?ephemeralContainers.orValue([])" expressions: - expression: >- variables.allContainers.all(container, - has(container.securityContext) && - has(container.securityContext.capabilities) && - has(container.securityContext.capabilities.drop) && - container.securityContext.capabilities.drop.exists(capability, capability.upperAscii() == 'ALL')) + container.?securityContext.?capabilities.?drop.orValue([]).exists(capability, capability.upperAscii() == 'ALL')) message: "Containers must drop `ALL` capabilities." diff --git a/content/en/policies/best-practices-cel/require-drop-cap-net-raw/require-drop-cap-net-raw.md b/content/en/policies/best-practices-cel/require-drop-cap-net-raw/require-drop-cap-net-raw.md index 134b8d1eb..44e744fc9 100644 --- a/content/en/policies/best-practices-cel/require-drop-cap-net-raw/require-drop-cap-net-raw.md +++ b/content/en/policies/best-practices-cel/require-drop-cap-net-raw/require-drop-cap-net-raw.md @@ -46,17 +46,15 @@ spec: validate: cel: variables: + - name: mustDropCapabilities + expression: "['CAP_NET_RAW','NET_RAW']" - name: allContainers - expression: "(object.spec.containers + (has(object.spec.initContainers) ? object.spec.initContainers : []) + (has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []))" + expression: "object.spec.containers + object.spec.?initContainers.orValue([]) + object.spec.?ephemeralContainers.orValue([])" expressions: - expression: >- variables.allContainers.all(container, - has(container.securityContext) && - has(container.securityContext.capabilities) && - has(container.securityContext.capabilities.drop) && - container.securityContext.capabilities.drop.exists(capability, capability.upperAscii() == 'CAP_NET_RAW')) + container.?securityContext.?capabilities.?drop.orValue([]).exists(capability, capability.upperAscii() in variables.mustDropCapabilities)) message: >- Containers must drop the `CAP_NET_RAW` capability. - ``` diff --git a/content/en/policies/best-practices-cel/require-labels/require-labels.md b/content/en/policies/best-practices-cel/require-labels/require-labels.md index 3bdb82cc1..5c6a0df55 100644 --- a/content/en/policies/best-practices-cel/require-labels/require-labels.md +++ b/content/en/policies/best-practices-cel/require-labels/require-labels.md @@ -45,8 +45,7 @@ spec: cel: expressions: - expression: >- - has(object.metadata.labels) && - 'app.kubernetes.io/name' in object.metadata.labels && object.metadata.labels['app.kubernetes.io/name'] != "" + object.metadata.?labels[?'app.kubernetes.io/name'].orValue('') != "" message: "The label `app.kubernetes.io/name` is required." diff --git a/content/en/policies/best-practices-cel/require-ro-rootfs/require-ro-rootfs.md b/content/en/policies/best-practices-cel/require-ro-rootfs/require-ro-rootfs.md index 188eb9ce6..09ebc0920 100644 --- a/content/en/policies/best-practices-cel/require-ro-rootfs/require-ro-rootfs.md +++ b/content/en/policies/best-practices-cel/require-ro-rootfs/require-ro-rootfs.md @@ -47,8 +47,7 @@ spec: expressions: - expression: >- object.spec.containers.all(container, - has(container.securityContext) && - container.securityContext.readOnlyRootFilesystem == true) + container.?securityContext.?readOnlyRootFilesystem.orValue(false) == true) message: "Root filesystem must be read-only." diff --git a/content/en/policies/best-practices-cel/restrict-image-registries/restrict-image-registries.md b/content/en/policies/best-practices-cel/restrict-image-registries/restrict-image-registries.md index 6f6471e3e..f6acb3276 100644 --- a/content/en/policies/best-practices-cel/restrict-image-registries/restrict-image-registries.md +++ b/content/en/policies/best-practices-cel/restrict-image-registries/restrict-image-registries.md @@ -46,7 +46,7 @@ spec: cel: variables: - name: allContainers - expression: "(object.spec.containers + (has(object.spec.initContainers) ? object.spec.initContainers : []) + (has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []))" + expression: "object.spec.containers + object.spec.?initContainers.orValue([]) + object.spec.?ephemeralContainers.orValue([])" expressions: - expression: "variables.allContainers.all(container, container.image.startsWith('eu.foo.io/') || container.image.startsWith('bar.io/'))" message: "Unknown image registry." diff --git a/content/en/policies/best-practices/check-deprecated-apis/check-deprecated-apis.md b/content/en/policies/best-practices/check-deprecated-apis/check-deprecated-apis.md index 8889bb3f9..7f6da6f75 100644 --- a/content/en/policies/best-practices/check-deprecated-apis/check-deprecated-apis.md +++ b/content/en/policies/best-practices/check-deprecated-apis/check-deprecated-apis.md @@ -35,7 +35,7 @@ metadata: so therefore the validate-v1-25-removals rule may not completely work on 1.25+. This policy requires Kyverno v1.7.4+ to function properly. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: validate-v1-25-removals diff --git a/content/en/policies/best-practices/disallow-cri-sock-mount/disallow-cri-sock-mount.md b/content/en/policies/best-practices/disallow-cri-sock-mount/disallow-cri-sock-mount.md index 56bc6fa1a..73a557662 100644 --- a/content/en/policies/best-practices/disallow-cri-sock-mount/disallow-cri-sock-mount.md +++ b/content/en/policies/best-practices/disallow-cri-sock-mount/disallow-cri-sock-mount.md @@ -30,7 +30,7 @@ metadata: to or replacement of this policy, preventing users from mounting the parent directories (/var/run and /var) may be necessary to completely prevent socket bind mounts. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: validate-docker-sock-mount diff --git a/content/en/policies/best-practices/disallow-default-namespace/disallow-default-namespace.md b/content/en/policies/best-practices/disallow-default-namespace/disallow-default-namespace.md index a3f8d9fe4..953339490 100644 --- a/content/en/policies/best-practices/disallow-default-namespace/disallow-default-namespace.md +++ b/content/en/policies/best-practices/disallow-default-namespace/disallow-default-namespace.md @@ -32,7 +32,7 @@ metadata: due to Pod controllers need to specify the `namespace` field under the top-level `metadata` object and not at the Pod template level. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: validate-namespace diff --git a/content/en/policies/best-practices/disallow-helm-tiller/disallow-helm-tiller.md b/content/en/policies/best-practices/disallow-helm-tiller/disallow-helm-tiller.md index 1930c35d0..009276faf 100644 --- a/content/en/policies/best-practices/disallow-helm-tiller/disallow-helm-tiller.md +++ b/content/en/policies/best-practices/disallow-helm-tiller/disallow-helm-tiller.md @@ -5,7 +5,7 @@ version: 1.6.0 subject: Pod policyType: "validate" description: > - Tiller, found in Helm v2, has known security challenges. It requires administrative privileges and acts as a shared resource accessible to any authenticated user. Tiller can lead to privilege escalation as restricted users can impact other users. It is recommend to use Helm v3+ which does not contain Tiller for these reasons. This policy validates that there is not an image containing the name `tiller`. + Tiller, found in Helm v2, has known security challenges. It requires administrative privileges and acts as a shared resource accessible to any authenticated user. Tiller can lead to privilege escalation as restricted users can impact other users. It is recommended to use Helm v3+ which does not contain Tiller for these reasons. This policy validates that there is not an image containing the name `tiller`. --- ## Policy Definition @@ -25,11 +25,11 @@ metadata: policies.kyverno.io/description: >- Tiller, found in Helm v2, has known security challenges. It requires administrative privileges and acts as a shared resource accessible to any authenticated user. Tiller can lead to privilege escalation as - restricted users can impact other users. It is recommend to use Helm v3+ which does not contain + restricted users can impact other users. It is recommended to use Helm v3+ which does not contain Tiller for these reasons. This policy validates that there is not an image containing the name `tiller`. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: validate-helm-tiller @@ -40,10 +40,15 @@ spec: - Pod validate: message: "Helm Tiller is not allowed" - pattern: - spec: - containers: - - name: "*" - image: "!*tiller*" + foreach: + - list: "request.object.spec.containers" + pattern: + image: "!*tiller*" + - list: "request.object.spec.initContainers" + pattern: + image: "!*tiller*" + - list: "request.object.spec.ephemeralContainers" + pattern: + image: "!*tiller*" ``` diff --git a/content/en/policies/best-practices/disallow-latest-tag/disallow-latest-tag.md b/content/en/policies/best-practices/disallow-latest-tag/disallow-latest-tag.md index 9e5c81c1f..90d5712ec 100644 --- a/content/en/policies/best-practices/disallow-latest-tag/disallow-latest-tag.md +++ b/content/en/policies/best-practices/disallow-latest-tag/disallow-latest-tag.md @@ -28,7 +28,7 @@ metadata: a specific version of an application Pod. This policy validates that the image specifies a tag and that it is not called `latest`. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: require-image-tag @@ -39,10 +39,16 @@ spec: - Pod validate: message: "An image tag is required." - pattern: - spec: - containers: - - image: "*:*" + foreach: + - list: "request.object.spec.containers" + pattern: + image: "*:*" + - list: "request.object.spec.initContainers" + pattern: + image: "*:*" + - list: "request.object.spec.ephemeralContainers" + pattern: + image: "*:*" - name: validate-image-tag match: any: @@ -51,8 +57,15 @@ spec: - Pod validate: message: "Using a mutable image tag e.g. 'latest' is not allowed." - pattern: - spec: - containers: - - image: "!*:latest" + foreach: + - list: "request.object.spec.containers" + pattern: + image: "!*:latest" + - list: "request.object.spec.initContainers" + pattern: + image: "!*:latest" + - list: "request.object.spec.ephemeralContainers" + pattern: + image: "!*:latest" + ``` diff --git a/content/en/policies/best-practices/require-drop-all/require-drop-all.md b/content/en/policies/best-practices/require-drop-all/require-drop-all.md index 0e837a330..acc06593e 100644 --- a/content/en/policies/best-practices/require-drop-all/require-drop-all.md +++ b/content/en/policies/best-practices/require-drop-all/require-drop-all.md @@ -29,7 +29,7 @@ metadata: ability. Note that this policy also illustrates how to cover drop entries in any case although this may not strictly conform to the Pod Security Standards. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: require-drop-all diff --git a/content/en/policies/best-practices/require-drop-cap-net-raw/require-drop-cap-net-raw.md b/content/en/policies/best-practices/require-drop-cap-net-raw/require-drop-cap-net-raw.md index 687be2c43..aace9d6eb 100644 --- a/content/en/policies/best-practices/require-drop-cap-net-raw/require-drop-cap-net-raw.md +++ b/content/en/policies/best-practices/require-drop-cap-net-raw/require-drop-cap-net-raw.md @@ -30,7 +30,7 @@ metadata: ability. Note that this policy also illustrates how to cover drop entries in any case although this may not strictly conform to the Pod Security Standards. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: require-drop-cap-net-raw @@ -55,4 +55,8 @@ spec: - key: CAP_NET_RAW operator: AnyNotIn value: "{{ element.securityContext.capabilities.drop[].to_upper(@) || `[]` }}" + - key: NET_RAW + operator: AnyNotIn + value: "{{ element.securityContext.capabilities.drop[].to_upper(@) || `[]` }}" + ``` diff --git a/content/en/policies/best-practices/require-labels/require-labels.md b/content/en/policies/best-practices/require-labels/require-labels.md index 147a85c9d..28aca43f5 100644 --- a/content/en/policies/best-practices/require-labels/require-labels.md +++ b/content/en/policies/best-practices/require-labels/require-labels.md @@ -28,7 +28,7 @@ metadata: all tools can understand. The recommended labels describe applications in a way that can be queried. This policy validates that the label `app.kubernetes.io/name` is specified with some value. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: check-for-labels diff --git a/content/en/policies/best-practices/require-pod-requests-limits/require-pod-requests-limits.md b/content/en/policies/best-practices/require-pod-requests-limits/require-pod-requests-limits.md index 09b2e1fdc..f26b04a41 100644 --- a/content/en/policies/best-practices/require-pod-requests-limits/require-pod-requests-limits.md +++ b/content/en/policies/best-practices/require-pod-requests-limits/require-pod-requests-limits.md @@ -30,7 +30,7 @@ metadata: This policy validates that all containers have something specified for memory and CPU requests and memory limits. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: validate-resources @@ -40,7 +40,7 @@ spec: kinds: - Pod validate: - message: "CPU and memory resource requests and limits are required." + message: "CPU and memory resource requests and memory limits are required for containers." pattern: spec: containers: @@ -50,14 +50,14 @@ spec: cpu: "?*" limits: memory: "?*" - initContainers: + =(initContainers): - resources: requests: memory: "?*" cpu: "?*" limits: memory: "?*" - ephemeralContainers: + =(ephemeralContainers): - resources: requests: memory: "?*" diff --git a/content/en/policies/best-practices/require-probes/require-probes.md b/content/en/policies/best-practices/require-probes/require-probes.md index 38ca11c50..917953715 100644 --- a/content/en/policies/best-practices/require-probes/require-probes.md +++ b/content/en/policies/best-practices/require-probes/require-probes.md @@ -31,7 +31,7 @@ metadata: This policy validates that all containers have one of livenessProbe, readinessProbe, or startupProbe defined. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: validate-probes diff --git a/content/en/policies/best-practices/require-ro-rootfs/require-ro-rootfs.md b/content/en/policies/best-practices/require-ro-rootfs/require-ro-rootfs.md index 45b345a6d..ad7e97ac8 100644 --- a/content/en/policies/best-practices/require-ro-rootfs/require-ro-rootfs.md +++ b/content/en/policies/best-practices/require-ro-rootfs/require-ro-rootfs.md @@ -29,7 +29,7 @@ metadata: host system. This policy validates that containers define a securityContext with `readOnlyRootFilesystem: true`. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: validate-readOnlyRootFilesystem diff --git a/content/en/policies/best-practices/restrict-image-registries/restrict-image-registries.md b/content/en/policies/best-practices/restrict-image-registries/restrict-image-registries.md index 54fd6bdd2..173617341 100644 --- a/content/en/policies/best-practices/restrict-image-registries/restrict-image-registries.md +++ b/content/en/policies/best-practices/restrict-image-registries/restrict-image-registries.md @@ -30,7 +30,7 @@ metadata: policy validates that container images only originate from the registry `eu.foo.io` or `bar.io`. Use of this policy requires customization to define your allowable registries. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: validate-registries diff --git a/content/en/policies/best-practices/restrict-node-port/restrict-node-port.md b/content/en/policies/best-practices/restrict-node-port/restrict-node-port.md index bed9060f4..07d7f01c0 100644 --- a/content/en/policies/best-practices/restrict-node-port/restrict-node-port.md +++ b/content/en/policies/best-practices/restrict-node-port/restrict-node-port.md @@ -29,7 +29,7 @@ metadata: with additional upstream security checks. This policy validates that any new Services do not use the `NodePort` type. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: validate-nodeport diff --git a/content/en/policies/best-practices/restrict-service-external-ips/restrict-service-external-ips.md b/content/en/policies/best-practices/restrict-service-external-ips/restrict-service-external-ips.md index 92b830b1a..61adc68fc 100644 --- a/content/en/policies/best-practices/restrict-service-external-ips/restrict-service-external-ips.md +++ b/content/en/policies/best-practices/restrict-service-external-ips/restrict-service-external-ips.md @@ -28,7 +28,7 @@ metadata: See: https://github.com/kyverno/kyverno/issues/1367. This policy validates that the `externalIPs` field is not set on a Service. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: check-ips diff --git a/content/en/policies/cert-manager/limit-dnsnames/limit-dnsnames.md b/content/en/policies/cert-manager/limit-dnsnames/limit-dnsnames.md index a5d21d908..f648f9c37 100644 --- a/content/en/policies/cert-manager/limit-dnsnames/limit-dnsnames.md +++ b/content/en/policies/cert-manager/limit-dnsnames/limit-dnsnames.md @@ -27,7 +27,7 @@ metadata: This policy ensures that each certificate request contains only one DNS name entry. spec: - validationFailureAction: audit + validationFailureAction: Audit background: false rules: - name: limit-dnsnames diff --git a/content/en/policies/cert-manager/limit-duration/limit-duration.md b/content/en/policies/cert-manager/limit-duration/limit-duration.md index 38e24638c..ce90ac8f7 100644 --- a/content/en/policies/cert-manager/limit-duration/limit-duration.md +++ b/content/en/policies/cert-manager/limit-duration/limit-duration.md @@ -25,7 +25,7 @@ metadata: policies.kyverno.io/description: >- Kubernetes managed non-letsencrypt certificates have to be renewed in every 100 days. spec: - validationFailureAction: audit + validationFailureAction: Audit background: false rules: - name: certificate-duration-max-100days diff --git a/content/en/policies/cert-manager/restrict-issuer/restrict-issuer.md b/content/en/policies/cert-manager/restrict-issuer/restrict-issuer.md index e5d2d267e..b7d04ab03 100644 --- a/content/en/policies/cert-manager/restrict-issuer/restrict-issuer.md +++ b/content/en/policies/cert-manager/restrict-issuer/restrict-issuer.md @@ -27,7 +27,7 @@ metadata: able to create their own issuers and sign certificates for other domains. This policy ensures that a certificate request for a specific domain uses a designated ClusterIssuer. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: restrict-corp-cert-issuer diff --git a/content/en/policies/consul-cel/enforce-min-tls-version/enforce-min-tls-version.md b/content/en/policies/consul-cel/enforce-min-tls-version/enforce-min-tls-version.md index 814ab21e8..eb2af272d 100644 --- a/content/en/policies/consul-cel/enforce-min-tls-version/enforce-min-tls-version.md +++ b/content/en/policies/consul-cel/enforce-min-tls-version/enforce-min-tls-version.md @@ -43,8 +43,7 @@ spec: cel: expressions: - expression: >- - has(object.spec) && has(object.spec.tls) && has(object.spec.tls.incoming) && - has(object.spec.tls.incoming.tlsMinVersion) && object.spec.tls.incoming.tlsMinVersion == 'TLSv1_2' + object.?spec.?tls.?incoming.?tlsMinVersion.orValue('') == 'TLSv1_2' message: The minimum version of TLS is TLS v1_2 diff --git a/content/en/policies/consul/enforce-min-tls-version/enforce-min-tls-version.md b/content/en/policies/consul/enforce-min-tls-version/enforce-min-tls-version.md index bafa65dc9..bc6edfc9e 100644 --- a/content/en/policies/consul/enforce-min-tls-version/enforce-min-tls-version.md +++ b/content/en/policies/consul/enforce-min-tls-version/enforce-min-tls-version.md @@ -27,7 +27,7 @@ metadata: policies.kyverno.io/description: >- This policy will check the TLS Min version to ensure that whenever the mesh is set, there is a minimum version of TLS set for all the service mesh proxies and this enforces that service mesh mTLS traffic uses TLS v1.2 or newer. spec: - validationFailureAction: enforce + validationFailureAction: Enforce background: true rules: - name: check-for-tls-version diff --git a/content/en/policies/flux-cel/verify-flux-sources/verify-flux-sources.md b/content/en/policies/flux-cel/verify-flux-sources/verify-flux-sources.md index 76bed366d..13663d64a 100644 --- a/content/en/policies/flux-cel/verify-flux-sources/verify-flux-sources.md +++ b/content/en/policies/flux-cel/verify-flux-sources/verify-flux-sources.md @@ -70,7 +70,7 @@ spec: validate: cel: expressions: - - expression: "has(object.spec.endpoint) && object.spec.endpoint.endsWith('.myorg.com')" + - expression: "object.spec.?endpoint.orValue('').endsWith('.myorg.com')" message: ".spec.endpoint must reference an address within the myorg organization." - name: flux-helm-repositories match: @@ -108,7 +108,7 @@ spec: validate: cel: expressions: - - expression: "has(object.spec.image) && object.spec.image.startsWith('ghcr.io/myorg/')" + - expression: "object.spec.?image.orValue('').startsWith('ghcr.io/myorg/')" message: ".spec.image must be from an image repository within the myorg organization." diff --git a/content/en/policies/flux/verify-flux-sources/verify-flux-sources.md b/content/en/policies/flux/verify-flux-sources/verify-flux-sources.md index 1b6f727c7..fabfc03d7 100644 --- a/content/en/policies/flux/verify-flux-sources/verify-flux-sources.md +++ b/content/en/policies/flux/verify-flux-sources/verify-flux-sources.md @@ -32,7 +32,7 @@ metadata: accessing outside sources. This policy verifies that each of the Flux sources comes from a trusted location. spec: - validationFailureAction: audit + validationFailureAction: Audit rules: - name: flux-github-repositories match: diff --git a/content/en/policies/istio-cel/enforce-sidecar-injection-namespace/enforce-sidecar-injection-namespace.md b/content/en/policies/istio-cel/enforce-sidecar-injection-namespace/enforce-sidecar-injection-namespace.md index f35e5062d..49c98e685 100644 --- a/content/en/policies/istio-cel/enforce-sidecar-injection-namespace/enforce-sidecar-injection-namespace.md +++ b/content/en/policies/istio-cel/enforce-sidecar-injection-namespace/enforce-sidecar-injection-namespace.md @@ -43,7 +43,7 @@ spec: validate: cel: expressions: - - expression: "has(object.metadata.labels) && 'istio-injection' in object.metadata.labels && object.metadata.labels['istio-injection'] == 'enabled'" + - expression: "object.metadata.?labels[?'istio-injection'].orValue('') == 'enabled'" message: "All new Namespaces must have Istio sidecar injection enabled." diff --git a/content/en/policies/istio-cel/prevent-disabling-injection-pods/prevent-disabling-injection-pods.md b/content/en/policies/istio-cel/prevent-disabling-injection-pods/prevent-disabling-injection-pods.md index 8fff8aaa6..4cc756b8f 100644 --- a/content/en/policies/istio-cel/prevent-disabling-injection-pods/prevent-disabling-injection-pods.md +++ b/content/en/policies/istio-cel/prevent-disabling-injection-pods/prevent-disabling-injection-pods.md @@ -46,8 +46,7 @@ spec: cel: expressions: - expression: >- - !has(object.metadata.annotations) || !('sidecar.istio.io/inject' in object.metadata.annotations) || - object.metadata.annotations['sidecar.istio.io/inject'] != 'false' + object.metadata.?annotations[?'sidecar.istio.io/inject'].orValue('') != 'false' message: "Pods may not disable sidecar injection by setting the annotation sidecar.istio.io/inject to a value of false." diff --git a/content/en/policies/istio/add-ambient-mode-namespace/add-ambient-mode-namespace.md b/content/en/policies/istio/add-ambient-mode-namespace/add-ambient-mode-namespace.md new file mode 100644 index 000000000..ab4161953 --- /dev/null +++ b/content/en/policies/istio/add-ambient-mode-namespace/add-ambient-mode-namespace.md @@ -0,0 +1,46 @@ +--- +title: "Add Istio Ambient Mode" +category: Istio +version: 1.6.0 +subject: Namespace +policyType: "mutate" +description: > + In order for Istio to include namespaces in ambient mode, the label `istio.io/dataplane-mode` must be set to `ambient`. As an alternative to rejecting Namespace definitions which don't already contain this label, it can be added automatically. This policy adds the label `istio.io/dataplane-mode` set to `ambient` for all new Namespaces. +--- + +## Policy Definition +/istio/add-ambient-mode-namespace/add-ambient-mode-namespace.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: add-ambient-mode-namespace + annotations: + policies.kyverno.io/title: Add Istio Ambient Mode + policies.kyverno.io/category: Istio + policies.kyverno.io/severity: medium + kyverno.io/kyverno-version: 1.8.0 + policies.kyverno.io/minversion: 1.6.0 + kyverno.io/kubernetes-version: "1.24" + policies.kyverno.io/subject: Namespace + policies.kyverno.io/description: >- + In order for Istio to include namespaces in ambient mode, the label `istio.io/dataplane-mode` + must be set to `ambient`. As an alternative to rejecting Namespace definitions which don't already + contain this label, it can be added automatically. This policy adds the label `istio.io/dataplane-mode` + set to `ambient` for all new Namespaces. +spec: + rules: + - name: add-ambient-mode-enabled + match: + any: + - resources: + kinds: + - Namespace + mutate: + patchStrategicMerge: + metadata: + labels: + istio.io/dataplane-mode: ambient + +``` diff --git a/content/en/policies/istio/enforce-ambient-mode-namespace/enforce-ambient-mode-namespace.md b/content/en/policies/istio/enforce-ambient-mode-namespace/enforce-ambient-mode-namespace.md new file mode 100644 index 000000000..7fee55229 --- /dev/null +++ b/content/en/policies/istio/enforce-ambient-mode-namespace/enforce-ambient-mode-namespace.md @@ -0,0 +1,48 @@ +--- +title: "Enforce Istio Ambient Mode" +category: Istio +version: 1.6.0 +subject: Namespace +policyType: "validate" +description: > + In order for Istio to include namespaces in ambient mode, the label `istio.io/dataplane-mode` must be set to `ambient`. This policy ensures that all new Namespaces set `istio.io/dataplane-mode` to `ambient`. +--- + +## Policy Definition +/istio/enforce-ambient-mode-namespace/enforce-ambient-mode-namespace.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: enforce-ambient-mode-namespace + annotations: + policies.kyverno.io/title: Enforce Istio Ambient Mode + policies.kyverno.io/category: Istio + policies.kyverno.io/severity: medium + kyverno.io/kyverno-version: 1.8.0 + policies.kyverno.io/minversion: 1.6.0 + kyverno.io/kubernetes-version: "1.24" + policies.kyverno.io/subject: Namespace + policies.kyverno.io/description: >- + In order for Istio to include namespaces in ambient mode, the label + `istio.io/dataplane-mode` must be set to `ambient`. This policy ensures that all new Namespaces + set `istio.io/dataplane-mode` to `ambient`. +spec: + validationFailureAction: Audit + background: true + rules: + - name: check-amblient-mode-enabled + match: + any: + - resources: + kinds: + - Namespace + validate: + message: "All new Namespaces must have Istio ambient mode enabled." + pattern: + metadata: + labels: + istio.io/dataplane-mode: ambient + +``` diff --git a/content/en/policies/istio/enforce-sidecar-injection-namespace/enforce-sidecar-injection-namespace.md b/content/en/policies/istio/enforce-sidecar-injection-namespace/enforce-sidecar-injection-namespace.md index e9670964c..2c7d5ec9f 100644 --- a/content/en/policies/istio/enforce-sidecar-injection-namespace/enforce-sidecar-injection-namespace.md +++ b/content/en/policies/istio/enforce-sidecar-injection-namespace/enforce-sidecar-injection-namespace.md @@ -29,7 +29,7 @@ metadata: `istio-injection` must be set to `enabled`. This policy ensures that all new Namespaces set `istio-inject` to `enabled`. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: check-istio-injection-enabled diff --git a/content/en/policies/istio/enforce-strict-mtls/enforce-strict-mtls.md b/content/en/policies/istio/enforce-strict-mtls/enforce-strict-mtls.md index 5776949e9..ee93a3225 100644 --- a/content/en/policies/istio/enforce-strict-mtls/enforce-strict-mtls.md +++ b/content/en/policies/istio/enforce-strict-mtls/enforce-strict-mtls.md @@ -32,7 +32,7 @@ metadata: This policy prevents disabling strict mTLS in a PeerAuthentication resource by requiring the `mode` be set to either `UNSET` or `STRICT`. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: validate-mtls diff --git a/content/en/policies/istio/enforce-tls-hosts-host-subnets/enforce-tls-hosts-host-subnets.md b/content/en/policies/istio/enforce-tls-hosts-host-subnets/enforce-tls-hosts-host-subnets.md index 208b998fa..183f6ffe9 100644 --- a/content/en/policies/istio/enforce-tls-hosts-host-subnets/enforce-tls-hosts-host-subnets.md +++ b/content/en/policies/istio/enforce-tls-hosts-host-subnets/enforce-tls-hosts-host-subnets.md @@ -30,7 +30,7 @@ metadata: to the destination host. This policy enforces that the TLS mode cannot be set to a value of `DISABLE`. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: destrule diff --git a/content/en/policies/istio/prevent-disabling-injection-pods/prevent-disabling-injection-pods.md b/content/en/policies/istio/prevent-disabling-injection-pods/prevent-disabling-injection-pods.md index cc12bb55b..6adb3c8c2 100644 --- a/content/en/policies/istio/prevent-disabling-injection-pods/prevent-disabling-injection-pods.md +++ b/content/en/policies/istio/prevent-disabling-injection-pods/prevent-disabling-injection-pods.md @@ -30,7 +30,7 @@ metadata: thereby reducing visibility. This policy ensures that Pods cannot set the annotation `sidecar.istio.io/inject` to a value of `false`. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: prohibit-inject-annotation diff --git a/content/en/policies/istio/require-authorizationpolicy/require-authorizationpolicy.md b/content/en/policies/istio/require-authorizationpolicy/require-authorizationpolicy.md index 373fe0aa1..d0dd2a98c 100644 --- a/content/en/policies/istio/require-authorizationpolicy/require-authorizationpolicy.md +++ b/content/en/policies/istio/require-authorizationpolicy/require-authorizationpolicy.md @@ -30,7 +30,7 @@ metadata: at least one AuthorizationPolicy. This policy, designed to run in background mode for reporting purposes, ensures every Namespace has at least one AuthorizationPolicy. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: check-authz-pol diff --git a/content/en/policies/istio/restrict-virtual-service-wildcard/restrict-virtual-service-wildcard.md b/content/en/policies/istio/restrict-virtual-service-wildcard/restrict-virtual-service-wildcard.md index f55375b16..e522eda0e 100644 --- a/content/en/policies/istio/restrict-virtual-service-wildcard/restrict-virtual-service-wildcard.md +++ b/content/en/policies/istio/restrict-virtual-service-wildcard/restrict-virtual-service-wildcard.md @@ -32,7 +32,7 @@ metadata: character and allows for more governance when a single mesh deployment model is used. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: block-virtual-service-wildcard diff --git a/content/en/policies/kasten-cel/k10-data-protection-by-label/k10-data-protection-by-label.md b/content/en/policies/kasten-cel/k10-data-protection-by-label/k10-data-protection-by-label.md index b7afbb5c2..418ebba61 100644 --- a/content/en/policies/kasten-cel/k10-data-protection-by-label/k10-data-protection-by-label.md +++ b/content/en/policies/kasten-cel/k10-data-protection-by-label/k10-data-protection-by-label.md @@ -45,7 +45,7 @@ spec: validate: cel: expressions: - - expression: "has(object.metadata.labels) && has(object.metadata.labels.dataprotection) && object.metadata.labels.dataprotection.startsWith('k10-')" + - expression: "object.metadata.?labels.?dataprotection.orValue('').startsWith('k10-')" message: "Deployments and StatefulSets that specify 'dataprotection' label must have a valid k10-?* name (use labels: dataprotection: k10-)" diff --git a/content/en/policies/kasten-cel/k10-validate-ns-by-preset-label/k10-validate-ns-by-preset-label.md b/content/en/policies/kasten-cel/k10-validate-ns-by-preset-label/k10-validate-ns-by-preset-label.md index c117090d4..940c7c07f 100644 --- a/content/en/policies/kasten-cel/k10-validate-ns-by-preset-label/k10-validate-ns-by-preset-label.md +++ b/content/en/policies/kasten-cel/k10-validate-ns-by-preset-label/k10-validate-ns-by-preset-label.md @@ -46,7 +46,7 @@ spec: validate: cel: expressions: - - expression: "has(object.metadata.labels) && has(object.metadata.labels.dataprotection) && object.metadata.labels.dataprotection in ['gold', 'silver', 'bronze', 'none']" + - expression: "object.metadata.?labels.?dataprotection.orValue('') in ['gold', 'silver', 'bronze', 'none']" message: >- Namespaces must specify a "dataprotection" label with a value corresponding to a Kasten K10 SLA: diff --git a/content/en/policies/kubecost-cel/require-kubecost-labels/require-kubecost-labels.md b/content/en/policies/kubecost-cel/require-kubecost-labels/require-kubecost-labels.md index dacdba17f..a6ba1d209 100644 --- a/content/en/policies/kubecost-cel/require-kubecost-labels/require-kubecost-labels.md +++ b/content/en/policies/kubecost-cel/require-kubecost-labels/require-kubecost-labels.md @@ -47,12 +47,11 @@ spec: cel: expressions: - expression: >- - has(object.metadata.labels) && - has(object.metadata.labels.owner) && object.metadata.labels.owner != '' && - has(object.metadata.labels.team) && object.metadata.labels.team != '' && - has(object.metadata.labels.department) && object.metadata.labels.department != '' && - has(object.metadata.labels.app) && object.metadata.labels.app != '' && - has(object.metadata.labels.env) && object.metadata.labels.env != '' + object.metadata.?labels.?owner.orValue('') != '' && + object.metadata.?labels.?team.orValue('') != '' && + object.metadata.?labels.?department.orValue('') != '' && + object.metadata.?labels.?app.orValue('') != '' && + object.metadata.?labels.?env.orValue('') != '' message: "The Kubecost labels `owner`, `team`, `department`, `app`, and `env` are all required for Pods." diff --git a/content/en/policies/kubeops/config-syncer-secret-generation-from-rancher-capi/config-syncer-secret-generation-from-rancher-capi.md b/content/en/policies/kubeops/config-syncer-secret-generation-from-rancher-capi/config-syncer-secret-generation-from-rancher-capi.md index 0b416ad3b..15e3d342a 100644 --- a/content/en/policies/kubeops/config-syncer-secret-generation-from-rancher-capi/config-syncer-secret-generation-from-rancher-capi.md +++ b/content/en/policies/kubeops/config-syncer-secret-generation-from-rancher-capi/config-syncer-secret-generation-from-rancher-capi.md @@ -30,6 +30,7 @@ metadata: required by the Kubeops Config Syncer for it to sync ConfigMaps/Secrets from the Rancher management cluster to downstream clusters. spec: + generateExisting: true rules: - name: source-rancher-non-local-cluster-and-capi-secret match: @@ -100,7 +101,6 @@ spec: operator: NotEquals value: '{{ currentKubeconfigData }}' generate: - generateExisting: true synchronize: true apiVersion: v1 kind: Secret diff --git a/content/en/policies/kubevirt/enforce-instancetype/enforce-instancetype.md b/content/en/policies/kubevirt/enforce-instancetype/enforce-instancetype.md index 0394f25e7..40071572f 100644 --- a/content/en/policies/kubevirt/enforce-instancetype/enforce-instancetype.md +++ b/content/en/policies/kubevirt/enforce-instancetype/enforce-instancetype.md @@ -25,7 +25,7 @@ metadata: kyverno.io/kyverno-version: "1.8.0-rc2" kyverno.io/kubernetes-version: "1.24-1.25" spec: - validationFailureAction: enforce + validationFailureAction: Enforce rules: - name: k6t-ensure-instance-type-and-preference match: diff --git a/content/en/policies/linkerd-cel/prevent-linkerd-pod-injection-override/prevent-linkerd-pod-injection-override.md b/content/en/policies/linkerd-cel/prevent-linkerd-pod-injection-override/prevent-linkerd-pod-injection-override.md new file mode 100644 index 000000000..c8695b4d0 --- /dev/null +++ b/content/en/policies/linkerd-cel/prevent-linkerd-pod-injection-override/prevent-linkerd-pod-injection-override.md @@ -0,0 +1,51 @@ +--- +title: "Prevent Linkerd Pod Injection Override in CEL expressions" +category: Linkerd in CEL +version: +subject: Pod +policyType: "validate" +description: > + Setting the annotation on a Pod (or its controller) `linkerd.io/inject` to `disabled` may effectively disable mesh participation for that workload reducing security and visibility. This policy prevents setting the annotation `linkerd.io/inject` to `disabled` for Pods. +--- + +## Policy Definition +/linkerd-cel/prevent-linkerd-pod-injection-override/prevent-linkerd-pod-injection-override.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: prevent-linkerd-pod-injection-override + annotations: + policies.kyverno.io/title: Prevent Linkerd Pod Injection Override in CEL expressions + policies.kyverno.io/category: Linkerd in CEL + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + kyverno.io/kyverno-version: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/description: >- + Setting the annotation on a Pod (or its controller) `linkerd.io/inject` to + `disabled` may effectively disable mesh participation for that workload reducing + security and visibility. This policy prevents setting the annotation `linkerd.io/inject` + to `disabled` for Pods. +spec: + validationFailureAction: Audit + background: true + rules: + - name: pod-injection-override + match: + any: + - resources: + kinds: + - Pod + operations: + - CREATE + - UPDATE + validate: + cel: + expressions: + - expression: "object.metadata.?annotations[?'linkerd.io/inject'].orValue('') != 'disabled'" + message: "Pods may not disable sidecar injection." + + +``` diff --git a/content/en/policies/linkerd-cel/prevent-linkerd-port-skipping/prevent-linkerd-port-skipping.md b/content/en/policies/linkerd-cel/prevent-linkerd-port-skipping/prevent-linkerd-port-skipping.md new file mode 100644 index 000000000..1b95ac241 --- /dev/null +++ b/content/en/policies/linkerd-cel/prevent-linkerd-port-skipping/prevent-linkerd-port-skipping.md @@ -0,0 +1,53 @@ +--- +title: "Prevent Linkerd Port Skipping in CEL expressions" +category: Linkerd in CEL +version: 1.11.0 +subject: Pod +policyType: "validate" +description: > + Linkerd has the ability to skip inbound and outbound ports assigned to Pods, exempting them from mTLS. This can be important in some narrow use cases but generally should be avoided. This policy prevents Pods from setting the annotations `config.linkerd.io/skip-inbound-ports` or `config.linkerd.io/skip-outbound-ports`. +--- + +## Policy Definition +/linkerd-cel/prevent-linkerd-port-skipping/prevent-linkerd-port-skipping.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: prevent-linkerd-port-skipping + annotations: + policies.kyverno.io/title: Prevent Linkerd Port Skipping in CEL expressions + policies.kyverno.io/category: Linkerd in CEL + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/description: >- + Linkerd has the ability to skip inbound and outbound ports assigned to Pods, exempting + them from mTLS. This can be important in some narrow use cases but + generally should be avoided. This policy prevents Pods from setting + the annotations `config.linkerd.io/skip-inbound-ports` or `config.linkerd.io/skip-outbound-ports`. +spec: + validationFailureAction: Audit + background: true + rules: + - name: pod-prevent-port-skipping + match: + any: + - resources: + kinds: + - Pod + operations: + - CREATE + - UPDATE + validate: + cel: + expressions: + - expression: >- + !has(object.metadata.annotations) || + (!('config.linkerd.io/skip-inbound-ports' in object.metadata.annotations) && !('config.linkerd.io/skip-outbound-ports' in object.metadata.annotations)) + message: "Pods may not skip ports. The annotations `config.linkerd.io/skip-inbound-ports` or `config.linkerd.io/skip-outbound-ports` must not be set." + + +``` diff --git a/content/en/policies/linkerd-cel/require-linkerd-mesh-injection/require-linkerd-mesh-injection.md b/content/en/policies/linkerd-cel/require-linkerd-mesh-injection/require-linkerd-mesh-injection.md new file mode 100644 index 000000000..59c84d5a2 --- /dev/null +++ b/content/en/policies/linkerd-cel/require-linkerd-mesh-injection/require-linkerd-mesh-injection.md @@ -0,0 +1,50 @@ +--- +title: "Require Linkerd Mesh Injection in CEL expressions" +category: Linkerd in CEL +version: 1.11.0 +subject: Namespace, Annotation +policyType: "validate" +description: > + Sidecar proxy injection in Linkerd may be handled at the Namespace level by setting the annotation `linkerd.io/inject` to `enabled`. This policy enforces that all Namespaces contain the annotation `linkerd.io/inject` set to `enabled`. +--- + +## Policy Definition +/linkerd-cel/require-linkerd-mesh-injection/require-linkerd-mesh-injection.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: require-linkerd-mesh-injection + annotations: + policies.kyverno.io/title: Require Linkerd Mesh Injection in CEL expressions + policies.kyverno.io/category: Linkerd in CEL + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Namespace, Annotation + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/description: >- + Sidecar proxy injection in Linkerd may be handled at the Namespace level by + setting the annotation `linkerd.io/inject` to `enabled`. This policy enforces that + all Namespaces contain the annotation `linkerd.io/inject` set to `enabled`. +spec: + validationFailureAction: Audit + background: true + rules: + - name: require-mesh-annotation + match: + any: + - resources: + kinds: + - Namespace + operations: + - CREATE + - UPDATE + validate: + cel: + expressions: + - expression: "object.metadata.?annotations[?'linkerd.io/inject'].orValue('') == 'enabled'" + message: "All Namespaces must set the annotation `linkerd.io/inject` to `enabled`." + + +``` diff --git a/content/en/policies/linkerd/check-linkerd-authorizationpolicy/check-linkerd-authorizationpolicy.md b/content/en/policies/linkerd/check-linkerd-authorizationpolicy/check-linkerd-authorizationpolicy.md index 043553c49..4bc2847d2 100644 --- a/content/en/policies/linkerd/check-linkerd-authorizationpolicy/check-linkerd-authorizationpolicy.md +++ b/content/en/policies/linkerd/check-linkerd-authorizationpolicy/check-linkerd-authorizationpolicy.md @@ -31,7 +31,7 @@ metadata: AuthorizationPolicy resources to ensure that either a matching Server or HTTPRoute exists first. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: check-server-exists diff --git a/content/en/policies/linkerd/prevent-linkerd-pod-injection-override/prevent-linkerd-pod-injection-override.md b/content/en/policies/linkerd/prevent-linkerd-pod-injection-override/prevent-linkerd-pod-injection-override.md index 208f006b2..4bb4574b2 100644 --- a/content/en/policies/linkerd/prevent-linkerd-pod-injection-override/prevent-linkerd-pod-injection-override.md +++ b/content/en/policies/linkerd/prevent-linkerd-pod-injection-override/prevent-linkerd-pod-injection-override.md @@ -27,7 +27,7 @@ metadata: security and visibility. This policy prevents setting the annotation `linkerd.io/inject` to `disabled` for Pods. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: pod-injection-override diff --git a/content/en/policies/linkerd/prevent-linkerd-port-skipping/prevent-linkerd-port-skipping.md b/content/en/policies/linkerd/prevent-linkerd-port-skipping/prevent-linkerd-port-skipping.md index 07ae083f5..03736d07f 100644 --- a/content/en/policies/linkerd/prevent-linkerd-port-skipping/prevent-linkerd-port-skipping.md +++ b/content/en/policies/linkerd/prevent-linkerd-port-skipping/prevent-linkerd-port-skipping.md @@ -27,7 +27,7 @@ metadata: generally should be avoided. This policy prevents Pods from setting the annotations `config.linkerd.io/skip-inbound-ports` or `config.linkerd.io/skip-outbound-ports`. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: pod-prevent-port-skipping diff --git a/content/en/policies/linkerd/require-linkerd-mesh-injection/require-linkerd-mesh-injection.md b/content/en/policies/linkerd/require-linkerd-mesh-injection/require-linkerd-mesh-injection.md index ecf416a53..5384f1596 100644 --- a/content/en/policies/linkerd/require-linkerd-mesh-injection/require-linkerd-mesh-injection.md +++ b/content/en/policies/linkerd/require-linkerd-mesh-injection/require-linkerd-mesh-injection.md @@ -26,7 +26,7 @@ metadata: setting the annotation `linkerd.io/inject` to `enabled`. This policy enforces that all Namespaces contain the annotation `linkerd.io/inject` set to `enabled`. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: require-mesh-annotation diff --git a/content/en/policies/linkerd/require-linkerd-server/require-linkerd-server.md b/content/en/policies/linkerd/require-linkerd-server/require-linkerd-server.md index d48a47559..53a5328d3 100644 --- a/content/en/policies/linkerd/require-linkerd-server/require-linkerd-server.md +++ b/content/en/policies/linkerd/require-linkerd-server/require-linkerd-server.md @@ -31,7 +31,7 @@ metadata: Deployments (exposing ports) and Services to ensure a corresponding Server resource exists first. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: check-deployment-has-server diff --git a/content/en/policies/nginx-ingress-cel/disallow-ingress-nginx-custom-snippets/disallow-ingress-nginx-custom-snippets.md b/content/en/policies/nginx-ingress-cel/disallow-ingress-nginx-custom-snippets/disallow-ingress-nginx-custom-snippets.md new file mode 100644 index 000000000..7a1eea5e3 --- /dev/null +++ b/content/en/policies/nginx-ingress-cel/disallow-ingress-nginx-custom-snippets/disallow-ingress-nginx-custom-snippets.md @@ -0,0 +1,65 @@ +--- +title: "Disallow Custom Snippets in CEL expressions" +category: Security, NGINX Ingress in CEL +version: 1.11.0 +subject: ConfigMap, Ingress +policyType: "validate" +description: > + Users that can create or update ingress objects can use the custom snippets feature to obtain all secrets in the cluster (CVE-2021-25742). This policy disables allow-snippet-annotations in the ingress-nginx configuration and blocks *-snippet annotations on an Ingress. See: https://github.com/kubernetes/ingress-nginx/issues/7837 +--- + +## Policy Definition +/nginx-ingress-cel/disallow-ingress-nginx-custom-snippets/disallow-ingress-nginx-custom-snippets.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-ingress-nginx-custom-snippets + annotations: + policies.kyverno.io/title: Disallow Custom Snippets in CEL expressions + policies.kyverno.io/category: Security, NGINX Ingress in CEL + policies.kyverno.io/subject: ConfigMap, Ingress + policies.kyverno.io/minversion: "1.11.0" + kyverno.io/kyverno-version: "1.11.0" + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/description: >- + Users that can create or update ingress objects can use the custom snippets + feature to obtain all secrets in the cluster (CVE-2021-25742). This policy + disables allow-snippet-annotations in the ingress-nginx configuration and + blocks *-snippet annotations on an Ingress. + See: https://github.com/kubernetes/ingress-nginx/issues/7837 +spec: + validationFailureAction: Enforce + rules: + - name: check-config-map + match: + any: + - resources: + kinds: + - ConfigMap + operations: + - CREATE + - UPDATE + validate: + cel: + expressions: + - expression: "object.?data[?'allow-snippet-annotations'].orValue('false') == 'false'" + message: "ingress-nginx allow-snippet-annotations must be set to false" + - name: check-ingress-annotations + match: + any: + - resources: + kinds: + - networking.k8s.io/v1/Ingress + operations: + - CREATE + - UPDATE + validate: + cel: + expressions: + - expression: "!object.metadata.?annotations.orValue([]).exists(annotation, annotation.endsWith('-snippet'))" + message: "ingress-nginx custom snippets are not allowed" + + +``` diff --git a/content/en/policies/nginx-ingress-cel/restrict-annotations/restrict-annotations.md b/content/en/policies/nginx-ingress-cel/restrict-annotations/restrict-annotations.md new file mode 100644 index 000000000..b041bd3b6 --- /dev/null +++ b/content/en/policies/nginx-ingress-cel/restrict-annotations/restrict-annotations.md @@ -0,0 +1,60 @@ +--- +title: "Restrict NGINX Ingress annotation values in CEL expressions" +category: Security, NGINX Ingress in CEL +version: 1.11.0 +subject: Ingress +policyType: "validate" +description: > + This policy mitigates CVE-2021-25746 by restricting `metadata.annotations` to safe values. See: https://github.com/kubernetes/ingress-nginx/blame/main/internal/ingress/inspector/rules.go. This issue has been fixed in NGINX Ingress v1.2.0. For NGINX Ingress version 1.0.5+ the "annotation-value-word-blocklist" configuration setting is also recommended. Please refer to the CVE for details. +--- + +## Policy Definition +/nginx-ingress-cel/restrict-annotations/restrict-annotations.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-annotations + annotations: + policies.kyverno.io/title: Restrict NGINX Ingress annotation values in CEL expressions + policies.kyverno.io/category: Security, NGINX Ingress in CEL + policies.kyverno.io/severity: high + policies.kyverno.io/subject: Ingress + policies.kyverno.io/minversion: "1.11.0" + kyverno.io/kyverno-version: "1.11.0" + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/description: >- + This policy mitigates CVE-2021-25746 by restricting `metadata.annotations` to safe values. + See: https://github.com/kubernetes/ingress-nginx/blame/main/internal/ingress/inspector/rules.go. + This issue has been fixed in NGINX Ingress v1.2.0. For NGINX Ingress version 1.0.5+ the + "annotation-value-word-blocklist" configuration setting is also recommended. + Please refer to the CVE for details. +spec: + validationFailureAction: Enforce + rules: + - name: check-ingress + match: + any: + - resources: + kinds: + - networking.k8s.io/v1/Ingress + operations: + - CREATE + - UPDATE + validate: + cel: + expressions: + - expression: >- + !has(object.metadata.annotations) || + ( + !object.metadata.annotations.exists(annotation, object.metadata.annotations[annotation].matches('\\s*alias\\s*.*;')) && + !object.metadata.annotations.exists(annotation, object.metadata.annotations[annotation].matches('\\s*root\\s*.*;')) && + !object.metadata.annotations.exists(annotation, object.metadata.annotations[annotation].matches('/etc/(passwd|shadow|group|nginx|ingress-controller)')) && + !object.metadata.annotations.exists(annotation, object.metadata.annotations[annotation].matches('/var/run/secrets')) && + !object.metadata.annotations.exists(annotation, object.metadata.annotations[annotation].matches('.*_by_lua.*')) + ) + message: "spec.rules[].http.paths[].path value is not allowed" + + +``` diff --git a/content/en/policies/nginx-ingress-cel/restrict-ingress-paths/restrict-ingress-paths.md b/content/en/policies/nginx-ingress-cel/restrict-ingress-paths/restrict-ingress-paths.md new file mode 100644 index 000000000..7e2cacee8 --- /dev/null +++ b/content/en/policies/nginx-ingress-cel/restrict-ingress-paths/restrict-ingress-paths.md @@ -0,0 +1,55 @@ +--- +title: "Restrict NGINX Ingress path values in CEL expressions" +category: Security, NGINX Ingress in CEL +version: 1.11.0 +subject: Ingress +policyType: "validate" +description: > + This policy mitigates CVE-2021-25745 by restricting `spec.rules[].http.paths[].path` to safe values. Additional paths can be added as required. This issue has been fixed in NGINX Ingress v1.2.0. Please refer to the CVE for details. +--- + +## Policy Definition +/nginx-ingress-cel/restrict-ingress-paths/restrict-ingress-paths.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-ingress-paths + annotations: + policies.kyverno.io/title: Restrict NGINX Ingress path values in CEL expressions + policies.kyverno.io/category: Security, NGINX Ingress in CEL + policies.kyverno.io/severity: high + policies.kyverno.io/subject: Ingress + policies.kyverno.io/minversion: "1.11.0" + kyverno.io/kyverno-version: "1.11.0" + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/description: >- + This policy mitigates CVE-2021-25745 by restricting `spec.rules[].http.paths[].path` to safe values. + Additional paths can be added as required. This issue has been fixed in NGINX Ingress v1.2.0. + Please refer to the CVE for details. +spec: + validationFailureAction: Enforce + rules: + - name: check-paths + match: + any: + - resources: + kinds: + - networking.k8s.io/v1/Ingress + operations: + - CREATE + - UPDATE + validate: + cel: + expressions: + - expression: >- + object.spec.?rules.orValue([]).all(rule, + rule.?http.?paths.orValue([]).all(p, + !p.path.contains('/etc') && !p.path.contains('/var/run/secrets') && + !p.path.contains('/root') && !p.path.contains('/var/run/kubernetes/serviceaccount') && + !p.path.contains('/etc/kubernetes/admin.conf'))) + message: "spec.rules[].http.paths[].path value is not allowed" + + +``` diff --git a/content/en/policies/nginx-ingress/disallow-ingress-nginx-custom-snippets/disallow-ingress-nginx-custom-snippets.md b/content/en/policies/nginx-ingress/disallow-ingress-nginx-custom-snippets/disallow-ingress-nginx-custom-snippets.md index de949af45..5a3bf826d 100644 --- a/content/en/policies/nginx-ingress/disallow-ingress-nginx-custom-snippets/disallow-ingress-nginx-custom-snippets.md +++ b/content/en/policies/nginx-ingress/disallow-ingress-nginx-custom-snippets/disallow-ingress-nginx-custom-snippets.md @@ -30,7 +30,7 @@ metadata: blocks *-snippet annotations on an Ingress. See: https://github.com/kubernetes/ingress-nginx/issues/7837 spec: - validationFailureAction: enforce + validationFailureAction: Enforce rules: - name: check-config-map match: diff --git a/content/en/policies/nginx-ingress/restrict-annotations/restrict-annotations.md b/content/en/policies/nginx-ingress/restrict-annotations/restrict-annotations.md index 4613282ad..2968f901d 100644 --- a/content/en/policies/nginx-ingress/restrict-annotations/restrict-annotations.md +++ b/content/en/policies/nginx-ingress/restrict-annotations/restrict-annotations.md @@ -31,7 +31,7 @@ metadata: "annotation-value-word-blocklist" configuration setting is also recommended. Please refer to the CVE for details. spec: - validationFailureAction: enforce + validationFailureAction: Enforce rules: - name: check-ingress match: diff --git a/content/en/policies/nginx-ingress/restrict-ingress-paths/restrict-ingress-paths.md b/content/en/policies/nginx-ingress/restrict-ingress-paths/restrict-ingress-paths.md index 9ab54ce8f..62d80cb8e 100644 --- a/content/en/policies/nginx-ingress/restrict-ingress-paths/restrict-ingress-paths.md +++ b/content/en/policies/nginx-ingress/restrict-ingress-paths/restrict-ingress-paths.md @@ -29,7 +29,7 @@ metadata: Additional paths can be added as required. This issue has been fixed in NGINX Ingress v1.2.0. Please refer to the CVE for details. spec: - validationFailureAction: enforce + validationFailureAction: Enforce rules: - name: check-paths match: diff --git a/content/en/policies/openshift-cel/check-routes/check-routes.md b/content/en/policies/openshift-cel/check-routes/check-routes.md new file mode 100644 index 000000000..48df98d9d --- /dev/null +++ b/content/en/policies/openshift-cel/check-routes/check-routes.md @@ -0,0 +1,50 @@ +--- +title: "Require TLS routes in OpenShift in CEL expressions" +category: OpenShift in CEL expressions +version: 1.11.0 +subject: Route +policyType: "validate" +description: > + HTTP traffic is not encrypted and hence insecure. This policy prevents configuration of OpenShift HTTP routes. +--- + +## Policy Definition +/openshift-cel/check-routes/check-routes.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: check-routes + annotations: + policies.kyverno.io/title: Require TLS routes in OpenShift in CEL expressions + policies.kyverno.io/category: OpenShift in CEL expressions + policies.kyverno.io/severity: high + kyverno.io/kyverno-version: 1.11.0 + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/subject: Route + policies.kyverno.io/description: |- + HTTP traffic is not encrypted and hence insecure. This policy prevents configuration of OpenShift HTTP routes. +spec: + validationFailureAction: Enforce + background: true + rules: + - name: require-tls-routes + match: + any: + - resources: + kinds: + - route.openshift.io/v1/Route + operations: + - CREATE + - UPDATE + validate: + cel: + expressions: + - expression: "has(object.spec.tls)" + message: >- + HTTP routes are not allowed. Configure TLS for secure routes. + + +``` diff --git a/content/en/policies/openshift-cel/disallow-deprecated-apis/disallow-deprecated-apis.md b/content/en/policies/openshift-cel/disallow-deprecated-apis/disallow-deprecated-apis.md new file mode 100644 index 000000000..a9807432a --- /dev/null +++ b/content/en/policies/openshift-cel/disallow-deprecated-apis/disallow-deprecated-apis.md @@ -0,0 +1,57 @@ +--- +title: "Disallow deprecated APIs in CEL expressions" +category: OpenShift in CEL +version: 1.11.0 +subject: ClusterRole,ClusterRoleBinding,Role,RoleBinding,RBAC +policyType: "validate" +description: > + OpenShift APIs are sometimes deprecated and removed after a few releases. As a best practice, older API versions should be replaced with newer versions. This policy validates for APIs that are deprecated or scheduled for removal. Note that checking for some of these resources may require modifying the Kyverno ConfigMap to remove filters. +--- + +## Policy Definition +/openshift-cel/disallow-deprecated-apis/disallow-deprecated-apis.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-deprecated-apis + annotations: + policies.kyverno.io/title: Disallow deprecated APIs in CEL expressions + policies.kyverno.io/category: OpenShift in CEL + policies.kyverno.io/severity: medium + kyverno.io/kyverno-version: 1.11.0 + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/subject: ClusterRole,ClusterRoleBinding,Role,RoleBinding,RBAC + policies.kyverno.io/description: >- + OpenShift APIs are sometimes deprecated and removed after a few releases. + As a best practice, older API versions should be replaced with newer versions. + This policy validates for APIs that are deprecated or scheduled for removal. + Note that checking for some of these resources may require modifying the Kyverno + ConfigMap to remove filters. +spec: + validationFailureAction: Enforce + background: true + rules: + - name: check-deprecated-apis + match: + any: + - resources: + kinds: + - authorization.openshift.io/v1/ClusterRole + - authorization.openshift.io/v1/ClusterRoleBinding + - authorization.openshift.io/v1/Role + - authorization.openshift.io/v1/RoleBinding + operations: + - CREATE + - UPDATE + validate: + cel: + expressions: + - expression: "false" + messageExpression: >- + object.apiVersion + '/' + object.kind + ' is deprecated.' + + +``` diff --git a/content/en/policies/openshift-cel/disallow-jenkins-pipeline-strategy/disallow-jenkins-pipeline-strategy.md b/content/en/policies/openshift-cel/disallow-jenkins-pipeline-strategy/disallow-jenkins-pipeline-strategy.md new file mode 100644 index 000000000..75046a09b --- /dev/null +++ b/content/en/policies/openshift-cel/disallow-jenkins-pipeline-strategy/disallow-jenkins-pipeline-strategy.md @@ -0,0 +1,51 @@ +--- +title: "Disallow OpenShift Jenkins Pipeline Build Strategy in CEL expressions" +category: OpenShift in CEL +version: 1.11.0 +subject: BuildConfig +policyType: "validate" +description: > + The Jenkins Pipeline Build Strategy has been deprecated. This policy prevents its use. Use OpenShift Pipelines instead. +--- + +## Policy Definition +/openshift-cel/disallow-jenkins-pipeline-strategy/disallow-jenkins-pipeline-strategy.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-jenkins-pipeline-strategy + annotations: + policies.kyverno.io/title: Disallow OpenShift Jenkins Pipeline Build Strategy in CEL expressions + policies.kyverno.io/category: OpenShift in CEL + policies.kyverno.io/severity: medium + kyverno.io/kyverno-version: 1.11.0 + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/subject: BuildConfig + policies.kyverno.io/description: >- + The Jenkins Pipeline Build Strategy has been deprecated. This policy prevents its use. Use OpenShift Pipelines instead. +spec: + validationFailureAction: Enforce + background: true + rules: + - name: check-build-strategy + match: + any: + - resources: + kinds: + - v1/BuildConfig + - build.openshift.io/v1/BuildConfig + operations: + - CREATE + - UPDATE + validate: + cel: + expressions: + - expression: "!has(object.spec.strategy.jenkinsPipelineStrategy)" + message: >- + Jenkins Pipeline Build Strategy has been deprecated and is not allowed + + +``` diff --git a/content/en/policies/openshift-cel/disallow-security-context-constraint-anyuid/disallow-security-context-constraint-anyuid.md b/content/en/policies/openshift-cel/disallow-security-context-constraint-anyuid/disallow-security-context-constraint-anyuid.md new file mode 100644 index 000000000..a007f607b --- /dev/null +++ b/content/en/policies/openshift-cel/disallow-security-context-constraint-anyuid/disallow-security-context-constraint-anyuid.md @@ -0,0 +1,67 @@ +--- +title: "Disallow use of the SecurityContextConstraint (SCC) anyuid in CEL expressions" +category: Security in CEL +version: 1.11.0 +subject: Role,ClusterRole,RBAC +policyType: "validate" +description: > + Disallow the use of the SecurityContextConstraint (SCC) anyuid which allows a pod to run with the UID as declared in the image instead of a random UID +--- + +## Policy Definition +/openshift-cel/disallow-security-context-constraint-anyuid/disallow-security-context-constraint-anyuid.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-security-context-constraint-anyuid + annotations: + policies.kyverno.io/title: Disallow use of the SecurityContextConstraint (SCC) anyuid in CEL expressions + policies.kyverno.io/category: Security in CEL + policies.kyverno.io/severity: high + kyverno.io/kyverno-version: 1.11.0 + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/subject: Role,ClusterRole,RBAC + policies.kyverno.io/description: >- + Disallow the use of the SecurityContextConstraint (SCC) anyuid which allows a pod to run with the UID as declared in the image instead of a random UID +spec: + validationFailureAction: Enforce + background: true + rules: + - name: check-security-context-constraint + match: + any: + - resources: + kinds: + - ClusterRole + - Role + operations: + - CREATE + - UPDATE + validate: + cel: + expressions: + - expression: "!object.?rules.orValue([]).exists(rule, 'anyuid' in rule.resourceNames && ('use' in rule.verbs || '*' in rule.verbs))" + message: >- + Use of the SecurityContextConstraint (SCC) anyuid is not allowed + - name: check-security-context-roleref + match: + any: + - resources: + kinds: + - ClusterRoleBinding + - RoleBinding + operations: + - CREATE + - UPDATE + validate: + cel: + expressions: + - expression: "object.roleRef.name != 'system:openshift:scc:anyuid'" + message: >- + Use of the SecurityContextConstraint (SCC) anyuid is not allowed + + +``` diff --git a/content/en/policies/openshift-cel/enforce-etcd-encryption/enforce-etcd-encryption.md b/content/en/policies/openshift-cel/enforce-etcd-encryption/enforce-etcd-encryption.md new file mode 100644 index 000000000..ec5391278 --- /dev/null +++ b/content/en/policies/openshift-cel/enforce-etcd-encryption/enforce-etcd-encryption.md @@ -0,0 +1,50 @@ +--- +title: "Enforce etcd encryption in OpenShift in CEL expressions" +category: OpenShift +version: 1.11.0 +subject: APIServer +policyType: "validate" +description: > + Encryption at rest is a security best practice. This policy ensures encryption is enabled for etcd in OpenShift clusters. +--- + +## Policy Definition +/openshift-cel/enforce-etcd-encryption/enforce-etcd-encryption.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: enforce-etcd-encryption + annotations: + policies.kyverno.io/title: Enforce etcd encryption in OpenShift in CEL expressions + policies.kyverno.io/category: OpenShift + policies.kyverno.io/severity: high + kyverno.io/kyverno-version: 1.11.0 + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/subject: APIServer + policies.kyverno.io/description: >- + Encryption at rest is a security best practice. This policy ensures encryption is enabled for etcd in OpenShift clusters. +spec: + validationFailureAction: Enforce + background: true + rules: + - name: check-etcd-encryption + match: + any: + - resources: + kinds: + - config.openshift.io/v1/APIServer + operations: + - CREATE + - UPDATE + validate: + cel: + expressions: + - expression: "has(object.spec.encryption)" + message: >- + Encryption should be enabled for etcd + + +``` diff --git a/content/en/policies/openshift/check-routes/check-routes.md b/content/en/policies/openshift/check-routes/check-routes.md index 0df6f5841..912eb0bd9 100644 --- a/content/en/policies/openshift/check-routes/check-routes.md +++ b/content/en/policies/openshift/check-routes/check-routes.md @@ -27,7 +27,7 @@ metadata: policies.kyverno.io/description: |- HTTP traffic is not encrypted and hence insecure. This policy prevents configuration of OpenShift HTTP routes. spec: - validationFailureAction: enforce + validationFailureAction: Enforce background: true rules: - name: require-tls-routes diff --git a/content/en/policies/openshift/disallow-deprecated-apis/disallow-deprecated-apis.md b/content/en/policies/openshift/disallow-deprecated-apis/disallow-deprecated-apis.md index a3230b057..6fd9d8929 100644 --- a/content/en/policies/openshift/disallow-deprecated-apis/disallow-deprecated-apis.md +++ b/content/en/policies/openshift/disallow-deprecated-apis/disallow-deprecated-apis.md @@ -31,7 +31,7 @@ metadata: Note that checking for some of these resources may require modifying the Kyverno ConfigMap to remove filters. spec: - validationFailureAction: enforce + validationFailureAction: Enforce background: true rules: - name: check-deprecated-apis diff --git a/content/en/policies/openshift/disallow-jenkins-pipeline-strategy/disallow-jenkins-pipeline-strategy.md b/content/en/policies/openshift/disallow-jenkins-pipeline-strategy/disallow-jenkins-pipeline-strategy.md index 5762543de..b6267829b 100644 --- a/content/en/policies/openshift/disallow-jenkins-pipeline-strategy/disallow-jenkins-pipeline-strategy.md +++ b/content/en/policies/openshift/disallow-jenkins-pipeline-strategy/disallow-jenkins-pipeline-strategy.md @@ -27,7 +27,7 @@ metadata: policies.kyverno.io/description: >- The Jenkins Pipeline Build Strategy has been deprecated. This policy prevents its use. Use OpenShift Pipelines instead. spec: - validationFailureAction: enforce + validationFailureAction: Enforce background: true rules: - name: check-build-strategy diff --git a/content/en/policies/openshift/disallow-security-context-constraint-anyuid/disallow-security-context-constraint-anyuid.md b/content/en/policies/openshift/disallow-security-context-constraint-anyuid/disallow-security-context-constraint-anyuid.md index d1ea2215e..50135b680 100644 --- a/content/en/policies/openshift/disallow-security-context-constraint-anyuid/disallow-security-context-constraint-anyuid.md +++ b/content/en/policies/openshift/disallow-security-context-constraint-anyuid/disallow-security-context-constraint-anyuid.md @@ -27,7 +27,7 @@ metadata: policies.kyverno.io/description: >- Disallow the use of the SecurityContextConstraint (SCC) anyuid which allows a pod to run with the UID as declared in the image instead of a random UID spec: - validationFailureAction: enforce + validationFailureAction: Enforce background: true rules: - name: check-security-context-constraint diff --git a/content/en/policies/openshift/disallow-self-provisioner-binding/disallow-self-provisioner-binding.md b/content/en/policies/openshift/disallow-self-provisioner-binding/disallow-self-provisioner-binding.md index 4b5497693..8aee5845d 100644 --- a/content/en/policies/openshift/disallow-self-provisioner-binding/disallow-self-provisioner-binding.md +++ b/content/en/policies/openshift/disallow-self-provisioner-binding/disallow-self-provisioner-binding.md @@ -27,7 +27,7 @@ metadata: policies.kyverno.io/description: >- This policy prevents binding to the self-provisioners role for strict control of OpenShift project creation. spec: - validationFailureAction: enforce + validationFailureAction: Enforce background: true rules: - name: check-self-provisioner-binding-no-subject diff --git a/content/en/policies/openshift/enforce-etcd-encryption/enforce-etcd-encryption.md b/content/en/policies/openshift/enforce-etcd-encryption/enforce-etcd-encryption.md index 0f533eb81..452778bff 100644 --- a/content/en/policies/openshift/enforce-etcd-encryption/enforce-etcd-encryption.md +++ b/content/en/policies/openshift/enforce-etcd-encryption/enforce-etcd-encryption.md @@ -27,7 +27,7 @@ metadata: policies.kyverno.io/description: >- Encryption at rest is a security best practice. This policy ensures encryption is enabled for etcd in OpenShift clusters. spec: - validationFailureAction: enforce + validationFailureAction: Enforce background: true rules: - name: check-etcd-encryption diff --git a/content/en/policies/openshift/team-validate-ns-name/team-validate-ns-name.md b/content/en/policies/openshift/team-validate-ns-name/team-validate-ns-name.md index 39bb76352..2da5e866f 100644 --- a/content/en/policies/openshift/team-validate-ns-name/team-validate-ns-name.md +++ b/content/en/policies/openshift/team-validate-ns-name/team-validate-ns-name.md @@ -31,7 +31,7 @@ metadata: This policy denies the creation of a Namespace if the name of the Namespace does not follow a specific naming defined by the cluster admins. spec: - validationFailureAction: audit + validationFailureAction: Audit background: false rules: - name: team-validate-ns-name diff --git a/content/en/policies/openshift/unique-routes/unique-routes.md b/content/en/policies/openshift/unique-routes/unique-routes.md index d37c25f17..44c4d064d 100644 --- a/content/en/policies/openshift/unique-routes/unique-routes.md +++ b/content/en/policies/openshift/unique-routes/unique-routes.md @@ -30,7 +30,7 @@ metadata: these hosts should be unique across the cluster to ensure no routing conflicts occur. This policy checks an incoming Route resource to ensure its hosts are unique to the cluster. spec: - validationFailureAction: enforce + validationFailureAction: Enforce background: false rules: - name: require-unique-routes diff --git a/content/en/policies/other-cel/advanced-restrict-image-registries/advanced-restrict-image-registries.md b/content/en/policies/other-cel/advanced-restrict-image-registries/advanced-restrict-image-registries.md index 10ae9d1d5..67bd911f8 100644 --- a/content/en/policies/other-cel/advanced-restrict-image-registries/advanced-restrict-image-registries.md +++ b/content/en/policies/other-cel/advanced-restrict-image-registries/advanced-restrict-image-registries.md @@ -55,13 +55,12 @@ spec: parameterNotFoundAction: Deny variables: - name: allContainers - expression: "(object.spec.containers + (has(object.spec.initContainers) ? object.spec.initContainers : []) + (has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []))" + expression: "object.spec.containers + object.spec.?initContainers.orValue([]) + object.spec.?ephemeralContainers.orValue([])" - name: nsregistries expression: >- - (has(namespaceObject.metadata.annotations) && 'corp.com/allowed-registries' in namespaceObject.metadata.annotations) ? - namespaceObject.metadata.annotations['corp.com/allowed-registries'] : ' ' + namespaceObject.metadata.?annotations[?'corp.com/allowed-registries'].orValue(' ') - name: clusterregistries - expression: "'registries' in params.data ? params.data['registries'] : ' '" + expression: "params.data[?'registries'].orValue(' ')" expressions: - expression: "variables.allContainers.all(container, container.image.startsWith(variables.nsregistries) || container.image.startsWith(variables.clusterregistries))" message: This Pod names an image that is not from an approved registry. diff --git a/content/en/policies/other-cel/allowed-annotations/allowed-annotations.md b/content/en/policies/other-cel/allowed-annotations/allowed-annotations.md index 51c15a6dd..9847e8c27 100644 --- a/content/en/policies/other-cel/allowed-annotations/allowed-annotations.md +++ b/content/en/policies/other-cel/allowed-annotations/allowed-annotations.md @@ -46,8 +46,7 @@ spec: cel: expressions: - expression: >- - !has(object.metadata.annotations) || - object.metadata.annotations.all(annotation, !annotation.contains('fluxcd.io/') || annotation in ['fluxcd.io/cow', 'fluxcd.io/dog']) + object.metadata.?annotations.orValue([]).all(annotation, !annotation.contains('fluxcd.io/') || annotation in ['fluxcd.io/cow', 'fluxcd.io/dog']) message: The only approved FluxCD annotations are `fluxcd.io/cow` and `fluxcd.io/dog`. diff --git a/content/en/policies/other-cel/check-env-vars/check-env-vars.md b/content/en/policies/other-cel/check-env-vars/check-env-vars.md index 6e1493d0b..2e6e0c9f9 100644 --- a/content/en/policies/other-cel/check-env-vars/check-env-vars.md +++ b/content/en/policies/other-cel/check-env-vars/check-env-vars.md @@ -46,8 +46,8 @@ spec: cel: expressions: - expression: >- - !object.spec.containers.exists(container, has(container.env) && - container.env.exists(e, e.name == 'DISABLE_OPA' && e.value == 'true')) + !object.spec.containers.exists(container, + container.?env.orValue([]).exists(e, e.name == 'DISABLE_OPA' && e.value == 'true')) message: "DISABLE_OPA must not be set to true." diff --git a/content/en/policies/other-cel/deny-commands-in-exec-probe/deny-commands-in-exec-probe.md b/content/en/policies/other-cel/deny-commands-in-exec-probe/deny-commands-in-exec-probe.md index a3b4b169e..1b58c777f 100644 --- a/content/en/policies/other-cel/deny-commands-in-exec-probe/deny-commands-in-exec-probe.md +++ b/content/en/policies/other-cel/deny-commands-in-exec-probe/deny-commands-in-exec-probe.md @@ -44,16 +44,13 @@ spec: celPreconditions: - name: "check-liveness-probes-commands-exist" expression: >- - object.spec.containers.exists(container, - has(container.livenessProbe) && has(container.livenessProbe.exec) && - size(container.livenessProbe.exec.command) > 0) + object.spec.containers.exists(container, size(container.?livenessProbe.?exec.?command.orValue([])) > 0) validate: cel: expressions: - expression: >- object.spec.containers.all(container, - !has(container.livenessProbe) || !has(container.livenessProbe.exec) || - !container.livenessProbe.exec.command.exists(command, + !container.?livenessProbe.?exec.?command.orValue([]).exists(command, command.matches('\\bjcmd\\b') || command.matches('\\bps\\b') || command.matches('\\bls\\b'))) message: Cannot use commands `jcmd`, `ps`, or `ls` in liveness probes. diff --git a/content/en/policies/other-cel/disallow-all-secrets/disallow-all-secrets.md b/content/en/policies/other-cel/disallow-all-secrets/disallow-all-secrets.md index b68cdb3d3..17bd1c0af 100644 --- a/content/en/policies/other-cel/disallow-all-secrets/disallow-all-secrets.md +++ b/content/en/policies/other-cel/disallow-all-secrets/disallow-all-secrets.md @@ -46,23 +46,21 @@ spec: variables: - name: allContainers expression: >- - object.spec.containers + - (has(object.spec.initContainers) ? object.spec.initContainers : []) + - (has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []) + object.spec.containers + + object.spec.?initContainers.orValue([]) + + object.spec.?ephemeralContainers.orValue([]) expressions: - expression: >- variables.allContainers.all(container, - !has(container.env) || - container.env.all(env, !has(env.valueFrom) || !has(env.valueFrom.secretKeyRef))) + container.?env.orValue([]).all(env, env.?valueFrom.?secretKeyRef.orValue(true))) message: "No Secrets from env." - expression: >- variables.allContainers.all(container, - !has(container.envFrom) || - container.envFrom.all(envFrom, !has(envFrom.secretRef))) + container.?envFrom.orValue([]).all(envFrom, !has(envFrom.secretRef))) message: "No Secrets from envFrom." - - expression: "!has(object.spec.volumes) || object.spec.volumes.all(volume, !has(volume.secret))" + - expression: "object.spec.?volumes.orValue([]).all(volume, !has(volume.secret))" message: "No Secrets from volumes." diff --git a/content/en/policies/other-cel/disallow-secrets-from-env-vars/disallow-secrets-from-env-vars.md b/content/en/policies/other-cel/disallow-secrets-from-env-vars/disallow-secrets-from-env-vars.md index 602ce80b7..d44226a47 100644 --- a/content/en/policies/other-cel/disallow-secrets-from-env-vars/disallow-secrets-from-env-vars.md +++ b/content/en/policies/other-cel/disallow-secrets-from-env-vars/disallow-secrets-from-env-vars.md @@ -43,9 +43,9 @@ spec: validate: cel: expressions: - - expression: "object.spec.containers.all(container, !has(container.env) || container.env.all(env, !has(env.valueFrom) || !has(env.valueFrom.secretKeyRef)))" + - expression: "object.spec.containers.all(container, container.?env.orValue([]).all(env, env.?valueFrom.?secretKeyRef.orValue(true)))" message: "Secrets must be mounted as volumes, not as environment variables." - - expression: "object.spec.containers.all(container, !has(container.envFrom) || container.envFrom.all(envFrom, !has(envFrom.secretRef)))" + - expression: "object.spec.containers.all(container, container.?envFrom.orValue([]).all(envFrom, !has(envFrom.secretRef)))" message: "Secrets must not come from envFrom statements." diff --git a/content/en/policies/other-cel/docker-socket-requires-label/docker-socket-requires-label.md b/content/en/policies/other-cel/docker-socket-requires-label/docker-socket-requires-label.md index 8286bc34e..b51ca5ed0 100644 --- a/content/en/policies/other-cel/docker-socket-requires-label/docker-socket-requires-label.md +++ b/content/en/policies/other-cel/docker-socket-requires-label/docker-socket-requires-label.md @@ -45,9 +45,9 @@ spec: cel: variables: - name: hasDockerSocket - expression: "has(object.spec.volumes) && object.spec.volumes.exists(volume, has(volume.hostPath) && volume.hostPath.path == '/var/run/docker.sock')" + expression: "object.spec.?volumes.orValue([]).exists(volume, volume.?hostPath.?path.orValue('') == '/var/run/docker.sock')" - name: isAllowDockerLabelTrue - expression: "has(object.metadata.labels) && 'allow-docker' in object.metadata.labels && object.metadata.labels['allow-docker'] == 'true'" + expression: "object.metadata.?labels[?'allow-docker'].orValue('false') == 'true'" expressions: - expression: "!variables.hasDockerSocket || variables.isAllowDockerLabelTrue" message: "If a hostPath volume exists and is set to `/var/run/docker.sock`, the label `allow-docker` must equal `true`." diff --git a/content/en/policies/other-cel/enforce-pod-duration/enforce-pod-duration.md b/content/en/policies/other-cel/enforce-pod-duration/enforce-pod-duration.md index 67748edfa..d824dd2e7 100644 --- a/content/en/policies/other-cel/enforce-pod-duration/enforce-pod-duration.md +++ b/content/en/policies/other-cel/enforce-pod-duration/enforce-pod-duration.md @@ -43,7 +43,7 @@ spec: cel: variables: - name: hasLifetimeAnnotation - expression: "has(object.metadata.annotations) && 'pod.kubernetes.io/lifetime' in object.metadata.annotations" + expression: "object.metadata.?annotations[?'pod.kubernetes.io/lifetime'].hasValue()" - name: lifetimeAnnotationValue expression: "variables.hasLifetimeAnnotation ? object.metadata.annotations['pod.kubernetes.io/lifetime'] : '0s'" expressions: diff --git a/content/en/policies/other-cel/ensure-readonly-hostpath/ensure-readonly-hostpath.md b/content/en/policies/other-cel/ensure-readonly-hostpath/ensure-readonly-hostpath.md index 91bb3b096..71617e6c3 100644 --- a/content/en/policies/other-cel/ensure-readonly-hostpath/ensure-readonly-hostpath.md +++ b/content/en/policies/other-cel/ensure-readonly-hostpath/ensure-readonly-hostpath.md @@ -48,14 +48,13 @@ spec: cel: variables: - name: allContainers - expression: "(object.spec.containers + (has(object.spec.initContainers) ? object.spec.initContainers : []) + (has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []))" + expression: "object.spec.containers + object.spec.?initContainers.orValue([]) + object.spec.?ephemeralContainers.orValue([])" - name: hostPathVolumes - expression: "has(object.spec.volumes) ? object.spec.volumes.filter(volume, has(volume.hostPath)) : []" + expression: "object.spec.?volumes.orValue([]).filter(volume, has(volume.hostPath))" expressions: - expression: >- variables.hostPathVolumes.all(hostPath, variables.allContainers.all(container, - !has(container.volumeMounts) || - container.volumeMounts.all(volume, (hostPath.name != volume.name) || has(volume.readOnly) && volume.readOnly == true))) + container.volumeMounts.orValue([]).all(volume, (hostPath.name != volume.name) || volume.?readOnly.orValue(false) == true))) message: All hostPath volumes must be mounted as readOnly. diff --git a/content/en/policies/other-cel/forbid-cpu-limits/forbid-cpu-limits.md b/content/en/policies/other-cel/forbid-cpu-limits/forbid-cpu-limits.md index ffebf4a72..2774727a4 100644 --- a/content/en/policies/other-cel/forbid-cpu-limits/forbid-cpu-limits.md +++ b/content/en/policies/other-cel/forbid-cpu-limits/forbid-cpu-limits.md @@ -44,7 +44,7 @@ spec: expressions: - expression: >- !object.spec.containers.exists(container, - has(container.resources) && has(container.resources.limits) && has(container.resources.limits.cpu)) + container.?resources.?limits.?cpu.hasValue()) message: Containers may not define CPU limits. diff --git a/content/en/policies/other-cel/ingress-host-match-tls/ingress-host-match-tls.md b/content/en/policies/other-cel/ingress-host-match-tls/ingress-host-match-tls.md index 3c6d78e8b..5a2474217 100644 --- a/content/en/policies/other-cel/ingress-host-match-tls/ingress-host-match-tls.md +++ b/content/en/policies/other-cel/ingress-host-match-tls/ingress-host-match-tls.md @@ -47,12 +47,12 @@ spec: cel: variables: - name: tls - expression: "has(object.spec.tls) ? object.spec.tls : []" + expression: "object.spec.?tls.orValue([])" expressions: - expression: >- object.spec.rules.all(rule, !has(rule.host) || - variables.tls.exists(tls, has(tls.hosts) && tls.hosts.exists(tlsHost, tlsHost == rule.host))) + variables.tls.exists(tls, tls.?hosts.orValue([]).exists(tlsHost, tlsHost == rule.host))) message: "The host(s) in spec.rules[].host must match those in spec.tls[].hosts[]." diff --git a/content/en/policies/other-cel/limit-hostpath-vols/limit-hostpath-vols.md b/content/en/policies/other-cel/limit-hostpath-vols/limit-hostpath-vols.md index ba7f09ac2..d6eeda099 100644 --- a/content/en/policies/other-cel/limit-hostpath-vols/limit-hostpath-vols.md +++ b/content/en/policies/other-cel/limit-hostpath-vols/limit-hostpath-vols.md @@ -46,7 +46,7 @@ spec: - UPDATE celPreconditions: - name: "has-host-path-volume" - expression: "has(object.spec.volumes) && object.spec.volumes.exists(volume, has(volume.hostPath))" + expression: "object.spec.?volumes.orValue([]).exists(volume, has(volume.hostPath))" validate: cel: expressions: diff --git a/content/en/policies/other-cel/memory-requests-equal-limits/memory-requests-equal-limits.md b/content/en/policies/other-cel/memory-requests-equal-limits/memory-requests-equal-limits.md index 68ee34b36..b8d3061ca 100644 --- a/content/en/policies/other-cel/memory-requests-equal-limits/memory-requests-equal-limits.md +++ b/content/en/policies/other-cel/memory-requests-equal-limits/memory-requests-equal-limits.md @@ -42,14 +42,10 @@ spec: - UPDATE validate: cel: - variables: - - name: containersWithResources - expression: object.spec.containers.filter(container, has(container.resources)) expressions: - expression: >- - variables.containersWithResources.all(container, - !has(container.resources.requests) || - !has(container.resources.requests.memory) || + object.spec.containers.all(container, + !container.?resources.?requests.?memory.hasValue() || container.resources.requests.memory == container.resources.?limits.?memory.orValue('-1')) message: "resources.requests.memory must be equal to resources.limits.memory" diff --git a/content/en/policies/other-cel/metadata-match-regex/metadata-match-regex.md b/content/en/policies/other-cel/metadata-match-regex/metadata-match-regex.md index ecf9999c3..546edabf3 100644 --- a/content/en/policies/other-cel/metadata-match-regex/metadata-match-regex.md +++ b/content/en/policies/other-cel/metadata-match-regex/metadata-match-regex.md @@ -45,8 +45,7 @@ spec: cel: expressions: - expression: >- - has(object.metadata.labels) && 'corp.org/version' in object.metadata.labels && - object.metadata.labels['corp.org/version'].matches('^v[0-9].[0-9].[0-9]$') + object.metadata.?labels[?'corp.org/version'].orValue('default').matches('^v[0-9].[0-9].[0-9]$') message: >- The label `corp.org/version` is required and must match the specified regex: ^v[0-9].[0-9].[0-9]$ diff --git a/content/en/policies/other-cel/pdb-maxunavailable/pdb-maxunavailable.md b/content/en/policies/other-cel/pdb-maxunavailable/pdb-maxunavailable.md index 3aa9657c5..262b384c4 100644 --- a/content/en/policies/other-cel/pdb-maxunavailable/pdb-maxunavailable.md +++ b/content/en/policies/other-cel/pdb-maxunavailable/pdb-maxunavailable.md @@ -43,7 +43,7 @@ spec: validate: cel: expressions: - - expression: "!has(object.spec.maxUnavailable) || int(object.spec.maxUnavailable) > 0" + - expression: "int(object.spec.?maxUnavailable.orValue(1)) > 0" message: "The value of maxUnavailable must be greater than zero." diff --git a/content/en/policies/other-cel/prevent-cr8escape/prevent-cr8escape.md b/content/en/policies/other-cel/prevent-cr8escape/prevent-cr8escape.md index b9279c18f..20ca08bb3 100644 --- a/content/en/policies/other-cel/prevent-cr8escape/prevent-cr8escape.md +++ b/content/en/policies/other-cel/prevent-cr8escape/prevent-cr8escape.md @@ -46,8 +46,8 @@ spec: cel: expressions: - expression: >- - !has(object.spec.securityContext) || !has(object.spec.securityContext.sysctls) || - object.spec.securityContext.sysctls.all(sysctl, !has(sysctl.value) || (!sysctl.value.contains('+') && !sysctl.value.contains('='))) + object.spec.?securityContext.?sysctls.orValue([]).all(sysctl, + !has(sysctl.value) || (!sysctl.value.contains('+') && !sysctl.value.contains('='))) message: "characters '+' or '=' are not allowed in sysctls values" diff --git a/content/en/policies/other-cel/require-annotations/require-annotations.md b/content/en/policies/other-cel/require-annotations/require-annotations.md index 041426973..dd6180ae5 100644 --- a/content/en/policies/other-cel/require-annotations/require-annotations.md +++ b/content/en/policies/other-cel/require-annotations/require-annotations.md @@ -45,8 +45,7 @@ spec: cel: expressions: - expression: >- - has(object.metadata.annotations) && - 'corp.org/department' in object.metadata.annotations && object.metadata.annotations['corp.org/department'] != '' + object.metadata.?annotations[?'corp.org/department'].orValue('') != '' message: "The annotation `corp.org/department` is required." diff --git a/content/en/policies/other-cel/require-container-port-names/require-container-port-names.md b/content/en/policies/other-cel/require-container-port-names/require-container-port-names.md index 4e7024053..daeb1ca1a 100644 --- a/content/en/policies/other-cel/require-container-port-names/require-container-port-names.md +++ b/content/en/policies/other-cel/require-container-port-names/require-container-port-names.md @@ -45,7 +45,7 @@ spec: validate: cel: expressions: - - expression: "object.spec.containers.all(container, !has(container.ports) || container.ports.all(port, has(port.name)))" + - expression: "object.spec.containers.all(container, container.?ports.orValue([]).all(port, has(port.name)))" message: Name is required for every containerPort. diff --git a/content/en/policies/other-cel/require-emptydir-requests-limits/require-emptydir-requests-limits.md b/content/en/policies/other-cel/require-emptydir-requests-limits/require-emptydir-requests-limits.md index 26f103119..6724be164 100644 --- a/content/en/policies/other-cel/require-emptydir-requests-limits/require-emptydir-requests-limits.md +++ b/content/en/policies/other-cel/require-emptydir-requests-limits/require-emptydir-requests-limits.md @@ -44,12 +44,12 @@ spec: - UPDATE celPreconditions: - name: "has-emptydir-volume" - expression: "has(object.spec.volumes) && object.spec.volumes.exists(volume, has(volume.emptyDir))" + expression: "object.spec.?volumes.orValue([]).exists(volume, has(volume.emptyDir))" validate: cel: variables: - name: containers - expression: "object.spec.containers + (has(object.spec.initContainers) ? object.spec.initContainers : [])" + expression: "object.spec.containers + object.spec.?initContainers.orValue([])" - name: emptydirnames expression: >- has(object.spec.volumes) ? @@ -57,8 +57,7 @@ spec: expressions: - expression: >- variables.containers.all(container, - !has(container.volumeMounts) || - !container.volumeMounts.exists(mount, mount.name in variables.emptydirnames) || + !container.?volumeMounts.orValue([]).exists(mount, mount.name in variables.emptydirnames) || container.resources.?requests[?'ephemeral-storage'].hasValue() && container.resources.?limits[?'ephemeral-storage'].hasValue()) message: Containers mounting emptyDir volumes must specify requests and limits for ephemeral-storage. diff --git a/content/en/policies/other-cel/require-ingress-https/require-ingress-https.md b/content/en/policies/other-cel/require-ingress-https/require-ingress-https.md index ebf741031..e8d7855ce 100644 --- a/content/en/policies/other-cel/require-ingress-https/require-ingress-https.md +++ b/content/en/policies/other-cel/require-ingress-https/require-ingress-https.md @@ -45,9 +45,7 @@ spec: cel: expressions: - expression: >- - has(object.metadata.annotations) && - 'kubernetes.io/ingress.allow-http' in object.metadata.annotations && - object.metadata.annotations['kubernetes.io/ingress.allow-http'] == 'false' + object.metadata.?annotations[?'kubernetes.io/ingress.allow-http'].orValue('default') == 'false' message: "The kubernetes.io/ingress.allow-http annotation must be set to false." - name: has-tls match: diff --git a/content/en/policies/other-cel/require-non-root-groups/require-non-root-groups.md b/content/en/policies/other-cel/require-non-root-groups/require-non-root-groups.md index 985b44457..66bd04aab 100644 --- a/content/en/policies/other-cel/require-non-root-groups/require-non-root-groups.md +++ b/content/en/policies/other-cel/require-non-root-groups/require-non-root-groups.md @@ -46,15 +46,15 @@ spec: cel: variables: - name: allContainers - expression: "(object.spec.containers + (has(object.spec.initContainers) ? object.spec.initContainers : []) + (has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []))" + expression: "object.spec.containers + object.spec.?initContainers.orValue([]) + object.spec.?ephemeralContainers.orValue([])" expressions: - expression: >- ( - has(object.spec.securityContext) && has(object.spec.securityContext.runAsGroup) && (object.spec.securityContext.runAsGroup > 0) && - variables.allContainers.all(container, !has(container.securityContext) || !has(container.securityContext.runAsGroup) || container.securityContext.runAsGroup > 0) + object.spec.?securityContext.?runAsGroup.orValue(-1) > 0 && + variables.allContainers.all(container, container.?securityContext.?runAsGroup.orValue(1) > 0) ) || ( - variables.allContainers.all(container, has(container.securityContext) && has(container.securityContext.runAsGroup) && container.securityContext.runAsGroup > 0) + variables.allContainers.all(container, container.?securityContext.?runAsGroup.orValue(-1) > 0) ) message: >- Running with root group IDs is disallowed. The fields @@ -75,8 +75,7 @@ spec: cel: expressions: - expression: >- - !has(object.spec.securityContext) || !has(object.spec.securityContext.supplementalGroups) || - object.spec.securityContext.supplementalGroups.all(group, group > 0) + object.spec.?securityContext.?supplementalGroups.orValue([]).all(group, group > 0) message: >- Containers cannot run with a root primary or supplementary GID. The field spec.securityContext.supplementalGroups must be unset or @@ -94,8 +93,7 @@ spec: cel: expressions: - expression: >- - !has(object.spec.securityContext) || !has(object.spec.securityContext.fsGroup) || - object.spec.securityContext.fsGroup > 0 + object.spec.?securityContext.?fsGroup.orValue(1) > 0 message: >- Containers cannot run with a root primary or supplementary GID. The field spec.securityContext.fsGroup must be unset or set to a value greater than zero. diff --git a/content/en/policies/other-cel/require-pod-priorityclassname/require-pod-priorityclassname.md b/content/en/policies/other-cel/require-pod-priorityclassname/require-pod-priorityclassname.md index 4c583ba7d..8ae02d574 100644 --- a/content/en/policies/other-cel/require-pod-priorityclassname/require-pod-priorityclassname.md +++ b/content/en/policies/other-cel/require-pod-priorityclassname/require-pod-priorityclassname.md @@ -46,7 +46,7 @@ spec: validate: cel: expressions: - - expression: "has(object.spec.priorityClassName) && object.spec.priorityClassName != ''" + - expression: "object.spec.?priorityClassName.orValue('') != ''" message: "Pods must define the priorityClassName field." diff --git a/content/en/policies/other-cel/require-storageclass/require-storageclass.md b/content/en/policies/other-cel/require-storageclass/require-storageclass.md index af4c8c4af..60e7a138e 100644 --- a/content/en/policies/other-cel/require-storageclass/require-storageclass.md +++ b/content/en/policies/other-cel/require-storageclass/require-storageclass.md @@ -45,7 +45,7 @@ spec: validate: cel: expressions: - - expression: "has(object.spec.storageClassName) && object.spec.storageClassName != ''" + - expression: "object.spec.?storageClassName.orValue('') != ''" message: "PersistentVolumeClaims must define a storageClassName." - name: ss-storageclass match: @@ -62,7 +62,7 @@ spec: - expression: >- !has(object.spec.volumeClaimTemplates) || object.spec.volumeClaimTemplates.all(volumeClaimTemplate, - has(volumeClaimTemplate.spec.storageClassName) && volumeClaimTemplate.spec.storageClassName != '') + volumeClaimTemplate.spec.?storageClassName.orValue('') != '') message: "StatefulSets must define a storageClassName." diff --git a/content/en/policies/other-cel/restrict-annotations/restrict-annotations.md b/content/en/policies/other-cel/restrict-annotations/restrict-annotations.md index 85a173a32..bf1773274 100644 --- a/content/en/policies/other-cel/restrict-annotations/restrict-annotations.md +++ b/content/en/policies/other-cel/restrict-annotations/restrict-annotations.md @@ -49,7 +49,7 @@ spec: validate: cel: expressions: - - expression: "!has(object.metadata.annotations) || !object.metadata.annotations.exists(annotation, annotation.startsWith('fluxcd.io/'))" + - expression: "!object.metadata.?annotations.orValue([]).exists(annotation, annotation.startsWith('fluxcd.io/'))" message: Cannot use Flux v1 annotation. diff --git a/content/en/policies/other-cel/restrict-controlplane-scheduling/restrict-controlplane-scheduling.md b/content/en/policies/other-cel/restrict-controlplane-scheduling/restrict-controlplane-scheduling.md index 8ed9beb1d..415137503 100644 --- a/content/en/policies/other-cel/restrict-controlplane-scheduling/restrict-controlplane-scheduling.md +++ b/content/en/policies/other-cel/restrict-controlplane-scheduling/restrict-controlplane-scheduling.md @@ -46,7 +46,7 @@ spec: expressions: - expression: >- !has(object.spec.tolerations) || - !object.spec.tolerations.exists(toleration, has(toleration.key) && toleration.key in ['node-role.kubernetes.io/master', 'node-role.kubernetes.io/control-plane']) + !object.spec.tolerations.exists(toleration, toleration.?key.orValue('') in ['node-role.kubernetes.io/master', 'node-role.kubernetes.io/control-plane']) message: Pods may not use tolerations which schedule on control plane nodes. diff --git a/content/en/policies/other-cel/restrict-deprecated-registry/restrict-deprecated-registry.md b/content/en/policies/other-cel/restrict-deprecated-registry/restrict-deprecated-registry.md index 5d19e0929..51940f2ad 100644 --- a/content/en/policies/other-cel/restrict-deprecated-registry/restrict-deprecated-registry.md +++ b/content/en/policies/other-cel/restrict-deprecated-registry/restrict-deprecated-registry.md @@ -46,7 +46,7 @@ spec: cel: variables: - name: allContainers - expression: "(object.spec.containers + (has(object.spec.initContainers) ? object.spec.initContainers : []) + (has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []))" + expression: "object.spec.containers + object.spec.?initContainers.orValue([]) + object.spec.?ephemeralContainers.orValue([])" expressions: - expression: "variables.allContainers.all(container, !container.image.startsWith('k8s.gcr.io/'))" message: "The \"k8s.gcr.io\" image registry is deprecated. \"registry.k8s.io\" should now be used." diff --git a/content/en/policies/other-cel/restrict-ingress-classes/restrict-ingress-classes.md b/content/en/policies/other-cel/restrict-ingress-classes/restrict-ingress-classes.md index e661b5088..2c0cb3e8d 100644 --- a/content/en/policies/other-cel/restrict-ingress-classes/restrict-ingress-classes.md +++ b/content/en/policies/other-cel/restrict-ingress-classes/restrict-ingress-classes.md @@ -47,9 +47,7 @@ spec: cel: expressions: - expression: >- - has(object.metadata.annotations) && - 'kubernetes.io/ingress.class' in object.metadata.annotations && - object.metadata.annotations['kubernetes.io/ingress.class'] in ['HAProxy', 'nginx'] + object.metadata.?annotations[?'kubernetes.io/ingress.class'].orValue('') in ['HAProxy', 'nginx'] message: "Unknown ingress class." diff --git a/content/en/policies/other-cel/restrict-ingress-wildcard/restrict-ingress-wildcard.md b/content/en/policies/other-cel/restrict-ingress-wildcard/restrict-ingress-wildcard.md index 1098cff8f..9e5873c2c 100644 --- a/content/en/policies/other-cel/restrict-ingress-wildcard/restrict-ingress-wildcard.md +++ b/content/en/policies/other-cel/restrict-ingress-wildcard/restrict-ingress-wildcard.md @@ -46,7 +46,7 @@ spec: validate: cel: expressions: - - expression: "!has(object.spec.rules) || !object.spec.rules.exists(rule, has(rule.host) && rule.host.contains('*'))" + - expression: "!object.spec.?rules.orValue([]).exists(rule, has(rule.host) && rule.host.contains('*'))" message: "Wildcards are not permitted as hosts." diff --git a/content/en/policies/other-cel/restrict-node-affinity/restrict-node-affinity.md b/content/en/policies/other-cel/restrict-node-affinity/restrict-node-affinity.md index 126802bbc..a082d0ac3 100644 --- a/content/en/policies/other-cel/restrict-node-affinity/restrict-node-affinity.md +++ b/content/en/policies/other-cel/restrict-node-affinity/restrict-node-affinity.md @@ -45,7 +45,7 @@ spec: validate: cel: expressions: - - expression: "!has(object.spec.affinity) || !has(object.spec.affinity.nodeAffinity)" + - expression: "!object.spec.?affinity.?nodeAffinity.hasValue()" message: "Node affinity cannot be used." diff --git a/content/en/policies/other-cel/restrict-node-label-creation/restrict-node-label-creation.md b/content/en/policies/other-cel/restrict-node-label-creation/restrict-node-label-creation.md index d1812d49e..7c8f5520b 100644 --- a/content/en/policies/other-cel/restrict-node-label-creation/restrict-node-label-creation.md +++ b/content/en/policies/other-cel/restrict-node-label-creation/restrict-node-label-creation.md @@ -45,7 +45,7 @@ spec: - name: "operation-should-be-update" expression: "request.operation == 'UPDATE'" - name: "has-foo-label" - expression: "has(object.metadata.labels) && 'foo' in object.metadata.labels" + expression: "object.metadata.?labels.?foo.hasValue()" validate: cel: expressions: diff --git a/content/en/policies/other-cel/restrict-sa-automount-sa-token/restrict-sa-automount-sa-token.md b/content/en/policies/other-cel/restrict-sa-automount-sa-token/restrict-sa-automount-sa-token.md index adb93a9d8..2bb3e6e5f 100644 --- a/content/en/policies/other-cel/restrict-sa-automount-sa-token/restrict-sa-automount-sa-token.md +++ b/content/en/policies/other-cel/restrict-sa-automount-sa-token/restrict-sa-automount-sa-token.md @@ -45,7 +45,7 @@ spec: validate: cel: expressions: - - expression: "has(object.automountServiceAccountToken) && object.automountServiceAccountToken == false" + - expression: "object.?automountServiceAccountToken.orValue(true) == false" message: "ServiceAccounts must set automountServiceAccountToken to false." diff --git a/content/en/policies/other-cel/restrict-secrets-by-name/restrict-secrets-by-name.md b/content/en/policies/other-cel/restrict-secrets-by-name/restrict-secrets-by-name.md index 654f64b9a..bb5714602 100644 --- a/content/en/policies/other-cel/restrict-secrets-by-name/restrict-secrets-by-name.md +++ b/content/en/policies/other-cel/restrict-secrets-by-name/restrict-secrets-by-name.md @@ -47,12 +47,12 @@ spec: cel: variables: - name: allContainers - expression: "(object.spec.containers + (has(object.spec.initContainers) ? object.spec.initContainers : []) + (has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []))" + expression: "object.spec.containers + object.spec.?initContainers.orValue([]) + object.spec.?ephemeralContainers.orValue([])" expressions: - expression: >- variables.allContainers.all(container, - !has(container.env) || container.env.all(env, - !has(env.valueFrom) || !has(env.valueFrom.secretKeyRef) || env.valueFrom.secretKeyRef.name.startsWith("safe-"))) + container.?env.orValue([]).all(env, + env.?valueFrom.?secretKeyRef.?name.orValue('safe-').startsWith("safe-"))) message: "Only Secrets beginning with `safe-` may be consumed in env statements." - name: safe-secrets-from-envfrom match: @@ -67,12 +67,12 @@ spec: cel: variables: - name: allContainers - expression: "(object.spec.containers + (has(object.spec.initContainers) ? object.spec.initContainers : []) + (has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []))" + expression: "object.spec.containers + object.spec.?initContainers.orValue([]) + object.spec.?ephemeralContainers.orValue([])" expressions: - expression: >- variables.allContainers.all(container, - !has(container.envFrom) || container.envFrom.all(env, - !has(env.secretRef) || env.secretRef.name.startsWith("safe-"))) + container.?envFrom.orValue([]).all(env, + env.?secretRef.?name.orValue('safe-').startsWith("safe-"))) message: "Only Secrets beginning with `safe-` may be consumed in envFrom statements." - name: safe-secrets-from-volumes match: @@ -87,8 +87,8 @@ spec: cel: expressions: - expression: >- - !has(object.spec.volumes) || object.spec.volumes.all(volume, - !has(volume.secret) || volume.secret.secretName.startsWith("safe-")) + object.spec.?volumes.orValue([]).all(volume, + volume.?secret.?secretName.orValue('safe-').startsWith("safe-")) message: "Only Secrets beginning with `safe-` may be consumed in volumes." diff --git a/content/en/policies/other-cel/restrict-usergroup-fsgroup-id/restrict-usergroup-fsgroup-id.md b/content/en/policies/other-cel/restrict-usergroup-fsgroup-id/restrict-usergroup-fsgroup-id.md index f3cb869c5..46a2a9212 100644 --- a/content/en/policies/other-cel/restrict-usergroup-fsgroup-id/restrict-usergroup-fsgroup-id.md +++ b/content/en/policies/other-cel/restrict-usergroup-fsgroup-id/restrict-usergroup-fsgroup-id.md @@ -45,11 +45,11 @@ spec: validate: cel: expressions: - - expression: "has(object.spec.securityContext.runAsUser) && object.spec.securityContext.runAsUser == 1000" + - expression: "object.spec.?securityContext.?runAsUser.orValue(1) == 1000" message: "User ID should be 1000." - - expression: "has(object.spec.securityContext.runAsGroup) && object.spec.securityContext.runAsGroup == 3000" + - expression: "object.spec.?securityContext.?runAsGroup.orValue(1) == 3000" message: "Group ID should be 3000." - - expression: "has(object.spec.securityContext.fsGroup) && object.spec.securityContext.fsGroup == 2000" + - expression: "object.spec.?securityContext.?fsGroup.orValue(1) == 2000" message: "fs Group should be 2000." diff --git a/content/en/policies/other-cel/topologyspreadconstraints-policy/topologyspreadconstraints-policy.md b/content/en/policies/other-cel/topologyspreadconstraints-policy/topologyspreadconstraints-policy.md index 0357db6c5..f33111a45 100644 --- a/content/en/policies/other-cel/topologyspreadconstraints-policy/topologyspreadconstraints-policy.md +++ b/content/en/policies/other-cel/topologyspreadconstraints-policy/topologyspreadconstraints-policy.md @@ -52,8 +52,7 @@ spec: cel: expressions: - expression: >- - has(object.spec.template.spec.topologySpreadConstraints) && - size(object.spec.template.spec.topologySpreadConstraints.filter(t, t.topologyKey == 'kubernetes.io/hostname' || t.topologyKey == 'topology.kubernetes.io/zone')) == 2 + size(object.spec.template.spec.?topologySpreadConstraints.orValue([]).filter(t, t.topologyKey == 'kubernetes.io/hostname' || t.topologyKey == 'topology.kubernetes.io/zone')) == 2 message: "topologySpreadConstraint for kubernetes.io/hostname & topology.kubernetes.io/zone are required" diff --git a/content/en/policies/other/advanced-restrict-image-registries/advanced-restrict-image-registries.md b/content/en/policies/other/advanced-restrict-image-registries/advanced-restrict-image-registries.md index 517c27c40..5b223db9a 100644 --- a/content/en/policies/other/advanced-restrict-image-registries/advanced-restrict-image-registries.md +++ b/content/en/policies/other/advanced-restrict-image-registries/advanced-restrict-image-registries.md @@ -32,7 +32,7 @@ metadata: policy which gets a global approved registry from a ConfigMap and, based upon an annotation at the Namespace level, gets the registry approved for that Namespace. spec: - validationFailureAction: audit + validationFailureAction: Audit background: false rules: - name: validate-corp-registries diff --git a/content/en/policies/other/allowed-annotations/allowed-annotations.md b/content/en/policies/other/allowed-annotations/allowed-annotations.md index 3f4f9c8ea..aec2f606a 100644 --- a/content/en/policies/other/allowed-annotations/allowed-annotations.md +++ b/content/en/policies/other/allowed-annotations/allowed-annotations.md @@ -30,7 +30,7 @@ metadata: This policy demonstrates how to allow two annotations with a specific key name of fluxcd.io/ while denying others that do not meet the pattern. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: allowed-fluxcd-annotations diff --git a/content/en/policies/other/allowed-base-images/allowed-base-images.md b/content/en/policies/other/allowed-base-images/allowed-base-images.md index 7e4a2a9df..479f03f3d 100644 --- a/content/en/policies/other/allowed-base-images/allowed-base-images.md +++ b/content/en/policies/other/allowed-base-images/allowed-base-images.md @@ -32,7 +32,7 @@ metadata: that a container's base, found in an OCI annotation, is in a cluster-wide allow list. spec: - validationFailureAction: audit + validationFailureAction: Audit rules: - name: allowed-base-images match: diff --git a/content/en/policies/other/allowed-image-repos/allowed-image-repos.md b/content/en/policies/other/allowed-image-repos/allowed-image-repos.md index 0701b01bf..09407b87a 100644 --- a/content/en/policies/other/allowed-image-repos/allowed-image-repos.md +++ b/content/en/policies/other/allowed-image-repos/allowed-image-repos.md @@ -30,7 +30,7 @@ metadata: image repositories present in a given Pod, across any container type, come from the designated list. spec: - validationFailureAction: audit + validationFailureAction: Audit background: false rules: - name: good-repos diff --git a/content/en/policies/other/allowed-label-changes/allowed-label-changes.md b/content/en/policies/other/allowed-label-changes/allowed-label-changes.md index c530748ac..bb06da9c5 100644 --- a/content/en/policies/other/allowed-label-changes/allowed-label-changes.md +++ b/content/en/policies/other/allowed-label-changes/allowed-label-changes.md @@ -32,7 +32,7 @@ metadata: except one with the key `breakglass`. Changing, adding, or deleting any other labels is denied. spec: - validationFailureAction: enforce + validationFailureAction: Enforce background: false rules: - name: safe-label diff --git a/content/en/policies/other/allowed-pod-priorities/allowed-pod-priorities.md b/content/en/policies/other/allowed-pod-priorities/allowed-pod-priorities.md index 786f64c9e..da64cfe6e 100644 --- a/content/en/policies/other/allowed-pod-priorities/allowed-pod-priorities.md +++ b/content/en/policies/other/allowed-pod-priorities/allowed-pod-priorities.md @@ -29,7 +29,7 @@ metadata: PriorityClasses for the given Namespace stored in a ConfigMap. If the `priorityClassName` is not among them, the Pod is blocked. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: validate-pod-priority diff --git a/content/en/policies/other/block-ephemeral-containers/block-ephemeral-containers.md b/content/en/policies/other/block-ephemeral-containers/block-ephemeral-containers.md index 1194743f5..a9d6814da 100644 --- a/content/en/policies/other/block-ephemeral-containers/block-ephemeral-containers.md +++ b/content/en/policies/other/block-ephemeral-containers/block-ephemeral-containers.md @@ -30,7 +30,7 @@ metadata: This may potentially be used to gain access to unauthorized information executing inside one or more containers in that Pod. This policy blocks the use of ephemeral containers. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: block-ephemeral-containers diff --git a/content/en/policies/other/block-images-with-volumes/block-images-with-volumes.md b/content/en/policies/other/block-images-with-volumes/block-images-with-volumes.md index 501bc678a..d990cfa22 100644 --- a/content/en/policies/other/block-images-with-volumes/block-images-with-volumes.md +++ b/content/en/policies/other/block-images-with-volumes/block-images-with-volumes.md @@ -30,7 +30,7 @@ metadata: This may be unexpected and undesirable. This policy checks the contents of every container image and inspects them for such VOLUME statements, then blocks if found. spec: - validationFailureAction: audit + validationFailureAction: Audit rules: - name: block-images-with-vols match: diff --git a/content/en/policies/other/block-large-images/block-large-images.md b/content/en/policies/other/block-large-images/block-large-images.md index 12d8841cd..b38d966ea 100644 --- a/content/en/policies/other/block-large-images/block-large-images.md +++ b/content/en/policies/other/block-large-images/block-large-images.md @@ -30,7 +30,7 @@ metadata: name an image which is unusually large to disrupt operations. This policy checks the size of every container image and blocks if it is over 2 Gibibytes. spec: - validationFailureAction: audit + validationFailureAction: Audit rules: - name: block-over-twogi match: diff --git a/content/en/policies/other/block-pod-exec-by-namespace-label/block-pod-exec-by-namespace-label.md b/content/en/policies/other/block-pod-exec-by-namespace-label/block-pod-exec-by-namespace-label.md index e9b2c3640..8b3830ead 100644 --- a/content/en/policies/other/block-pod-exec-by-namespace-label/block-pod-exec-by-namespace-label.md +++ b/content/en/policies/other/block-pod-exec-by-namespace-label/block-pod-exec-by-namespace-label.md @@ -26,7 +26,7 @@ metadata: be useful for troubleshooting purposes, it could represent an attack vector and is discouraged. This policy blocks Pod exec commands based upon a Namespace label `exec=false`. spec: - validationFailureAction: enforce + validationFailureAction: Enforce background: false rules: - name: deny-exec-by-ns-label diff --git a/content/en/policies/other/block-pod-exec-by-namespace/block-pod-exec-by-namespace.md b/content/en/policies/other/block-pod-exec-by-namespace/block-pod-exec-by-namespace.md index ff85a64e1..7682de3b1 100644 --- a/content/en/policies/other/block-pod-exec-by-namespace/block-pod-exec-by-namespace.md +++ b/content/en/policies/other/block-pod-exec-by-namespace/block-pod-exec-by-namespace.md @@ -26,7 +26,7 @@ metadata: be useful for troubleshooting purposes, it could represent an attack vector and is discouraged. This policy blocks Pod exec commands to Pods in a Namespace called `pci`. spec: - validationFailureAction: enforce + validationFailureAction: Enforce background: false rules: - name: deny-exec-ns-pci diff --git a/content/en/policies/other/block-pod-exec-by-pod-and-container/block-pod-exec-by-pod-and-container.md b/content/en/policies/other/block-pod-exec-by-pod-and-container/block-pod-exec-by-pod-and-container.md index f0ec46aba..782b4e9c8 100644 --- a/content/en/policies/other/block-pod-exec-by-pod-and-container/block-pod-exec-by-pod-and-container.md +++ b/content/en/policies/other/block-pod-exec-by-pod-and-container/block-pod-exec-by-pod-and-container.md @@ -27,7 +27,7 @@ metadata: This policy blocks Pod exec commands to containers named `nginx` in Pods starting with name `myapp-maintenance`. spec: - validationFailureAction: enforce + validationFailureAction: Enforce background: false rules: - name: deny-nginx-exec-in-myapp-maintenance diff --git a/content/en/policies/other/block-pod-exec-by-pod-label/block-pod-exec-by-pod-label.md b/content/en/policies/other/block-pod-exec-by-pod-label/block-pod-exec-by-pod-label.md index 33c04a306..8fb2ed602 100644 --- a/content/en/policies/other/block-pod-exec-by-pod-label/block-pod-exec-by-pod-label.md +++ b/content/en/policies/other/block-pod-exec-by-pod-label/block-pod-exec-by-pod-label.md @@ -26,7 +26,7 @@ metadata: be useful for troubleshooting purposes, it could represent an attack vector and is discouraged. This policy blocks Pod exec commands to Pods having the label `exec=false`. spec: - validationFailureAction: enforce + validationFailureAction: Enforce background: false rules: - name: deny-exec-by-label diff --git a/content/en/policies/other/block-pod-exec-by-pod-name/block-pod-exec-by-pod-name.md b/content/en/policies/other/block-pod-exec-by-pod-name/block-pod-exec-by-pod-name.md index a5f9afb28..61b3050a2 100644 --- a/content/en/policies/other/block-pod-exec-by-pod-name/block-pod-exec-by-pod-name.md +++ b/content/en/policies/other/block-pod-exec-by-pod-name/block-pod-exec-by-pod-name.md @@ -27,7 +27,7 @@ metadata: This policy blocks Pod exec commands to Pods beginning with the name `myapp-maintenance-`. spec: - validationFailureAction: enforce + validationFailureAction: Enforce background: false rules: - name: deny-exec-myapp-maintenance diff --git a/content/en/policies/other/block-stale-images/block-stale-images.md b/content/en/policies/other/block-stale-images/block-stale-images.md index 5d1c3607e..074fb18ab 100644 --- a/content/en/policies/other/block-stale-images/block-stale-images.md +++ b/content/en/policies/other/block-stale-images/block-stale-images.md @@ -29,7 +29,7 @@ metadata: This policy checks the contents of every container image and inspects them for the create time. If it finds any image which was built more than 6 months ago this policy blocks the deployment. spec: - validationFailureAction: audit + validationFailureAction: Audit rules: - name: block-stale-images match: diff --git a/content/en/policies/other/block-updates-deletes/block-updates-deletes.md b/content/en/policies/other/block-updates-deletes/block-updates-deletes.md index 2a2ed55f1..69a6f7a67 100644 --- a/content/en/policies/other/block-updates-deletes/block-updates-deletes.md +++ b/content/en/policies/other/block-updates-deletes/block-updates-deletes.md @@ -27,7 +27,7 @@ metadata: Service resource that contains the label `protected=true` unless by a cluster-admin. spec: - validationFailureAction: enforce + validationFailureAction: Enforce background: false rules: - name: block-updates-deletes diff --git a/content/en/policies/other/check-env-vars/check-env-vars.md b/content/en/policies/other/check-env-vars/check-env-vars.md index e4a18e6ea..39c28eac0 100644 --- a/content/en/policies/other/check-env-vars/check-env-vars.md +++ b/content/en/policies/other/check-env-vars/check-env-vars.md @@ -31,7 +31,7 @@ metadata: `DISABLE_OPA` environment variable is defined, it must not be set to a value of `"true"`. spec: background: true - validationFailureAction: audit + validationFailureAction: Audit rules: - name: check-disable-opa match: diff --git a/content/en/policies/other/check-hpa-exists/check-hpa-exists.md b/content/en/policies/other/check-hpa-exists/check-hpa-exists.md new file mode 100644 index 000000000..2b2a22f6e --- /dev/null +++ b/content/en/policies/other/check-hpa-exists/check-hpa-exists.md @@ -0,0 +1,60 @@ +--- +title: "Ensure HPA for Deployments" +category: Other +version: 1.9.0 +subject: Deployment,ReplicaSet,StatefulSet,DaemonSet +policyType: "validate" +description: > + This policy ensures that Deployments, ReplicaSets, StatefulSets, and DaemonSets are only allowed if they have a corresponding Horizontal Pod Autoscaler (HPA) configured in the same namespace. The policy checks for the presence of an HPA that targets the resource and denies the creation or update of the resource if no such HPA exists. This policy helps enforce scaling practices and ensures that resources are managed efficiently. +--- + +## Policy Definition +/other/check-hpa-exists/check-hpa-exists.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: check-hpa-exists + annotations: + policies.kyverno.io/title: Ensure HPA for Deployments + policies.kyverno.io/category: Other + policies.kyverno.io/severity: medium + kyverno.io/kyverno-version: 1.11.0 + policies.kyverno.io/minversion: 1.9.0 + kyverno.io/kubernetes-version: "1.28" + policies.kyverno.io/subject: Deployment,ReplicaSet,StatefulSet,DaemonSet + policies.kyverno.io/description: >- + This policy ensures that Deployments, ReplicaSets, StatefulSets, and DaemonSets are only allowed + if they have a corresponding Horizontal Pod Autoscaler (HPA) configured in the same namespace. + The policy checks for the presence of an HPA that targets the resource and denies the creation or update + of the resource if no such HPA exists. This policy helps enforce scaling practices + and ensures that resources are managed efficiently. +spec: + validationFailureAction: Audit + background: true + rules: + - name: validate-hpa + match: + any: + - resources: + kinds: + - Deployment + - ReplicaSet + - StatefulSet + - DaemonSet + context: + - name: hpas + apiCall: + urlPath: "/apis/autoscaling/v1/namespaces/{{ request.namespace }}/horizontalpodautoscalers" + jmesPath: "items[].spec.scaleTargetRef.name" + validate: + message: "Deployment is not allowed without a corresponding HPA." + deny: + conditions: + all: + - key: "{{ request.object.metadata.name }}" + operator: AnyNotIn + value: "{{ hpas }}" + +``` diff --git a/content/en/policies/other/check-ingress-nginx-controller-version-and-annotation-policy/check-ingress-nginx-controller-version-and-annotation-policy.md b/content/en/policies/other/check-ingress-nginx-controller-version-and-annotation-policy/check-ingress-nginx-controller-version-and-annotation-policy.md new file mode 100644 index 000000000..819eb1037 --- /dev/null +++ b/content/en/policies/other/check-ingress-nginx-controller-version-and-annotation-policy/check-ingress-nginx-controller-version-and-annotation-policy.md @@ -0,0 +1,103 @@ +--- +title: "Ensure Valid Ingress NGINX Controller and Annotations" +category: Ingress, Security +version: 1.9.0 +subject: Ingress, Pod +policyType: "validate" +description: > + This policy ensures that Ingress resources do not have certain disallowed annotations and that the ingress-nginx controller Pod is running an appropriate version of the image. It checks for the presence of the `nginx.ingress.kubernetes.io/server-snippet` annotation and disallows its usage, enforces specific values for `auth-tls-verify-client`, and ensures that the ingress-nginx controller image is of the required version. +--- + +## Policy Definition +/other/check-ingress-nginx-controller-version-and-annotation-policy/check-ingress-nginx-controller-version-and-annotation-policy.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: check-ingress-nginx-controller-version-and-annotation-policy + annotations: + policies.kyverno.io/title: Ensure Valid Ingress NGINX Controller and Annotations + policies.kyverno.io/category: Ingress, Security + policies.kyverno.io/severity: high + kyverno.io/kyverno-version: 1.11.0 + policies.kyverno.io/minversion: 1.9.0 + kyverno.io/kubernetes-version: "1.28" + policies.kyverno.io/subject: Ingress, Pod + policies.kyverno.io/description: >- + This policy ensures that Ingress resources do not have certain disallowed annotations and that the ingress-nginx + controller Pod is running an appropriate version of the image. It checks for the presence of the + `nginx.ingress.kubernetes.io/server-snippet` annotation and disallows its usage, enforces specific values + for `auth-tls-verify-client`, and ensures that the ingress-nginx controller image is of the required version. +spec: + validationFailureAction: Audit + background: true + rules: + - name: validate-ingress-annotations + match: + resources: + kinds: + - Ingress + validate: + message: "The annotation nginx.ingress.kubernetes.io/server-snippet is not allowed." + pattern: + metadata: + annotations: + X(nginx.ingress.kubernetes.io/server-snippet): "" + - name: validate-auth-tls-verify-client + match: + resources: + kinds: + - Ingress + validate: + message: "auth-tls-verify-client annotation must be 'on', 'off', 'optional', or 'optional_no_ca'." + deny: + conditions: + any: + - key: "{{request.object.metadata.annotations.\"nginx.ingress.kubernetes.io/auth-tls-verify-client\"}}" + operator: AnyNotIn + value: + - "on" + - "off" + - "optional" + - "optional_no_ca" + - name: ensure-ingress-nginx-controller-version-pattern + match: + resources: + kinds: + - Pod + validate: + message: "The ingress-nginx controller image version must start with v1.11." + pattern: + spec: + containers: + - name: controller + image: "registry.k8s.io/ingress-nginx/controller:v1.11.*" + + - name: deny-lower-ingress-nginx-controller-versions + match: + resources: + kinds: + - Pod + validate: + message: "The ingress-nginx controller image version must be v1.11.2 or greater." + deny: + conditions: + - key: "{{ request.object.spec.containers[?(@.name=='controller')].image }}" + operator: AnyIn + value: + - "registry.k8s.io/ingress-nginx/controller:v1.11.0" + - "registry.k8s.io/ingress-nginx/controller:v1.11.1" + - "registry.k8s.io/ingress-nginx/controller:v1.10.*" + - "registry.k8s.io/ingress-nginx/controller:v1.9.*" + - "registry.k8s.io/ingress-nginx/controller:v1.8.*" + - "registry.k8s.io/ingress-nginx/controller:v1.7.*" + - "registry.k8s.io/ingress-nginx/controller:v1.6.*" + - "registry.k8s.io/ingress-nginx/controller:v1.5.*" + - "registry.k8s.io/ingress-nginx/controller:v1.4.*" + - "registry.k8s.io/ingress-nginx/controller:v1.3.*" + - "registry.k8s.io/ingress-nginx/controller:v1.2.*" + - "registry.k8s.io/ingress-nginx/controller:v1.1.*" + - "registry.k8s.io/ingress-nginx/controller:v1.0.*" + +``` diff --git a/content/en/policies/other/check-node-for-cve-2022-0185/check-node-for-cve-2022-0185.md b/content/en/policies/other/check-node-for-cve-2022-0185/check-node-for-cve-2022-0185.md index e0061e053..9a890b806 100644 --- a/content/en/policies/other/check-node-for-cve-2022-0185/check-node-for-cve-2022-0185.md +++ b/content/en/policies/other/check-node-for-cve-2022-0185/check-node-for-cve-2022-0185.md @@ -31,7 +31,7 @@ metadata: This policy runs in background mode and flags an entry in the ClusterPolicyReport if any Node is reporting one of the affected kernel versions. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: kernel-validate diff --git a/content/en/policies/other/check-nvidia-gpu/check-nvidia-gpu.md b/content/en/policies/other/check-nvidia-gpu/check-nvidia-gpu.md index 2576277e6..7000dcf88 100644 --- a/content/en/policies/other/check-nvidia-gpu/check-nvidia-gpu.md +++ b/content/en/policies/other/check-nvidia-gpu/check-nvidia-gpu.md @@ -31,7 +31,7 @@ metadata: request a GPU to ensure they have been authored with this environment variable. spec: - validationFailureAction: audit + validationFailureAction: Audit rules: - name: check-nvidia-gpus match: diff --git a/content/en/policies/other/check-serviceaccount/check-serviceaccount.md b/content/en/policies/other/check-serviceaccount/check-serviceaccount.md index 37a4627b6..29c08084a 100644 --- a/content/en/policies/other/check-serviceaccount/check-serviceaccount.md +++ b/content/en/policies/other/check-serviceaccount/check-serviceaccount.md @@ -29,7 +29,7 @@ metadata: Pod, if created by a ServiceAccount, and ensures the `serviceAccountName` field matches the actual ServiceAccount. spec: - validationFailureAction: audit + validationFailureAction: Audit background: false rules: - name: check-sa diff --git a/content/en/policies/other/disallow-all-secrets/disallow-all-secrets.md b/content/en/policies/other/disallow-all-secrets/disallow-all-secrets.md index 839683c4b..7eba48bb9 100644 --- a/content/en/policies/other/disallow-all-secrets/disallow-all-secrets.md +++ b/content/en/policies/other/disallow-all-secrets/disallow-all-secrets.md @@ -30,7 +30,7 @@ metadata: this Policy needs a separate Policy or rule to require `automountServiceAccountToken=false` at the Pod level or ServiceAccount level since this would otherwise result in a Secret being mounted. spec: - validationFailureAction: audit + validationFailureAction: Audit rules: - name: secrets-not-from-env match: diff --git a/content/en/policies/other/disallow-localhost-services/disallow-localhost-services.md b/content/en/policies/other/disallow-localhost-services/disallow-localhost-services.md index a61366b01..3c79c7f40 100644 --- a/content/en/policies/other/disallow-localhost-services/disallow-localhost-services.md +++ b/content/en/policies/other/disallow-localhost-services/disallow-localhost-services.md @@ -27,7 +27,7 @@ metadata: vulnerabilities in some Ingress controllers. This policy audits Services of type ExternalName if the externalName field refers to localhost. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: no-localhost-service diff --git a/content/en/policies/other/disallow-secrets-from-env-vars/disallow-secrets-from-env-vars.md b/content/en/policies/other/disallow-secrets-from-env-vars/disallow-secrets-from-env-vars.md index 05b6ad042..368b4021f 100644 --- a/content/en/policies/other/disallow-secrets-from-env-vars/disallow-secrets-from-env-vars.md +++ b/content/en/policies/other/disallow-secrets-from-env-vars/disallow-secrets-from-env-vars.md @@ -27,7 +27,7 @@ metadata: be printed in log output which could be visible to unauthorized people and captured in forwarding applications. This policy disallows using Secrets as environment variables. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: secrets-not-from-env-vars diff --git a/content/en/policies/other/docker-socket-requires-label/docker-socket-requires-label.md b/content/en/policies/other/docker-socket-requires-label/docker-socket-requires-label.md index 1a848ff64..d4b04cad4 100644 --- a/content/en/policies/other/docker-socket-requires-label/docker-socket-requires-label.md +++ b/content/en/policies/other/docker-socket-requires-label/docker-socket-requires-label.md @@ -29,7 +29,7 @@ metadata: requires that, for any Pod mounting the Docker socket, it must have the label `allow-docker` set to `true`. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: conditional-anchor-dockersock diff --git a/content/en/policies/other/enforce-pod-duration/enforce-pod-duration.md b/content/en/policies/other/enforce-pod-duration/enforce-pod-duration.md index 7ff350bb8..5e1793ecb 100644 --- a/content/en/policies/other/enforce-pod-duration/enforce-pod-duration.md +++ b/content/en/policies/other/enforce-pod-duration/enforce-pod-duration.md @@ -26,7 +26,7 @@ metadata: such as to ensure a Pod lifetime annotation does not exceed some site specific max threshold. Pod lifetime annotation can be no greater than 8 hours. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: pods-lifetime diff --git a/content/en/policies/other/enforce-resources-as-ratio/enforce-resources-as-ratio.md b/content/en/policies/other/enforce-resources-as-ratio/enforce-resources-as-ratio.md index 3f7a22675..98477b560 100644 --- a/content/en/policies/other/enforce-resources-as-ratio/enforce-resources-as-ratio.md +++ b/content/en/policies/other/enforce-resources-as-ratio/enforce-resources-as-ratio.md @@ -30,7 +30,7 @@ metadata: or limits may not work and a ratio may be better suited instead. This policy checks every container in a Pod and ensures that memory limits are no more than 2.5x its requests. spec: - validationFailureAction: audit + validationFailureAction: Audit rules: - name: check-memory-requests-limits match: diff --git a/content/en/policies/other/ensure-probes-different/ensure-probes-different.md b/content/en/policies/other/ensure-probes-different/ensure-probes-different.md index fd5b02628..32a868e93 100644 --- a/content/en/policies/other/ensure-probes-different/ensure-probes-different.md +++ b/content/en/policies/other/ensure-probes-different/ensure-probes-different.md @@ -29,7 +29,7 @@ metadata: checks that liveness and readiness probes are not equal. Keep in mind that if both the probes are not set, they are considered to be equal and hence fails the check. spec: - validationFailureAction: audit + validationFailureAction: Audit background: false rules: - name: validate-probes diff --git a/content/en/policies/other/ensure-production-matches-staging/ensure-production-matches-staging.md b/content/en/policies/other/ensure-production-matches-staging/ensure-production-matches-staging.md index c193ab1f9..350b8e2a3 100644 --- a/content/en/policies/other/ensure-production-matches-staging/ensure-production-matches-staging.md +++ b/content/en/policies/other/ensure-production-matches-staging/ensure-production-matches-staging.md @@ -33,7 +33,7 @@ metadata: that a production Deployment uses same image name as its staging counterpart. Third, that a production Deployment uses an older or equal image version as its staging counterpart. spec: - validationFailureAction: enforce + validationFailureAction: Enforce background: true rules: ####################### diff --git a/content/en/policies/other/ensure-readonly-hostpath/ensure-readonly-hostpath.md b/content/en/policies/other/ensure-readonly-hostpath/ensure-readonly-hostpath.md index faf743f6c..b63eedc66 100644 --- a/content/en/policies/other/ensure-readonly-hostpath/ensure-readonly-hostpath.md +++ b/content/en/policies/other/ensure-readonly-hostpath/ensure-readonly-hostpath.md @@ -33,7 +33,7 @@ metadata: explicitly mounted in readOnly mode. spec: background: false - validationFailureAction: audit + validationFailureAction: Audit rules: - name: ensure-hostpaths-readonly match: diff --git a/content/en/policies/other/exclude-namespaces-dynamically/exclude-namespaces-dynamically.md b/content/en/policies/other/exclude-namespaces-dynamically/exclude-namespaces-dynamically.md index df58f0c29..6a72067e5 100644 --- a/content/en/policies/other/exclude-namespaces-dynamically/exclude-namespaces-dynamically.md +++ b/content/en/policies/other/exclude-namespaces-dynamically/exclude-namespaces-dynamically.md @@ -31,7 +31,7 @@ metadata: where the ConfigMap stores an array of strings. This policy validates that any Pods created outside of the list of Namespaces have the label `foo` applied. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: exclude-namespaces-dynamically diff --git a/content/en/policies/other/generate-networkpolicy-existing/generate-networkpolicy-existing.md b/content/en/policies/other/generate-networkpolicy-existing/generate-networkpolicy-existing.md index fd0fa3913..8410ea4a2 100644 --- a/content/en/policies/other/generate-networkpolicy-existing/generate-networkpolicy-existing.md +++ b/content/en/policies/other/generate-networkpolicy-existing/generate-networkpolicy-existing.md @@ -31,6 +31,7 @@ metadata: is additional overhead. This policy creates a new NetworkPolicy for existing Namespaces which results in a default deny behavior and labels it with created-by=kyverno. spec: + generateExisting: true rules: - name: generate-existing-networkpolicy match: @@ -39,7 +40,6 @@ spec: kinds: - Namespace generate: - generateExisting: true kind: NetworkPolicy apiVersion: networking.k8s.io/v1 name: default-deny diff --git a/content/en/policies/other/get-debug-information/get-debug-information.md b/content/en/policies/other/get-debug-information/get-debug-information.md new file mode 100644 index 000000000..25f6a547e --- /dev/null +++ b/content/en/policies/other/get-debug-information/get-debug-information.md @@ -0,0 +1,99 @@ +--- +title: "Collect Debug Information for Pods in CrashLoopBackOff" +category: Other +version: +subject: Pod +policyType: "generate" +description: > + This policy generates a job which gathers troubleshooting data (including logs, kubectl describe output and events from the namespace) from pods that are in CrashLoopBackOff and have 3 restarts. This data can further be used to automatically create a Jira issue using some kind of automation or another Kyverno policy. For more information on the image used in this policy in addition to the necessary RBAC resources required in order for this policy to operate, see the documentation at https://github.com/nirmata/SRE-Operational-Usecases/tree/main/get-troubleshooting-data/get-debug-data. +--- + +## Policy Definition +/other/get-debug-information/get-debug-information.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: get-debug-data-policy + annotations: + policies.kyverno.io/title: Collect Debug Information for Pods in CrashLoopBackOff + policies.kyverno.io/category: Other + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + kyverno.io/kyverno-version: 1.11.5 + kyverno.io/kubernetes-version: "1.27" + policies.kyverno.io/description: >- + This policy generates a job which gathers troubleshooting data (including logs, kubectl describe output and events from the namespace) from pods that are in CrashLoopBackOff and have 3 restarts. This data can further be used to automatically create a Jira issue using some kind of automation or another Kyverno policy. For more information on the image used in this policy in addition to the necessary RBAC resources required in order for this policy to operate, see the documentation at https://github.com/nirmata/SRE-Operational-Usecases/tree/main/get-troubleshooting-data/get-debug-data. +spec: + rules: + - name: get-debug-data-policy-rule + match: + any: + - resources: + kinds: + - v1/Pod.status + context: + - name: pdcount + apiCall: + urlPath: "/api/v1/namespaces/{{request.namespace}}/pods?labelSelector=requestpdname=pod-{{request.object.metadata.name}}" + jmesPath: "items | length(@)" + preconditions: + all: + - key: "{{ sum(request.object.status.containerStatuses[*].restartCount || `0`) }}" + operator: Equals + value: 3 + - key: "{{ request.object.metadata.labels.deleteme || 'empty' }}" + operator: Equals + value: "empty" + - key: "{{ pdcount }}" + operator: Equals + value: 0 + generate: + apiVersion: batch/v1 + kind: Job + name: get-debug-data-{{request.object.metadata.name}}-{{ random('[0-9a-z]{8}') }} + namespace: "{{request.namespace}}" + synchronize: false + data: + metadata: + labels: + deleteme: allow + spec: + template: + metadata: + labels: + app: my-app + deleteme: allow + requestpdname: "pod-{{request.object.metadata.name}}" + spec: + restartPolicy: OnFailure + containers: + - name: my-container + image: sagarkundral/my-python-app:v52 + ports: + - containerPort: 8080 + volumeMounts: + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: token + readOnly: true + args: + - "/app/get-debug-jira-v2.sh" + - "{{request.namespace}}" + - "{{request.object.metadata.name}}" + serviceAccount: default # This serviceaccount needs the necessary RBAC in order for the policy to operate. + volumes: + - name: token + projected: + defaultMode: 420 + sources: + - serviceAccountToken: + expirationSeconds: 3607 + path: token + - configMap: + items: + - key: ca.crt + path: ca.crt + name: kube-root-ca.crt + +``` diff --git a/content/en/policies/other/imagepullpolicy-always/imagepullpolicy-always.md b/content/en/policies/other/imagepullpolicy-always/imagepullpolicy-always.md index 20d247054..5428632a6 100644 --- a/content/en/policies/other/imagepullpolicy-always/imagepullpolicy-always.md +++ b/content/en/policies/other/imagepullpolicy-always/imagepullpolicy-always.md @@ -28,7 +28,7 @@ metadata: pulls will get the updated image. This policy validates the imagePullPolicy is set to `Always` when the `latest` tag is specified explicitly or where a tag is not defined at all. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: imagepullpolicy-always diff --git a/content/en/policies/other/ingress-host-match-tls/ingress-host-match-tls.md b/content/en/policies/other/ingress-host-match-tls/ingress-host-match-tls.md index 868db4350..8dc6368f3 100644 --- a/content/en/policies/other/ingress-host-match-tls/ingress-host-match-tls.md +++ b/content/en/policies/other/ingress-host-match-tls/ingress-host-match-tls.md @@ -32,7 +32,7 @@ metadata: in the list of TLS hosts. spec: background: false - validationFailureAction: audit + validationFailureAction: Audit rules: - name: host-match-tls match: diff --git a/content/en/policies/other/limit-configmap-for-sa/limit-configmap-for-sa.md b/content/en/policies/other/limit-configmap-for-sa/limit-configmap-for-sa.md index ff56cbcb5..9dc8d0669 100644 --- a/content/en/policies/other/limit-configmap-for-sa/limit-configmap-for-sa.md +++ b/content/en/policies/other/limit-configmap-for-sa/limit-configmap-for-sa.md @@ -26,7 +26,7 @@ metadata: policies.kyverno.io/description: This policy shows how to restrict certain operations on specific ConfigMaps by ServiceAccounts. spec: background: false - validationFailureAction: audit + validationFailureAction: Audit rules: - name: limit-configmap-for-sa-developer match: diff --git a/content/en/policies/other/limit-containers-per-pod/limit-containers-per-pod.md b/content/en/policies/other/limit-containers-per-pod/limit-containers-per-pod.md index e7417e2a0..cccabf96d 100644 --- a/content/en/policies/other/limit-containers-per-pod/limit-containers-per-pod.md +++ b/content/en/policies/other/limit-containers-per-pod/limit-containers-per-pod.md @@ -28,7 +28,7 @@ metadata: be applied consistently. This policy checks all Pods to ensure they have no more than four containers. spec: - validationFailureAction: audit + validationFailureAction: Audit background: false rules: - name: limit-containers-per-pod diff --git a/content/en/policies/other/limit-hostpath-type-pv/limit-hostpath-type-pv.md b/content/en/policies/other/limit-hostpath-type-pv/limit-hostpath-type-pv.md index e1051d03e..de81f1831 100644 --- a/content/en/policies/other/limit-hostpath-type-pv/limit-hostpath-type-pv.md +++ b/content/en/policies/other/limit-hostpath-type-pv/limit-hostpath-type-pv.md @@ -29,7 +29,7 @@ metadata: the only directory that can be mounted as a hostPath volume is /data. spec: background: false - validationFailureAction: audit + validationFailureAction: Audit rules: - name: limit-hostpath-type-pv-to-slash-data match: diff --git a/content/en/policies/other/limit-hostpath-vols/limit-hostpath-vols.md b/content/en/policies/other/limit-hostpath-vols/limit-hostpath-vols.md index 4c5573f57..b5bfa248f 100644 --- a/content/en/policies/other/limit-hostpath-vols/limit-hostpath-vols.md +++ b/content/en/policies/other/limit-hostpath-vols/limit-hostpath-vols.md @@ -33,7 +33,7 @@ metadata: access is enforced preventing directory escape. spec: background: false - validationFailureAction: audit + validationFailureAction: Audit rules: - name: limit-hostpath-to-slash-data match: diff --git a/content/en/policies/other/memory-requests-equal-limits/memory-requests-equal-limits.md b/content/en/policies/other/memory-requests-equal-limits/memory-requests-equal-limits.md index fec6aaa1f..eb668b4ba 100644 --- a/content/en/policies/other/memory-requests-equal-limits/memory-requests-equal-limits.md +++ b/content/en/policies/other/memory-requests-equal-limits/memory-requests-equal-limits.md @@ -27,7 +27,7 @@ metadata: they also set CPU limits equal to requests. Guaranteed is the highest schedulable class. This policy checks that all containers in a given Pod have memory requests equal to limits. spec: - validationFailureAction: audit + validationFailureAction: Audit background: false rules: - name: memory-requests-equal-limits diff --git a/content/en/policies/other/metadata-match-regex/metadata-match-regex.md b/content/en/policies/other/metadata-match-regex/metadata-match-regex.md index 4fa21cde3..62a407316 100644 --- a/content/en/policies/other/metadata-match-regex/metadata-match-regex.md +++ b/content/en/policies/other/metadata-match-regex/metadata-match-regex.md @@ -27,7 +27,7 @@ metadata: policy illustrates how to ensure a label with key `corp.org/version` is both present and matches a given regex, in this case ensuring semver is met. spec: - validationFailureAction: audit + validationFailureAction: Audit background: false rules: - name: check-for-regex diff --git a/content/en/policies/other/mitigate-log4shell/mitigate-log4shell.md b/content/en/policies/other/mitigate-log4shell/mitigate-log4shell.md index 48f07a6c9..ee4153b85 100644 --- a/content/en/policies/other/mitigate-log4shell/mitigate-log4shell.md +++ b/content/en/policies/other/mitigate-log4shell/mitigate-log4shell.md @@ -5,7 +5,7 @@ version: 1.6.0 subject: Pod policyType: "mutate" description: > - In response to CVE-2021-44228 referred to as Log4Shell, a RCE vulnerability in the Log4j library, a partial yet incomplete workaround for versions 2.10 to 2.14.1 of the library is to set the environment variable LOG4J_FORMAT_MSG_NO_LOOKUPS to "true". While this does provide some benefit by limiting exposure, there are still code paths which can exploit this vulnerability. It is highly recommended to upgrade log4j as soon as possible. See https://logging.apache.org/security.html for more details. This policy will mutate all initContainers and containers in an incoming Pod to add this environment variable automatically. + In response to CVE-2021-44228 referred to as Log4Shell, a RCE vulnerability in the Log4j library, a partial yet incomplete workaround for versions 2.10 to 2.14.1 of the library is to set the environment variable LOG4J_FORMAT_MSG_NO_LOOKUPS to "true". While this does provide some benefit by limiting exposure, there are still code paths which can exploit this vulnerability. It is highly recommended to upgrade log4j as soon as possible. See https://logging.apache.org/log4j/2.x/security.html for more details. This policy will mutate all initContainers and containers in an incoming Pod to add this environment variable automatically. --- ## Policy Definition @@ -29,7 +29,7 @@ metadata: variable LOG4J_FORMAT_MSG_NO_LOOKUPS to "true". While this does provide some benefit by limiting exposure, there are still code paths which can exploit this vulnerability. It is highly recommended to upgrade log4j as soon as possible. - See https://logging.apache.org/security.html for more details. + See https://logging.apache.org/log4j/2.x/security.html for more details. This policy will mutate all initContainers and containers in an incoming Pod to add this environment variable automatically. spec: diff --git a/content/en/policies/other/nfs-subdir-external-provisioner-storage-path/nfs-subdir-external-provisioner-storage-path.md b/content/en/policies/other/nfs-subdir-external-provisioner-storage-path/nfs-subdir-external-provisioner-storage-path.md index 9ccd0b336..702d1d406 100644 --- a/content/en/policies/other/nfs-subdir-external-provisioner-storage-path/nfs-subdir-external-provisioner-storage-path.md +++ b/content/en/policies/other/nfs-subdir-external-provisioner-storage-path/nfs-subdir-external-provisioner-storage-path.md @@ -32,7 +32,7 @@ metadata: annotation that it cannot be empty, which may otherwise result in it consuming the root of the designated path. spec: background: false - validationFailureAction: audit + validationFailureAction: Audit rules: - name: enforce-storage-path match: diff --git a/content/en/policies/other/only-trustworthy-registries-set-root/only-trustworthy-registries-set-root.md b/content/en/policies/other/only-trustworthy-registries-set-root/only-trustworthy-registries-set-root.md index 8924dd77e..81ba425e2 100644 --- a/content/en/policies/other/only-trustworthy-registries-set-root/only-trustworthy-registries-set-root.md +++ b/content/en/policies/other/only-trustworthy-registries-set-root/only-trustworthy-registries-set-root.md @@ -30,7 +30,7 @@ metadata: This policy blocks any image that runs as root if it does not come from a trustworthy registry, `ghcr.io` in this case. spec: - validationFailureAction: audit + validationFailureAction: Audit rules: - name: only-allow-trusted-images match: diff --git a/content/en/policies/other/pdb-maxunavailable/pdb-maxunavailable.md b/content/en/policies/other/pdb-maxunavailable/pdb-maxunavailable.md index a45ad7bbe..33c65419c 100644 --- a/content/en/policies/other/pdb-maxunavailable/pdb-maxunavailable.md +++ b/content/en/policies/other/pdb-maxunavailable/pdb-maxunavailable.md @@ -28,7 +28,7 @@ metadata: This policy enforces that if a PodDisruptionBudget specifies the maxUnavailable field it must be greater than zero. spec: - validationFailureAction: audit + validationFailureAction: Audit background: false rules: - name: pdb-maxunavailable diff --git a/content/en/policies/other/pdb-minavailable/pdb-minavailable.md b/content/en/policies/other/pdb-minavailable/pdb-minavailable.md index 05d659d46..69143e920 100644 --- a/content/en/policies/other/pdb-minavailable/pdb-minavailable.md +++ b/content/en/policies/other/pdb-minavailable/pdb-minavailable.md @@ -29,7 +29,7 @@ metadata: tasks and disrupt operations. This policy checks incoming Deployments and StatefulSets which have a matching PodDisruptionBudget to ensure these two values do not match. spec: - validationFailureAction: audit + validationFailureAction: Audit background: false rules: - name: pdb-minavailable diff --git a/content/en/policies/other/prevent-bare-pods/prevent-bare-pods.md b/content/en/policies/other/prevent-bare-pods/prevent-bare-pods.md index c95e06ac5..3e7f728e2 100644 --- a/content/en/policies/other/prevent-bare-pods/prevent-bare-pods.md +++ b/content/en/policies/other/prevent-bare-pods/prevent-bare-pods.md @@ -31,7 +31,7 @@ metadata: This policy prevents such "bare" Pods from being created unless they originate from a higher-level workload controller of some sort. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: bare-pods diff --git a/content/en/policies/other/prevent-cr8escape/prevent-cr8escape.md b/content/en/policies/other/prevent-cr8escape/prevent-cr8escape.md index 4d47a99a7..85dc739ee 100644 --- a/content/en/policies/other/prevent-cr8escape/prevent-cr8escape.md +++ b/content/en/policies/other/prevent-cr8escape/prevent-cr8escape.md @@ -30,7 +30,7 @@ metadata: and gain root access to the host. The recommended remediation is to disallow sysctl settings with + or = in their value. spec: - validationFailureAction: enforce + validationFailureAction: Enforce background: true rules: - name: restrict-sysctls-cr8escape @@ -40,10 +40,11 @@ spec: kinds: - Pod validate: - message: "characters '+' or '=' are not allowed in sysctls values" + message: "characters '+' or '=' are not allowed in sysctls values" pattern: spec: =(securityContext): =(sysctls): - =(value): "!*+* & !*=*" + ``` diff --git a/content/en/policies/other/prevent-duplicate-hpa/prevent-duplicate-hpa.md b/content/en/policies/other/prevent-duplicate-hpa/prevent-duplicate-hpa.md new file mode 100644 index 000000000..3cc9c6902 --- /dev/null +++ b/content/en/policies/other/prevent-duplicate-hpa/prevent-duplicate-hpa.md @@ -0,0 +1,86 @@ +--- +title: "Prevent Duplicate HorizontalPodAutoscalers" +category: Other +version: +subject: HorizontalPodAutoscaler +policyType: "validate" +description: > + HorizontalPodAutoscaler (HPA) is useful to automatically adjust the number of pods in a deployment or replication controller. It requires defining a specific target resource by kind and name. There are no built-in validation checks by the HPA controller to prevent the creation of multiple HPAs which target the same resource. This policy has two rules, the first of which ensures that the only targetRef kinds accepted are one of either Deployment, StatefulSet, ReplicaSet, or DaemonSet. The second prevents the creation of duplicate HPAs by validating that any new HPA targets a unique resource. +--- + +## Policy Definition +/other/prevent-duplicate-hpa/prevent-duplicate-hpa.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: prevent-duplicate-hpa + annotations: + policies.kyverno.io/title: Prevent Duplicate HorizontalPodAutoscalers + policies.kyverno.io/category: Other + policies.kyverno.io/severity: medium + kyverno.io/kyverno-version: 1.11.4 + kyverno.io/kubernetes-version: "1.27" + policies.kyverno.io/subject: HorizontalPodAutoscaler + policies.kyverno.io/description: >- + HorizontalPodAutoscaler (HPA) is useful to automatically adjust the number of pods in a deployment + or replication controller. It requires defining a specific target resource by kind and name. + There are no built-in validation checks by the HPA controller to prevent the creation of multiple HPAs + which target the same resource. This policy has two rules, the first of which ensures that the only targetRef + kinds accepted are one of either Deployment, StatefulSet, ReplicaSet, or DaemonSet. The second + prevents the creation of duplicate HPAs by validating that any new HPA targets a unique resource. +spec: + validationFailureAction: Audit + background: false + rules: + - name: verify-kind-name-duplicates + match: + any: + - resources: + kinds: + - HorizontalPodAutoscaler + operations: + - CREATE + validate: + message: >- + The target kind must be specified exactly as Deployment, StatefulSet, ReplicaSet, or DaemonSet. + pattern: + spec: + scaleTargetRef: + kind: Deployment | StatefulSet | ReplicaSet | DaemonSet + - name: check-targetref-duplicates + match: + any: + - resources: + kinds: + - HorizontalPodAutoscaler + operations: + - CREATE + preconditions: + all: + - key: + - Deployment + - StatefulSet + - ReplicaSet + - DaemonSet + operator: AnyIn + value: "{{ request.object.spec.scaleTargetRef.kind }}" + context: + - name: targets + apiCall: + urlPath: "/apis/autoscaling/v1/namespaces/{{ request.namespace }}/horizontalpodautoscalers" + jmesPath: "items[?spec.scaleTargetRef.kind=='{{ request.object.spec.scaleTargetRef.kind }}'].spec.scaleTargetRef.name" + validate: + message: >- + The target {{ request.object.spec.scaleTargetRef.kind }} named + {{ request.object.spec.scaleTargetRef.name }} already has an existing + HPA configured for it. Duplicate HPAs are not allowed. + deny: + conditions: + all: + - key: "{{ request.object.spec.scaleTargetRef.name }}" + operator: AnyIn + value: "{{ targets }}" + +``` diff --git a/content/en/policies/other/protect-node-taints/protect-node-taints.md b/content/en/policies/other/protect-node-taints/protect-node-taints.md index 414480cdc..680cf04f9 100644 --- a/content/en/policies/other/protect-node-taints/protect-node-taints.md +++ b/content/en/policies/other/protect-node-taints/protect-node-taints.md @@ -31,7 +31,7 @@ metadata: requires, at minimum, one of the following versions of Kubernetes: v1.18.18, v1.19.10, v1.20.6, or v1.21.0. spec: - validationFailureAction: enforce + validationFailureAction: Enforce background: false rules: - name: protect-node-taints diff --git a/content/en/policies/other/record-creation-details/record-creation-details.md b/content/en/policies/other/record-creation-details/record-creation-details.md index 0c706d373..2981df32a 100644 --- a/content/en/policies/other/record-creation-details/record-creation-details.md +++ b/content/en/policies/other/record-creation-details/record-creation-details.md @@ -36,7 +36,7 @@ metadata: all kinds ("*") it is highly recommend to more narrowly scope it to only the resources which should be labeled. spec: - validationFailureAction: enforce + validationFailureAction: Enforce background: false rules: - name: add-userinfo diff --git a/content/en/policies/other/require-annotations/require-annotations.md b/content/en/policies/other/require-annotations/require-annotations.md index 4324fe096..08ba7a3a2 100644 --- a/content/en/policies/other/require-annotations/require-annotations.md +++ b/content/en/policies/other/require-annotations/require-annotations.md @@ -27,7 +27,7 @@ metadata: all tools can understand. The recommended annotations describe applications in a way that can be queried. This policy validates that the annotation `corp.org/department` is specified with some value. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: check-for-annotation diff --git a/content/en/policies/other/require-base-image/require-base-image.md b/content/en/policies/other/require-base-image/require-base-image.md index a7e7f60fc..3085b2d82 100644 --- a/content/en/policies/other/require-base-image/require-base-image.md +++ b/content/en/policies/other/require-base-image/require-base-image.md @@ -35,7 +35,7 @@ metadata: to specify it using metadata or build directives of some sort (ex., Dockerfile FROM statements do not automatically expose this information). spec: - validationFailureAction: audit + validationFailureAction: Audit rules: - name: require-base-image match: diff --git a/content/en/policies/other/require-container-port-names/require-container-port-names.md b/content/en/policies/other/require-container-port-names/require-container-port-names.md index 3b63d6e6e..c42a0ba52 100644 --- a/content/en/policies/other/require-container-port-names/require-container-port-names.md +++ b/content/en/policies/other/require-container-port-names/require-container-port-names.md @@ -30,7 +30,7 @@ metadata: the port number to change. This policy requires that for every containerPort defined there is also a name specified. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: port-name diff --git a/content/en/policies/other/require-cpu-limits/require-cpu-limits.md b/content/en/policies/other/require-cpu-limits/require-cpu-limits.md new file mode 100644 index 000000000..2f6d3ed74 --- /dev/null +++ b/content/en/policies/other/require-cpu-limits/require-cpu-limits.md @@ -0,0 +1,57 @@ +--- +title: "Require CPU Limits" +category: Other +version: +subject: Pod +policyType: "validate" +description: > + Setting CPU limits on containers ensures fair distribution of resources, preventing any single container from monopolizing CPU and impacting the performance of other containers. This practice enhances stability, predictability, and cost control, while also mitigating the noisy neighbor problem and facilitating efficient scaling in Kubernetes clusters. This policy ensures that cpu limits are set on every container. +--- + +## Policy Definition +/other/require-cpu-limits/require-cpu-limits.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: require-cpu-limits + annotations: + policies.kyverno.io/title: Require CPU Limits + policies.kyverno.io/category: Other + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + kyverno.io/kubernetes-version: "1.26" + policies.kyverno.io/description: >- + Setting CPU limits on containers ensures fair distribution of resources, preventing any single container from monopolizing CPU and impacting the performance of other containers. This practice enhances stability, predictability, and cost control, while also mitigating the noisy neighbor problem and facilitating efficient scaling in Kubernetes clusters. This policy ensures that cpu limits are set on every container. +spec: + validationFailureAction: Audit + background: true + rules: + - name: check-cpu-limits + match: + any: + - resources: + kinds: + - Pod + validate: + message: "CPU limits are required for all containers." + pattern: + spec: + containers: + - (name): "*" + resources: + limits: + cpu: "?*" + =(ephemeralContainers): + - =(name): "*" + resources: + limits: + cpu: "?*" + =(initContainers): + - =(name): "*" + resources: + limits: + cpu: "?*" + +``` diff --git a/content/en/policies/other/require-deployments-have-multiple-replicas/require-deployments-have-multiple-replicas.md b/content/en/policies/other/require-deployments-have-multiple-replicas/require-deployments-have-multiple-replicas.md index 02a783747..78007d2af 100644 --- a/content/en/policies/other/require-deployments-have-multiple-replicas/require-deployments-have-multiple-replicas.md +++ b/content/en/policies/other/require-deployments-have-multiple-replicas/require-deployments-have-multiple-replicas.md @@ -27,7 +27,7 @@ metadata: may suffer downtime if that one replica goes down. This policy validates that Deployments have more than one replica. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: deployment-has-multiple-replicas diff --git a/content/en/policies/other/require-image-checksum/require-image-checksum.md b/content/en/policies/other/require-image-checksum/require-image-checksum.md index 56cbfc572..24932a69f 100644 --- a/content/en/policies/other/require-image-checksum/require-image-checksum.md +++ b/content/en/policies/other/require-image-checksum/require-image-checksum.md @@ -23,11 +23,9 @@ metadata: policies.kyverno.io/subject: Pod policies.kyverno.io/minversion: 1.6.0 policies.kyverno.io/description: >- - Use of a SHA checksum when pulling an image is often preferable because tags - are mutable and can be overwritten. This policy checks to ensure that all images - use SHA checksums rather than tags. + Use of a SHA checksum when pulling an image is often preferable because tags are mutable and can be overwritten. This policy checks to ensure that all images use SHA checksums rather than tags. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: require-image-checksum @@ -42,4 +40,9 @@ spec: spec: containers: - image: "*@*" + =(ephemeralContainers): + - image: "*@*" + =(initContainers): + - image: "*@*" + ``` diff --git a/content/en/policies/other/require-image-source/require-image-source.md b/content/en/policies/other/require-image-source/require-image-source.md index 25c37f088..cd80fde3b 100644 --- a/content/en/policies/other/require-image-source/require-image-source.md +++ b/content/en/policies/other/require-image-source/require-image-source.md @@ -32,7 +32,7 @@ metadata: either a label `org.opencontainers.image.source` or a newer annotation in the manifest of the same name. spec: - validationFailureAction: audit + validationFailureAction: Audit rules: - name: check-source match: diff --git a/content/en/policies/other/require-imagepullsecrets/require-imagepullsecrets.md b/content/en/policies/other/require-imagepullsecrets/require-imagepullsecrets.md index 9a0f9d546..5314fafc2 100644 --- a/content/en/policies/other/require-imagepullsecrets/require-imagepullsecrets.md +++ b/content/en/policies/other/require-imagepullsecrets/require-imagepullsecrets.md @@ -26,7 +26,7 @@ metadata: from them. This policy checks those images and if they come from a registry other than ghcr.io or quay.io an `imagePullSecret` is required. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: check-for-image-pull-secrets diff --git a/content/en/policies/other/require-ingress-https/require-ingress-https.md b/content/en/policies/other/require-ingress-https/require-ingress-https.md index 6619ed184..88b047e17 100644 --- a/content/en/policies/other/require-ingress-https/require-ingress-https.md +++ b/content/en/policies/other/require-ingress-https/require-ingress-https.md @@ -30,7 +30,7 @@ metadata: `"false"` and specify TLS in the spec. spec: background: true - validationFailureAction: audit + validationFailureAction: Audit rules: - name: has-annotation match: diff --git a/content/en/policies/other/require-netpol/require-netpol.md b/content/en/policies/other/require-netpol/require-netpol.md index dec73530b..c968ded2c 100644 --- a/content/en/policies/other/require-netpol/require-netpol.md +++ b/content/en/policies/other/require-netpol/require-netpol.md @@ -29,7 +29,7 @@ metadata: traffic. This policy checks incoming Deployments to ensure they have a matching, preexisting NetworkPolicy. spec: - validationFailureAction: audit + validationFailureAction: Audit background: false rules: - name: require-network-policy diff --git a/content/en/policies/other/require-non-root-groups/require-non-root-groups.md b/content/en/policies/other/require-non-root-groups/require-non-root-groups.md index a42ed9bbc..8f3db7b20 100644 --- a/content/en/policies/other/require-non-root-groups/require-non-root-groups.md +++ b/content/en/policies/other/require-non-root-groups/require-non-root-groups.md @@ -30,7 +30,7 @@ metadata: greater than zero (i.e., non root). A known issue prevents a policy such as this using `anyPattern` from being persisted properly in Kubernetes 1.23.0-1.23.2. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: check-runasgroup diff --git a/content/en/policies/other/require-pdb/require-pdb.md b/content/en/policies/other/require-pdb/require-pdb.md index b1eb8aa0f..453cb3e70 100644 --- a/content/en/policies/other/require-pdb/require-pdb.md +++ b/content/en/policies/other/require-pdb/require-pdb.md @@ -29,7 +29,7 @@ metadata: to ensure they have a matching, preexisting PodDisruptionBudget. Note: This policy must be run in `enforce` mode to ensure accuracy. spec: - validationFailureAction: audit + validationFailureAction: Audit background: false rules: - name: require-pdb diff --git a/content/en/policies/other/require-pod-priorityclassname/require-pod-priorityclassname.md b/content/en/policies/other/require-pod-priorityclassname/require-pod-priorityclassname.md index ed3acd930..5dfa82e20 100644 --- a/content/en/policies/other/require-pod-priorityclassname/require-pod-priorityclassname.md +++ b/content/en/policies/other/require-pod-priorityclassname/require-pod-priorityclassname.md @@ -29,7 +29,7 @@ metadata: scheduling guarantees. This policy requires that a Pod defines the priorityClassName field with some value. spec: - validationFailureAction: enforce + validationFailureAction: Enforce background: true rules: - name: check-priorityclassname diff --git a/content/en/policies/other/require-qos-burstable/require-qos-burstable.md b/content/en/policies/other/require-qos-burstable/require-qos-burstable.md index 3160a6421..7a9293c77 100644 --- a/content/en/policies/other/require-qos-burstable/require-qos-burstable.md +++ b/content/en/policies/other/require-qos-burstable/require-qos-burstable.md @@ -30,7 +30,7 @@ metadata: This policy is provided with the intention that users will need to control its scope by using exclusions, preconditions, and other policy language mechanisms. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: burstable diff --git a/content/en/policies/other/require-qos-guaranteed/require-qos-guaranteed.md b/content/en/policies/other/require-qos-guaranteed/require-qos-guaranteed.md index da147785d..41f642492 100644 --- a/content/en/policies/other/require-qos-guaranteed/require-qos-guaranteed.md +++ b/content/en/policies/other/require-qos-guaranteed/require-qos-guaranteed.md @@ -31,7 +31,7 @@ metadata: intention that users will need to control its scope by using exclusions, preconditions, and other policy language mechanisms. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: guaranteed diff --git a/content/en/policies/other/require-storageclass/require-storageclass.md b/content/en/policies/other/require-storageclass/require-storageclass.md index 297f99343..a15ea825e 100644 --- a/content/en/policies/other/require-storageclass/require-storageclass.md +++ b/content/en/policies/other/require-storageclass/require-storageclass.md @@ -28,7 +28,7 @@ metadata: StorageClasses. This policy requires that PVCs and StatefulSets containing volumeClaimTemplates define the storageClassName field with some value. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: pvc-storageclass diff --git a/content/en/policies/other/require-unique-external-dns/require-unique-external-dns.md b/content/en/policies/other/require-unique-external-dns/require-unique-external-dns.md index 434c11c1f..d69d8ae27 100644 --- a/content/en/policies/other/require-unique-external-dns/require-unique-external-dns.md +++ b/content/en/policies/other/require-unique-external-dns/require-unique-external-dns.md @@ -30,7 +30,7 @@ metadata: internal DNS, duplicates must be avoided. This policy requires every such Service have a cluster-unique hostname present in the value of the annotation. spec: - validationFailureAction: audit + validationFailureAction: Audit background: false rules: - name: ensure-valid-externaldns-annotation diff --git a/content/en/policies/other/require-unique-service-selector/require-unique-service-selector.md b/content/en/policies/other/require-unique-service-selector/require-unique-service-selector.md index 6935bafe1..b188418c4 100644 --- a/content/en/policies/other/require-unique-service-selector/require-unique-service-selector.md +++ b/content/en/policies/other/require-unique-service-selector/require-unique-service-selector.md @@ -28,7 +28,7 @@ metadata: consequences. This policy ensures that within the same Namespace a Service has a unique set of labels as a selector. spec: - validationFailureAction: audit + validationFailureAction: Audit background: false rules: - name: check-service-selector diff --git a/content/en/policies/other/require-unique-uid-per-workload/require-unique-uid-per-workload.md b/content/en/policies/other/require-unique-uid-per-workload/require-unique-uid-per-workload.md index f6568d838..5649e1127 100644 --- a/content/en/policies/other/require-unique-uid-per-workload/require-unique-uid-per-workload.md +++ b/content/en/policies/other/require-unique-uid-per-workload/require-unique-uid-per-workload.md @@ -32,7 +32,7 @@ metadata: kyverno.io/kubernetes-version: "1.20" spec: background: false - validationFailureAction: audit + validationFailureAction: Audit rules: - name: require-unique-uid match: diff --git a/content/en/policies/other/require-vulnerability-scan/require-vulnerability-scan.md b/content/en/policies/other/require-vulnerability-scan/require-vulnerability-scan.md index 9c77608a8..cc59f4b77 100644 --- a/content/en/policies/other/require-vulnerability-scan/require-vulnerability-scan.md +++ b/content/en/policies/other/require-vulnerability-scan/require-vulnerability-scan.md @@ -33,7 +33,7 @@ metadata: policy is expected to be customized based upon your signing strategy and applicable to the images you designate. spec: - validationFailureAction: audit + validationFailureAction: Audit webhookTimeoutSeconds: 10 failurePolicy: Fail rules: diff --git a/content/en/policies/other/restrict-annotations/restrict-annotations.md b/content/en/policies/other/restrict-annotations/restrict-annotations.md index e60747621..615b0cec3 100644 --- a/content/en/policies/other/restrict-annotations/restrict-annotations.md +++ b/content/en/policies/other/restrict-annotations/restrict-annotations.md @@ -28,7 +28,7 @@ metadata: don't set reserved annotations or to force them to use a newer version of an annotation. pod-policies.kyverno.io/autogen-controllers: none spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: block-flux-v1 diff --git a/content/en/policies/other/restrict-automount-sa-token/restrict-automount-sa-token.md b/content/en/policies/other/restrict-automount-sa-token/restrict-automount-sa-token.md index e496ba9bd..1eb995a84 100644 --- a/content/en/policies/other/restrict-automount-sa-token/restrict-automount-sa-token.md +++ b/content/en/policies/other/restrict-automount-sa-token/restrict-automount-sa-token.md @@ -29,7 +29,7 @@ metadata: be followed if Pods do not need to speak to the API server to function. This policy ensures that mounting of these ServiceAccount tokens is blocked. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: validate-automountServiceAccountToken diff --git a/content/en/policies/other/restrict-binding-clusteradmin/restrict-binding-clusteradmin.md b/content/en/policies/other/restrict-binding-clusteradmin/restrict-binding-clusteradmin.md index 76beccac6..c86f56202 100644 --- a/content/en/policies/other/restrict-binding-clusteradmin/restrict-binding-clusteradmin.md +++ b/content/en/policies/other/restrict-binding-clusteradmin/restrict-binding-clusteradmin.md @@ -30,7 +30,7 @@ metadata: policy prevents binding to the cluster-admin ClusterRole in RoleBinding or ClusterRoleBinding resources. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: clusteradmin-bindings diff --git a/content/en/policies/other/restrict-binding-system-groups/restrict-binding-system-groups.md b/content/en/policies/other/restrict-binding-system-groups/restrict-binding-system-groups.md index 904482c6f..4b6b48665 100644 --- a/content/en/policies/other/restrict-binding-system-groups/restrict-binding-system-groups.md +++ b/content/en/policies/other/restrict-binding-system-groups/restrict-binding-system-groups.md @@ -30,7 +30,7 @@ metadata: for other users. This policy prevents creating bindings to some of these groups including system:anonymous, system:unauthenticated, and system:masters. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: restrict-anonymous diff --git a/content/en/policies/other/restrict-clusterrole-csr/restrict-clusterrole-csr.md b/content/en/policies/other/restrict-clusterrole-csr/restrict-clusterrole-csr.md new file mode 100644 index 000000000..8ec699ff9 --- /dev/null +++ b/content/en/policies/other/restrict-clusterrole-csr/restrict-clusterrole-csr.md @@ -0,0 +1,71 @@ +--- +title: "Restrict Cluster Role CSR" +category: Other +version: +subject: ClusterRole +policyType: "validate" +description: > + ClusterRoles that grant permissions to approve CertificateSigningRequests should be minimized to reduce powerful identities in the cluster. Approving CertificateSigningRequests allows one to issue new credentials for any user or group. As such, ClusterRoles that grant permissions to approve CertificateSigningRequests are granting cluster admin privileges. Minimize such ClusterRoles to limit the number of powerful credentials that if compromised could take over the entire cluster. For more information, refer to https://docs.prismacloud.io/en/enterprise-edition/policy-reference/kubernetes-policies/kubernetes-policy-index/ensure-clusterroles-that-grant-permissions-to-approve-certificatesigningrequests-are-minimized. +--- + +## Policy Definition +/other/restrict-clusterrole-csr/restrict-clusterrole-csr.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-clusterrole-csr + annotations: + policies.kyverno.io/title: Restrict Cluster Role CSR + policies.kyverno.io/category: Other + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: ClusterRole + kyverno.io/kyverno-version: 1.11.5 + kyverno.io/kubernetes-version: "1.27" + policies.kyverno.io/description: >- + ClusterRoles that grant permissions to approve CertificateSigningRequests should be minimized to reduce powerful identities in the cluster. Approving CertificateSigningRequests allows one to issue new credentials for any user or group. As such, ClusterRoles that grant permissions to approve CertificateSigningRequests are granting cluster admin privileges. Minimize such ClusterRoles to limit the number of powerful credentials that if compromised could take over the entire cluster. For more information, refer to https://docs.prismacloud.io/en/enterprise-edition/policy-reference/kubernetes-policies/kubernetes-policy-index/ensure-clusterroles-that-grant-permissions-to-approve-certificatesigningrequests-are-minimized. +spec: + validationFailureAction: Audit + background: true + rules: + - name: certificatesigningrequests-update-prevention + match: + any: + - resources: + kinds: + - ClusterRole + validate: + message: "Use of verbs `update` and `patch` are forbidden for certificatesigningrequests/approval." + foreach: + - list: "request.object.rules[?resources.contains(@,'certificatesigningrequests/approval')]" + deny: + conditions: + any: + - key: ["update", "patch"] + operator: AnyIn + value: "{{ element.verbs[] }}" + - key: "{{ contains(element.verbs[], '*') }}" + operator: Equals + value: true + - name: signers-approve-prevention + match: + any: + - resources: + kinds: + - ClusterRole + validate: + message: "Use of verbs `approve` are forbidden for signers." + foreach: + - list: "request.object.rules[?resources.contains(@,'signers')]" + deny: + conditions: + any: + - key: ["approve"] + operator: AnyIn + value: "{{ element.verbs[] }}" + - key: "{{ contains(element.verbs[], '*') }}" + operator: Equals + value: true + +``` diff --git a/content/en/policies/other/restrict-clusterrole-mutating-validating-admission-webhooks/restrict-clusterrole-mutating-validating-admission-webhooks.md b/content/en/policies/other/restrict-clusterrole-mutating-validating-admission-webhooks/restrict-clusterrole-mutating-validating-admission-webhooks.md new file mode 100644 index 000000000..82a0cd659 --- /dev/null +++ b/content/en/policies/other/restrict-clusterrole-mutating-validating-admission-webhooks/restrict-clusterrole-mutating-validating-admission-webhooks.md @@ -0,0 +1,66 @@ +--- +title: "Restrict Clusterrole for Mutating and Validating Admission Webhooks" +category: Other +version: +subject: ClusterRole +policyType: "validate" +description: > + ClusterRoles that grant write permissions over admission webhook should be minimized to reduce powerful identities in the cluster. This policy checks to ensure write permissions are not provided to admission webhooks. +--- + +## Policy Definition +/other/restrict-clusterrole-mutating-validating-admission-webhooks/restrict-clusterrole-mutating-validating-admission-webhooks.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-clusterrole-mutating-validating-admission-webhooks + annotations: + policies.kyverno.io/title: Restrict Clusterrole for Mutating and Validating Admission Webhooks + policies.kyverno.io/category: Other + policies.kyverno.io/severity: medium + kyverno.io/kyverno-version: 1.10.7 + kyverno.io/kubernetes-version: "1.27" + policies.kyverno.io/subject: ClusterRole + policies.kyverno.io/description: >- + ClusterRoles that grant write permissions over admission webhook should be minimized to reduce powerful identities in the cluster. This policy checks to ensure write permissions are not provided to admission webhooks. +spec: + validationFailureAction: Audit + background: true + rules: + - name: restrict-clusterrole + match: + any: + - resources: + kinds: + - ClusterRole + validate: + message: "Use of verbs `create`, `update`, and `patch` are forbidden for mutating and validating admission webhooks" + foreach: + - list: "request.object.rules[]" + deny: + conditions: + all: + - key: "{{ element.apiGroups || '' }}" + operator: AnyIn + value: + - admissionregistration.k8s.io + - key: "{{ element.resources || '' }}" + operator: AnyIn + value: + - mutatingwebhookconfigurations + - validatingwebhookconfigurations + any: + - key: "{{ element.verbs }}" + operator: AnyIn + value: + - create + - update + - patch + - key: "{{ contains(element.verbs[], '*') }}" + operator: Equals + value: true + + +``` diff --git a/content/en/policies/other/restrict-clusterrole-nodesproxy/restrict-clusterrole-nodesproxy.md b/content/en/policies/other/restrict-clusterrole-nodesproxy/restrict-clusterrole-nodesproxy.md index edd94f07e..a03005bed 100644 --- a/content/en/policies/other/restrict-clusterrole-nodesproxy/restrict-clusterrole-nodesproxy.md +++ b/content/en/policies/other/restrict-clusterrole-nodesproxy/restrict-clusterrole-nodesproxy.md @@ -32,7 +32,7 @@ metadata: for more info. This policy prevents the creation of a ClusterRole if it contains the nodes/proxy resource. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: clusterrole-nodesproxy diff --git a/content/en/policies/other/restrict-controlplane-scheduling/restrict-controlplane-scheduling.md b/content/en/policies/other/restrict-controlplane-scheduling/restrict-controlplane-scheduling.md index aeea142bd..3a771e4f5 100644 --- a/content/en/policies/other/restrict-controlplane-scheduling/restrict-controlplane-scheduling.md +++ b/content/en/policies/other/restrict-controlplane-scheduling/restrict-controlplane-scheduling.md @@ -28,7 +28,7 @@ metadata: in a Pod spec which allows running on control plane nodes with the taint key `node-role.kubernetes.io/master`. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: restrict-controlplane-scheduling-master diff --git a/content/en/policies/other/restrict-edit-for-endpoints/restrict-edit-for-endpoints.md b/content/en/policies/other/restrict-edit-for-endpoints/restrict-edit-for-endpoints.md index 453fd7a21..c3033b76e 100644 --- a/content/en/policies/other/restrict-edit-for-endpoints/restrict-edit-for-endpoints.md +++ b/content/en/policies/other/restrict-edit-for-endpoints/restrict-edit-for-endpoints.md @@ -32,7 +32,7 @@ metadata: to CVE-2021-25740 by ensuring the system:aggregate-to-edit ClusterRole does not have the edit permission of Endpoints. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: system-aggregate-to-edit-check diff --git a/content/en/policies/other/restrict-escalation-verbs-roles/restrict-escalation-verbs-roles.md b/content/en/policies/other/restrict-escalation-verbs-roles/restrict-escalation-verbs-roles.md index 59930f115..f07d9018e 100644 --- a/content/en/policies/other/restrict-escalation-verbs-roles/restrict-escalation-verbs-roles.md +++ b/content/en/policies/other/restrict-escalation-verbs-roles/restrict-escalation-verbs-roles.md @@ -29,7 +29,7 @@ metadata: privilege escalation and should be tightly controlled. This policy prevents use of these verbs in Role or ClusterRole resources. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: escalate diff --git a/content/en/policies/other/restrict-ingress-classes/restrict-ingress-classes.md b/content/en/policies/other/restrict-ingress-classes/restrict-ingress-classes.md index 3699bd1cf..7f7428ad9 100644 --- a/content/en/policies/other/restrict-ingress-classes/restrict-ingress-classes.md +++ b/content/en/policies/other/restrict-ingress-classes/restrict-ingress-classes.md @@ -30,7 +30,7 @@ metadata: annotation. This annotation has largely been replaced as of Kubernetes 1.18 with the IngressClass resource. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: validate-ingress diff --git a/content/en/policies/other/restrict-ingress-defaultbackend/restrict-ingress-defaultbackend.md b/content/en/policies/other/restrict-ingress-defaultbackend/restrict-ingress-defaultbackend.md index b947772d0..b541930f6 100644 --- a/content/en/policies/other/restrict-ingress-defaultbackend/restrict-ingress-defaultbackend.md +++ b/content/en/policies/other/restrict-ingress-defaultbackend/restrict-ingress-defaultbackend.md @@ -32,7 +32,7 @@ metadata: want users to use explicit hosts, they should not be able to overwrite the global default backend service. This policy prohibits the use of the defaultBackend field. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: restrict-ingress-defaultbackend diff --git a/content/en/policies/other/restrict-ingress-host/restrict-ingress-host.md b/content/en/policies/other/restrict-ingress-host/restrict-ingress-host.md index 4336ff304..87da72f05 100644 --- a/content/en/policies/other/restrict-ingress-host/restrict-ingress-host.md +++ b/content/en/policies/other/restrict-ingress-host/restrict-ingress-host.md @@ -28,7 +28,7 @@ metadata: This policy checks an incoming Ingress resource to ensure its hosts are unique to the cluster. It also ensures that only a single host may be specified in a given manifest. spec: - validationFailureAction: audit + validationFailureAction: Audit background: false rules: - name: check-single-host-create diff --git a/content/en/policies/other/restrict-ingress-wildcard/restrict-ingress-wildcard.md b/content/en/policies/other/restrict-ingress-wildcard/restrict-ingress-wildcard.md index 61781710f..e425ecab5 100644 --- a/content/en/policies/other/restrict-ingress-wildcard/restrict-ingress-wildcard.md +++ b/content/en/policies/other/restrict-ingress-wildcard/restrict-ingress-wildcard.md @@ -31,7 +31,7 @@ metadata: policy enforces that any Ingress host does not contain a wildcard character. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: block-ingress-wildcard diff --git a/content/en/policies/other/restrict-loadbalancer/restrict-loadbalancer.md b/content/en/policies/other/restrict-loadbalancer/restrict-loadbalancer.md index b8bc9ffd8..b308796c6 100644 --- a/content/en/policies/other/restrict-loadbalancer/restrict-loadbalancer.md +++ b/content/en/policies/other/restrict-loadbalancer/restrict-loadbalancer.md @@ -29,7 +29,7 @@ metadata: overrun established budgets and security practices set by the organization. This policy restricts use of the Service type LoadBalancer. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: no-LoadBalancer diff --git a/content/en/policies/other/restrict-networkpolicy-empty-podselector/restrict-networkpolicy-empty-podselector.md b/content/en/policies/other/restrict-networkpolicy-empty-podselector/restrict-networkpolicy-empty-podselector.md index 4ac187519..51b79bb29 100644 --- a/content/en/policies/other/restrict-networkpolicy-empty-podselector/restrict-networkpolicy-empty-podselector.md +++ b/content/en/policies/other/restrict-networkpolicy-empty-podselector/restrict-networkpolicy-empty-podselector.md @@ -27,7 +27,7 @@ metadata: more closely control the necessary traffic flows. This policy requires that all NetworkPolicies other than that of `default-deny` not use an empty podSelector. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: empty-podselector diff --git a/content/en/policies/other/restrict-node-affinity/restrict-node-affinity.md b/content/en/policies/other/restrict-node-affinity/restrict-node-affinity.md index b6c6548f5..ff20f3003 100644 --- a/content/en/policies/other/restrict-node-affinity/restrict-node-affinity.md +++ b/content/en/policies/other/restrict-node-affinity/restrict-node-affinity.md @@ -31,7 +31,7 @@ metadata: is not used in a Pod spec. spec: background: true - validationFailureAction: audit + validationFailureAction: Audit rules: - name: check-nodeaffinity match: diff --git a/content/en/policies/other/restrict-node-label-changes/restrict-node-label-changes.md b/content/en/policies/other/restrict-node-label-changes/restrict-node-label-changes.md index 94bb09fcf..389f3c9b9 100644 --- a/content/en/policies/other/restrict-node-label-changes/restrict-node-label-changes.md +++ b/content/en/policies/other/restrict-node-label-changes/restrict-node-label-changes.md @@ -30,7 +30,7 @@ metadata: requires, at minimum, one of the following versions of Kubernetes: v1.18.18, v1.19.10, v1.20.6, or v1.21.0. spec: - validationFailureAction: enforce + validationFailureAction: Enforce background: false rules: - name: prevent-label-value-changes @@ -40,6 +40,7 @@ spec: kinds: - Node validate: + allowExistingViolations: false message: "Modifying the `foo` label on a Node is not allowed." deny: conditions: @@ -65,9 +66,11 @@ spec: operator: Equals value: "?*" validate: + allowExistingViolations: false message: "Removing the `foo` label on a Node is not allowed." pattern: metadata: labels: foo: "*" + ``` diff --git a/content/en/policies/other/restrict-node-label-creation/restrict-node-label-creation.md b/content/en/policies/other/restrict-node-label-creation/restrict-node-label-creation.md index ffae81cf2..f0ffdb183 100644 --- a/content/en/policies/other/restrict-node-label-creation/restrict-node-label-creation.md +++ b/content/en/policies/other/restrict-node-label-creation/restrict-node-label-creation.md @@ -31,7 +31,7 @@ metadata: requires, at minimum, one of the following versions of Kubernetes: v1.18.18, v1.19.10, v1.20.6, or v1.21.0. spec: - validationFailureAction: enforce + validationFailureAction: Enforce background: false rules: - name: prevent-label-set diff --git a/content/en/policies/other/restrict-node-selection/restrict-node-selection.md b/content/en/policies/other/restrict-node-selection/restrict-node-selection.md index a093123d0..3c45bd0c7 100644 --- a/content/en/policies/other/restrict-node-selection/restrict-node-selection.md +++ b/content/en/policies/other/restrict-node-selection/restrict-node-selection.md @@ -30,7 +30,7 @@ metadata: this policy is only designed to work on initial creation and not in background mode. spec: - validationFailureAction: audit + validationFailureAction: Audit background: false rules: - name: restrict-nodeselector diff --git a/content/en/policies/other/restrict-pod-controller-serviceaccount-updates/restrict-pod-controller-serviceaccount-updates.md b/content/en/policies/other/restrict-pod-controller-serviceaccount-updates/restrict-pod-controller-serviceaccount-updates.md index de1b0d6b9..a340b6937 100644 --- a/content/en/policies/other/restrict-pod-controller-serviceaccount-updates/restrict-pod-controller-serviceaccount-updates.md +++ b/content/en/policies/other/restrict-pod-controller-serviceaccount-updates/restrict-pod-controller-serviceaccount-updates.md @@ -30,7 +30,7 @@ metadata: to Pod controllers if those updates modify the serviceAccountName field. Updates to Pods directly for this field are not possible as it is immutable once set. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: block-serviceaccount-updates diff --git a/content/en/policies/other/restrict-pod-count-per-node/restrict-pod-count-per-node.md b/content/en/policies/other/restrict-pod-count-per-node/restrict-pod-count-per-node.md index d45151204..a711d0bf1 100644 --- a/content/en/policies/other/restrict-pod-count-per-node/restrict-pod-count-per-node.md +++ b/content/en/policies/other/restrict-pod-count-per-node/restrict-pod-count-per-node.md @@ -28,7 +28,7 @@ metadata: development cases. This policy restricts Pod count on a Node named `minikube` to be no more than 10. # pod-policies.kyverno.io/autogen-controllers: none spec: - validationFailureAction: audit + validationFailureAction: Audit background: false rules: - name: restrict-pod-count diff --git a/content/en/policies/other/restrict-scale/restrict-scale.md b/content/en/policies/other/restrict-scale/restrict-scale.md index 64c5d57af..417bdd903 100644 --- a/content/en/policies/other/restrict-scale/restrict-scale.md +++ b/content/en/policies/other/restrict-scale/restrict-scale.md @@ -32,7 +32,7 @@ metadata: of rules which can be used to limit the replica count both upon creation of a Deployment and when a scale operation is performed. spec: - validationFailureAction: audit + validationFailureAction: Audit background: false rules: # This rule can be used to limit scale operations based upon Deployment labels assuming the given label diff --git a/content/en/policies/other/restrict-secret-role-verbs/restrict-secret-role-verbs.md b/content/en/policies/other/restrict-secret-role-verbs/restrict-secret-role-verbs.md index 6a8d1ddae..b709cf902 100644 --- a/content/en/policies/other/restrict-secret-role-verbs/restrict-secret-role-verbs.md +++ b/content/en/policies/other/restrict-secret-role-verbs/restrict-secret-role-verbs.md @@ -32,7 +32,7 @@ metadata: also prevents use of the wildcard ('*') in the verbs list either when explicitly naming Secrets or when also using a wildcard in the base API group. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: secret-verbs diff --git a/content/en/policies/other/restrict-secrets-by-label/restrict-secrets-by-label.md b/content/en/policies/other/restrict-secrets-by-label/restrict-secrets-by-label.md index d89866ee8..4ee71a52e 100644 --- a/content/en/policies/other/restrict-secrets-by-label/restrict-secrets-by-label.md +++ b/content/en/policies/other/restrict-secrets-by-label/restrict-secrets-by-label.md @@ -31,7 +31,7 @@ metadata: that only Secrets not labeled with `status=protected` can be consumed by Pods. spec: background: false - validationFailureAction: audit + validationFailureAction: Audit rules: - name: secrets-lookup-from-env match: diff --git a/content/en/policies/other/restrict-secrets-by-name/restrict-secrets-by-name.md b/content/en/policies/other/restrict-secrets-by-name/restrict-secrets-by-name.md index b9b176af4..7b5a7e833 100644 --- a/content/en/policies/other/restrict-secrets-by-name/restrict-secrets-by-name.md +++ b/content/en/policies/other/restrict-secrets-by-name/restrict-secrets-by-name.md @@ -32,7 +32,7 @@ metadata: result in a Secret being mounted. spec: background: false - validationFailureAction: enforce + validationFailureAction: Enforce rules: - name: safe-secrets-from-env match: diff --git a/content/en/policies/other/restrict-service-account/restrict-service-account.md b/content/en/policies/other/restrict-service-account/restrict-service-account.md index 657c6b021..f83c14e73 100644 --- a/content/en/policies/other/restrict-service-account/restrict-service-account.md +++ b/content/en/policies/other/restrict-service-account/restrict-service-account.md @@ -32,7 +32,7 @@ metadata: specified is matched based on the image and name of the container. For example: 'sa-name: ["registry/image-name"]' spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: validate-service-account diff --git a/content/en/policies/other/restrict-service-port-range/restrict-service-port-range.md b/content/en/policies/other/restrict-service-port-range/restrict-service-port-range.md index a4286719c..582bd1a5c 100644 --- a/content/en/policies/other/restrict-service-port-range/restrict-service-port-range.md +++ b/content/en/policies/other/restrict-service-port-range/restrict-service-port-range.md @@ -31,7 +31,7 @@ metadata: This policy enforces that only the port range 32000 to 33000 may be used for Service resources. spec: - validationFailureAction: audit + validationFailureAction: Audit rules: - name: restrict-port-range match: diff --git a/content/en/policies/other/restrict-storageclass/restrict-storageclass.md b/content/en/policies/other/restrict-storageclass/restrict-storageclass.md index ac9fcd796..2e1bdad4e 100644 --- a/content/en/policies/other/restrict-storageclass/restrict-storageclass.md +++ b/content/en/policies/other/restrict-storageclass/restrict-storageclass.md @@ -29,7 +29,7 @@ metadata: a PersistentVolume cannot be reused across Namespaces. This policy requires StorageClasses set a reclaimPolicy of `Delete`. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: storageclass-delete diff --git a/content/en/policies/other/restrict-usergroup-fsgroup-id/restrict-usergroup-fsgroup-id.md b/content/en/policies/other/restrict-usergroup-fsgroup-id/restrict-usergroup-fsgroup-id.md index 2daec9b35..b4f0bee45 100644 --- a/content/en/policies/other/restrict-usergroup-fsgroup-id/restrict-usergroup-fsgroup-id.md +++ b/content/en/policies/other/restrict-usergroup-fsgroup-id/restrict-usergroup-fsgroup-id.md @@ -28,7 +28,7 @@ metadata: to make sure any file created in the volume will have the specified groupID. This policy validates that these fields are set to the defined values. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: validate-userid diff --git a/content/en/policies/other/restrict-wildcard-resources/restrict-wildcard-resources.md b/content/en/policies/other/restrict-wildcard-resources/restrict-wildcard-resources.md index 399a4dd71..21141573f 100644 --- a/content/en/policies/other/restrict-wildcard-resources/restrict-wildcard-resources.md +++ b/content/en/policies/other/restrict-wildcard-resources/restrict-wildcard-resources.md @@ -31,7 +31,7 @@ metadata: This policy blocks any Role or ClusterRole that contains a wildcard entry in the resources list found in any rule. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: wildcard-resources diff --git a/content/en/policies/other/restrict-wildcard-verbs/restrict-wildcard-verbs.md b/content/en/policies/other/restrict-wildcard-verbs/restrict-wildcard-verbs.md index f8cab811f..b02c44408 100644 --- a/content/en/policies/other/restrict-wildcard-verbs/restrict-wildcard-verbs.md +++ b/content/en/policies/other/restrict-wildcard-verbs/restrict-wildcard-verbs.md @@ -31,7 +31,7 @@ metadata: This policy blocks any Role or ClusterRole that contains a wildcard entry in the verbs list found in any rule. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: wildcard-verbs diff --git a/content/en/policies/other/topologyspreadconstraints-policy/topologyspreadconstraints-policy.md b/content/en/policies/other/topologyspreadconstraints-policy/topologyspreadconstraints-policy.md index cfbae6003..b05ce9661 100644 --- a/content/en/policies/other/topologyspreadconstraints-policy/topologyspreadconstraints-policy.md +++ b/content/en/policies/other/topologyspreadconstraints-policy/topologyspreadconstraints-policy.md @@ -34,7 +34,7 @@ metadata: spec: background: true failurePolicy: Ignore - validationFailureAction: audit + validationFailureAction: Audit rules: - name: spread-pods match: diff --git a/content/en/policies/other/unique-ingress-host-and-path/unique-ingress-host-and-path.md b/content/en/policies/other/unique-ingress-host-and-path/unique-ingress-host-and-path.md index f42cd434f..910b6422d 100644 --- a/content/en/policies/other/unique-ingress-host-and-path/unique-ingress-host-and-path.md +++ b/content/en/policies/other/unique-ingress-host-and-path/unique-ingress-host-and-path.md @@ -30,7 +30,7 @@ metadata: This policy ensures that no Ingress can be created or updated unless it is globally unique with respect to host plus path combination. spec: - validationFailureAction: audit + validationFailureAction: Audit background: false rules: - name: check-host-path-combo diff --git a/content/en/policies/other/unique-ingress-paths/unique-ingress-paths.md b/content/en/policies/other/unique-ingress-paths/unique-ingress-paths.md index 09b731cef..46fb38acb 100644 --- a/content/en/policies/other/unique-ingress-paths/unique-ingress-paths.md +++ b/content/en/policies/other/unique-ingress-paths/unique-ingress-paths.md @@ -30,7 +30,7 @@ metadata: existing Ingress rule (ex., when blocking /foo/bar /foo must exist by itself and not part of /foo/baz). spec: - validationFailureAction: audit + validationFailureAction: Audit background: false rules: - name: check-path diff --git a/content/en/policies/other/verify-image-cve-2022-42889/verify-image-cve-2022-42889.md b/content/en/policies/other/verify-image-cve-2022-42889/verify-image-cve-2022-42889.md index 5d94cac26..321ccc189 100644 --- a/content/en/policies/other/verify-image-cve-2022-42889/verify-image-cve-2022-42889.md +++ b/content/en/policies/other/verify-image-cve-2022-42889/verify-image-cve-2022-42889.md @@ -33,7 +33,7 @@ metadata: package. Using this for your own purposes will require customizing the `imageReferences`, `subject`, and `issuer` fields based on your image signatures and attestations. spec: - validationFailureAction: audit + validationFailureAction: Audit webhookTimeoutSeconds: 10 rules: - name: cve-2022-42889 diff --git a/content/en/policies/other/verify-image-gcpkms/verify-image-gcpkms.md b/content/en/policies/other/verify-image-gcpkms/verify-image-gcpkms.md index 874dff930..4014aaf48 100644 --- a/content/en/policies/other/verify-image-gcpkms/verify-image-gcpkms.md +++ b/content/en/policies/other/verify-image-gcpkms/verify-image-gcpkms.md @@ -30,7 +30,7 @@ metadata: its signature against the provided public key. This policy serves as an illustration for how to configure a similar rule and will require replacing with your image(s) and keys. spec: - validationFailureAction: audit + validationFailureAction: Audit background: false rules: - name: verify-image diff --git a/content/en/policies/other/verify-image-slsa/verify-image-slsa.md b/content/en/policies/other/verify-image-slsa/verify-image-slsa.md index 5adf5f442..204db7341 100644 --- a/content/en/policies/other/verify-image-slsa/verify-image-slsa.md +++ b/content/en/policies/other/verify-image-slsa/verify-image-slsa.md @@ -32,7 +32,7 @@ metadata: when produced through GitHub Actions. It requires configuration based upon your own values. spec: - validationFailureAction: audit + validationFailureAction: Audit webhookTimeoutSeconds: 30 rules: - name: check-slsa-keyless diff --git a/content/en/policies/other/verify-image-with-multi-keys/verify-image-with-multi-keys.md b/content/en/policies/other/verify-image-with-multi-keys/verify-image-with-multi-keys.md index 8983a7ab0..3ce7a66fc 100644 --- a/content/en/policies/other/verify-image-with-multi-keys/verify-image-with-multi-keys.md +++ b/content/en/policies/other/verify-image-with-multi-keys/verify-image-with-multi-keys.md @@ -5,7 +5,7 @@ version: 1.7.0 subject: Pod policyType: "verifyImages" description: > - There may be multiple keys used to sign images based on the parties involved in the creation process. This image verification policy requires the named image be signed by two separate keys. It will search for a global "production" key in a ConfigMap called `key` in the `default` Namespace and also a Namespace key in the same ConfigMap. + There may be multiple keys used to sign images based on the parties involved in the creation process. This image verification policy requires the named image be signed by two separate keys. It will search for a global "production" key in a ConfigMap called `keys` in the `default` Namespace and also a Namespace key in the same ConfigMap. --- ## Policy Definition @@ -29,10 +29,10 @@ metadata: the parties involved in the creation process. This image verification policy requires the named image be signed by two separate keys. It will search for a global "production" - key in a ConfigMap called `key` in the `default` Namespace + key in a ConfigMap called `keys` in the `default` Namespace and also a Namespace key in the same ConfigMap. spec: - validationFailureAction: enforce + validationFailureAction: Enforce background: false rules: - name: check-image-with-two-keys @@ -57,4 +57,5 @@ spec: publicKeys: "{{ keys.data.production }}" - keys: publicKeys: "{{ keys.data.{{request.namespace}} }}" + ``` diff --git a/content/en/policies/other/verify-image/verify-image.md b/content/en/policies/other/verify-image/verify-image.md index f7db5d0fd..a524cee18 100644 --- a/content/en/policies/other/verify-image/verify-image.md +++ b/content/en/policies/other/verify-image/verify-image.md @@ -30,7 +30,7 @@ metadata: its signature against the provided public key. This policy serves as an illustration for how to configure a similar rule and will require replacing with your image(s) and keys. spec: - validationFailureAction: enforce + validationFailureAction: Enforce background: false rules: - name: verify-image diff --git a/content/en/policies/other/verify-manifest-integrity/verify-manifest-integrity.md b/content/en/policies/other/verify-manifest-integrity/verify-manifest-integrity.md index e5ca0416c..db02721ae 100644 --- a/content/en/policies/other/verify-manifest-integrity/verify-manifest-integrity.md +++ b/content/en/policies/other/verify-manifest-integrity/verify-manifest-integrity.md @@ -33,7 +33,7 @@ metadata: the expected key but ignores the `spec.replicas` field allowing other teams to change just this value. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: verify-deployment-allow-replicas diff --git a/content/en/policies/other/verify-sbom-cyclonedx/verify-sbom-cyclonedx.md b/content/en/policies/other/verify-sbom-cyclonedx/verify-sbom-cyclonedx.md index 48cb51c68..6aa984af9 100644 --- a/content/en/policies/other/verify-sbom-cyclonedx/verify-sbom-cyclonedx.md +++ b/content/en/policies/other/verify-sbom-cyclonedx/verify-sbom-cyclonedx.md @@ -32,7 +32,7 @@ metadata: and was signed by the expected subject and issuer when produced through GitHub Actions and using Cosign's keyless signing. It requires configuration based upon your own values. spec: - validationFailureAction: audit + validationFailureAction: Audit webhookTimeoutSeconds: 30 rules: - name: check-sbom diff --git a/content/en/policies/pod-security-cel/baseline/disallow-capabilities/disallow-capabilities.md b/content/en/policies/pod-security-cel/baseline/disallow-capabilities/disallow-capabilities.md index ad9512538..02595b17b 100644 --- a/content/en/policies/pod-security-cel/baseline/disallow-capabilities/disallow-capabilities.md +++ b/content/en/policies/pod-security-cel/baseline/disallow-capabilities/disallow-capabilities.md @@ -40,38 +40,16 @@ spec: - UPDATE validate: cel: + variables: + - name: allowedCapabilities + expression: "['AUDIT_WRITE','CHOWN','DAC_OVERRIDE','FOWNER','FSETID','KILL','MKNOD','NET_BIND_SERVICE','SETFCAP','SETGID','SETPCAP','SETUID','SYS_CHROOT']" + - name: allContainers + expression: "(object.spec.containers + (has(object.spec.initContainers) ? object.spec.initContainers : []) + (has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []))" expressions: - expression: >- - object.spec.containers.all(container, - !has(container.securityContext) || - !has(container.securityContext.capabilities) || - !has(container.securityContext.capabilities.add) || - container.securityContext.capabilities.add.all(capability, - ['AUDIT_WRITE','CHOWN','DAC_OVERRIDE','FOWNER','FSETID','KILL','MKNOD','NET_BIND_SERVICE','SETFCAP','SETGID','SETPCAP','SETUID','SYS_CHROOT'].exists(secureCapability, secureCapability == capability))) - message: >- - Any capabilities added beyond the allowed list (AUDIT_WRITE, CHOWN, DAC_OVERRIDE, FOWNER, - FSETID, KILL, MKNOD, NET_BIND_SERVICE, SETFCAP, SETGID, SETPCAP, SETUID, SYS_CHROOT) - are disallowed. - - - expression: >- - !has(object.spec.initContainers) || - object.spec.initContainers.all(container, !has(container.securityContext) || - !has(container.securityContext.capabilities) || - !has(container.securityContext.capabilities.add) || - container.securityContext.capabilities.add.all(capability, - ['AUDIT_WRITE','CHOWN','DAC_OVERRIDE','FOWNER','FSETID','KILL','MKNOD','NET_BIND_SERVICE','SETFCAP','SETGID','SETPCAP','SETUID','SYS_CHROOT'].exists(secureCapability, secureCapability == capability))) - message: >- - Any capabilities added beyond the allowed list (AUDIT_WRITE, CHOWN, DAC_OVERRIDE, FOWNER, - FSETID, KILL, MKNOD, NET_BIND_SERVICE, SETFCAP, SETGID, SETPCAP, SETUID, SYS_CHROOT) - are disallowed. - - - expression: >- - !has(object.spec.ephemeralContainers) || - object.spec.ephemeralContainers.all(container, !has(container.securityContext) || - !has(container.securityContext.capabilities) || - !has(container.securityContext.capabilities.add) || - container.securityContext.capabilities.add.all(capability, - ['AUDIT_WRITE','CHOWN','DAC_OVERRIDE','FOWNER','FSETID','KILL','MKNOD','NET_BIND_SERVICE','SETFCAP','SETGID','SETPCAP','SETUID','SYS_CHROOT'].exists(secureCapability, secureCapability == capability))) + variables.allContainers.all(container, + container.?securityContext.?capabilities.?add.orValue([]).all(capability, capability == '' || + capability in variables.allowedCapabilities)) message: >- Any capabilities added beyond the allowed list (AUDIT_WRITE, CHOWN, DAC_OVERRIDE, FOWNER, FSETID, KILL, MKNOD, NET_BIND_SERVICE, SETFCAP, SETGID, SETPCAP, SETUID, SYS_CHROOT) diff --git a/content/en/policies/pod-security-cel/baseline/disallow-host-namespaces/disallow-host-namespaces.md b/content/en/policies/pod-security-cel/baseline/disallow-host-namespaces/disallow-host-namespaces.md index baaf0931b..02f85944e 100644 --- a/content/en/policies/pod-security-cel/baseline/disallow-host-namespaces/disallow-host-namespaces.md +++ b/content/en/policies/pod-security-cel/baseline/disallow-host-namespaces/disallow-host-namespaces.md @@ -45,9 +45,9 @@ spec: cel: expressions: - expression: >- - (!has(object.spec.hostNetwork) || object.spec.hostNetwork == false) && - (!has(object.spec.hostIPC) || object.spec.hostIPC == false) && - (!has(object.spec.hostPID) || object.spec.hostPID == false) + ( object.spec.?hostNetwork.orValue(false) == false) && + ( object.spec.?hostIPC.orValue(false) == false) && + ( object.spec.?hostPID.orValue(false) == false) message: >- Sharing the host namespaces is disallowed. The fields spec.hostNetwork, spec.hostIPC, and spec.hostPID must be unset or set to `false`. diff --git a/content/en/policies/pod-security-cel/baseline/disallow-host-path/disallow-host-path.md b/content/en/policies/pod-security-cel/baseline/disallow-host-path/disallow-host-path.md index 384450490..c16f451a3 100644 --- a/content/en/policies/pod-security-cel/baseline/disallow-host-path/disallow-host-path.md +++ b/content/en/policies/pod-security-cel/baseline/disallow-host-path/disallow-host-path.md @@ -43,7 +43,7 @@ spec: validate: cel: expressions: - - expression: "!has(object.spec.volumes) || object.spec.volumes.all(volume, !has(volume.hostPath))" + - expression: "object.spec.?volumes.orValue([]).all(volume, size(volume) == 0 || !has(volume.hostPath))" message: "HostPath volumes are forbidden. The field spec.volumes[*].hostPath must be unset" ``` diff --git a/content/en/policies/pod-security-cel/baseline/disallow-host-ports-range/disallow-host-ports-range.md b/content/en/policies/pod-security-cel/baseline/disallow-host-ports-range/disallow-host-ports-range.md index eb1ccf662..4d5b32483 100644 --- a/content/en/policies/pod-security-cel/baseline/disallow-host-ports-range/disallow-host-ports-range.md +++ b/content/en/policies/pod-security-cel/baseline/disallow-host-ports-range/disallow-host-ports-range.md @@ -43,24 +43,18 @@ spec: - UPDATE validate: cel: + variables: + - name: allContainers + expression: >- + object.spec.containers + + object.spec.?initContainers.orValue([]) + + object.spec.?ephemeralContainers.orValue([]) expressions: - expression: >- - object.spec.containers.all(container, !has(container.ports) || - container.ports.all(port, !has(port.hostPort) || (port.hostPort >= 5000 && port.hostPort <= 6000))) - message: >- - The only permitted hostPorts are in the range 5000-6000. - - - expression: >- - !has(object.spec.initContainers) || - object.spec.initContainers.all(container, !has(container.ports) || - container.ports.all(port, !has(port.hostPort) || (port.hostPort >= 5000 && port.hostPort <= 6000))) - message: >- - The only permitted hostPorts are in the range 5000-6000. - - - expression: >- - !has(object.spec.ephemeralContainers) || - object.spec.ephemeralContainers.all(container, !has(container.ports) || - container.ports.all(port, !has(port.hostPort) || (port.hostPort >= 5000 && port.hostPort <= 6000))) + variables.allContainers.all(container, + container.?ports.orValue([]).all(port, + size(port) == 0 || + !has(port.hostPort) || (port.hostPort >= 5000 && port.hostPort <= 6000) )) message: >- The only permitted hostPorts are in the range 5000-6000. diff --git a/content/en/policies/pod-security-cel/baseline/disallow-host-process/disallow-host-process.md b/content/en/policies/pod-security-cel/baseline/disallow-host-process/disallow-host-process.md index 38b8683b5..ae6bbab6d 100644 --- a/content/en/policies/pod-security-cel/baseline/disallow-host-process/disallow-host-process.md +++ b/content/en/policies/pod-security-cel/baseline/disallow-host-process/disallow-host-process.md @@ -43,34 +43,17 @@ spec: - UPDATE validate: cel: + variables: + - name: allContainers + expression: "(object.spec.containers + (has(object.spec.initContainers) ? object.spec.initContainers : []) + (has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []))" expressions: - - expression: >- - object.spec.containers.all(container, !has(container.securityContext) || - !has(container.securityContext.windowsOptions) || - !has(container.securityContext.windowsOptions.hostProcess) || - container.securityContext.windowsOptions.hostProcess == false) + - expression: >- + variables.allContainers.all(container, + container.?securityContext.?windowsOptions.?hostProcess.orValue(false) == false) message: >- - HostProcess containers are disallowed. The field spec.containers[*].securityContext.windowsOptions.hostProcess - must either be undefined or set to `false`. - - - expression: >- - !has(object.spec.initContainers) || - object.spec.initContainers.all(container, !has(container.securityContext) || - !has(container.securityContext.windowsOptions) || - !has(container.securityContext.windowsOptions.hostProcess) || - container.securityContext.windowsOptions.hostProcess == false) - message: >- - HostProcess containers are disallowed. The field spec.initContainers[*].securityContext.windowsOptions.hostProcess - must either be undefined or set to `false`. - - - expression: >- - !has(object.spec.ephemeralContainers) || - object.spec.ephemeralContainers.all(container, !has(container.securityContext) || - !has(container.securityContext.windowsOptions) || - !has(container.securityContext.windowsOptions.hostProcess) || - container.securityContext.windowsOptions.hostProcess == false) - message: >- - HostProcess containers are disallowed. The field spec.ephemeralContainers[*].securityContext.windowsOptions.hostProcess - must either be undefined or set to `false`. + HostProcess containers are disallowed. The field spec.containers[*].securityContext.windowsOptions.hostProcess, + spec.initContainers[*].securityContext.windowsOptions.hostProcess, and + spec.ephemeralContainers[*].securityContext.windowsOptions.hostProcess + must either be undefined or set to `false`. ``` diff --git a/content/en/policies/pod-security-cel/baseline/disallow-privileged-containers/disallow-privileged-containers.md b/content/en/policies/pod-security-cel/baseline/disallow-privileged-containers/disallow-privileged-containers.md index 475d256d4..d0476c17e 100644 --- a/content/en/policies/pod-security-cel/baseline/disallow-privileged-containers/disallow-privileged-containers.md +++ b/content/en/policies/pod-security-cel/baseline/disallow-privileged-containers/disallow-privileged-containers.md @@ -42,31 +42,11 @@ spec: - UPDATE validate: cel: + variables: + - name: allContainers + expression: "(object.spec.containers + (has(object.spec.initContainers) ? object.spec.initContainers : []) + (has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []))" expressions: - - expression: >- - object.spec.containers.all(container, !has(container.securityContext) || - !has(container.securityContext.privileged) || - container.securityContext.privileged == false) - message: >- - Privileged mode is disallowed. The fields spec.containers[*].securityContext.privileged - must be unset or set to `false`. - - - expression: >- - !has(object.spec.initContainers) || - object.spec.initContainers.all(container, !has(container.securityContext) || - !has(container.securityContext.privileged) || - container.securityContext.privileged == false) - message: >- - Privileged mode is disallowed. The fields spec.initContainers[*].securityContext.privileged - must be unset or set to `false`. - - - expression: >- - !has(object.spec.ephemeralContainers) || - object.spec.ephemeralContainers.all(container, !has(container.securityContext) || - !has(container.securityContext.privileged) || - container.securityContext.privileged == false) - message: >- - Privileged mode is disallowed. The fields spec.ephemeralContainers[*].securityContext.privileged - must be unset or set to `false`. + - expression: "variables.allContainers.all(container, container.?securityContext.?privileged.orValue(false) == false)" + message: "Privileged mode is disallowed. All containers must set the securityContext.privileged field to `false` or unset the field." ``` diff --git a/content/en/policies/pod-security-cel/baseline/disallow-proc-mount/disallow-proc-mount.md b/content/en/policies/pod-security-cel/baseline/disallow-proc-mount/disallow-proc-mount.md index 536457ada..04be35b23 100644 --- a/content/en/policies/pod-security-cel/baseline/disallow-proc-mount/disallow-proc-mount.md +++ b/content/en/policies/pod-security-cel/baseline/disallow-proc-mount/disallow-proc-mount.md @@ -44,31 +44,11 @@ spec: - UPDATE validate: cel: + variables: + - name: allContainers + expression: "(object.spec.containers + (has(object.spec.initContainers) ? object.spec.initContainers : []) + (has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []))" expressions: - - expression: >- - object.spec.containers.all(container, !has(container.securityContext) || - !has(container.securityContext.procMount) || - container.securityContext.procMount == 'Default') - message: >- - Changing the proc mount from the default is not allowed. The field - spec.containers[*].securityContext.procMount must be unset or set to `Default`. - - - expression: >- - !has(object.spec.initContainers) || - object.spec.initContainers.all(container, !has(container.securityContext) || - !has(container.securityContext.procMount) || - container.securityContext.procMount == 'Default') - message: >- - Changing the proc mount from the default is not allowed. The field - spec.initContainers[*].securityContext.procMount must be unset or set to `Default`. - - - expression: >- - !has(object.spec.ephemeralContainers) || - object.spec.ephemeralContainers.all(container, !has(container.securityContext) || - !has(container.securityContext.procMount) || - container.securityContext.procMount == 'Default') - message: >- - Changing the proc mount from the default is not allowed. The field - spec.ephemeralContainers[*].securityContext.procMount must be unset or set to `Default`. + - expression: "variables.allContainers.all(container, container.?securityContext.?procMount.orValue('Default') == 'Default')" + message: "Changing the proc mount from the default is not allowed." ``` diff --git a/content/en/policies/pod-security-cel/baseline/disallow-selinux/disallow-selinux.md b/content/en/policies/pod-security-cel/baseline/disallow-selinux/disallow-selinux.md index cdfa32589..e8ae833c4 100644 --- a/content/en/policies/pod-security-cel/baseline/disallow-selinux/disallow-selinux.md +++ b/content/en/policies/pod-security-cel/baseline/disallow-selinux/disallow-selinux.md @@ -42,52 +42,24 @@ spec: - UPDATE validate: cel: + variables: + - name: allContainerTypes + expression: "(object.spec.containers + (has(object.spec.initContainers) ? object.spec.initContainers : []) + (has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []))" + - name: seLinuxTypes + expression: "['container_t', 'container_init_t', 'container_kvm_t']" expressions: - - expression: >- - !has(object.spec.securityContext) || + - expression: >- + (!has(object.spec.securityContext) || !has(object.spec.securityContext.seLinuxOptions) || !has(object.spec.securityContext.seLinuxOptions.type) || - object.spec.securityContext.seLinuxOptions.type == 'container_t' || - object.spec.securityContext.seLinuxOptions.type == 'container_init_t' || - object.spec.securityContext.seLinuxOptions.type == 'container_kvm_t' - message: >- - Setting the SELinux type is restricted. The field spec.securityContext.seLinuxOptions.type - must either be unset or set to one of the allowed values (container_t, container_init_t, or container_kvm_t). - - - expression: >- - object.spec.containers.all(container, !has(container.securityContext) || - !has(container.securityContext.seLinuxOptions) || - !has(container.securityContext.seLinuxOptions.type) || - container.securityContext.seLinuxOptions.type == 'container_t' || - container.securityContext.seLinuxOptions.type == 'container_init_t' || - container.securityContext.seLinuxOptions.type == 'container_kvm_t') - message: >- - Setting the SELinux type is restricted. The field spec.containers[*].securityContext.seLinuxOptions.type - must either be unset or set to one of the allowed values (container_t, container_init_t, or container_kvm_t). - - - expression: >- - !has(object.spec.initContainers) || - object.spec.initContainers.all(container, !has(container.securityContext) || - !has(container.securityContext.seLinuxOptions) || - !has(container.securityContext.seLinuxOptions.type) || - container.securityContext.seLinuxOptions.type == 'container_t' || - container.securityContext.seLinuxOptions.type == 'container_init_t' || - container.securityContext.seLinuxOptions.type == 'container_kvm_t') - message: >- - Setting the SELinux type is restricted. The field spec.initContainers[*].securityContext.seLinuxOptions.type - must either be unset or set to one of the allowed values (container_t, container_init_t, or container_kvm_t). - - - expression: >- - !has(object.spec.ephemeralContainers) || - object.spec.ephemeralContainers.all(container, !has(container.securityContext) || + variables.seLinuxTypes.exists(type, type == object.spec.securityContext.seLinuxOptions.type)) && + variables.allContainerTypes.all(container, + !has(container.securityContext) || !has(container.securityContext.seLinuxOptions) || !has(container.securityContext.seLinuxOptions.type) || - container.securityContext.seLinuxOptions.type == 'container_t' || - container.securityContext.seLinuxOptions.type == 'container_init_t' || - container.securityContext.seLinuxOptions.type == 'container_kvm_t') + variables.seLinuxTypes.exists(type, type == container.securityContext.seLinuxOptions.type)) message: >- - Setting the SELinux type is restricted. The field spec.ephemeralContainers[*].securityContext.seLinuxOptions.type - must either be unset or set to one of the allowed values (container_t, container_init_t, or container_kvm_t). + Setting the SELinux type is restricted. The field securityContext.seLinuxOptions.type must either be unset or set to one of the allowed values (container_t, container_init_t, or container_kvm_t). - name: selinux-user-role match: any: @@ -99,39 +71,19 @@ spec: - UPDATE validate: cel: + variables: + - name: allContainerTypes + expression: "(object.spec.containers + (has(object.spec.initContainers) ? object.spec.initContainers : []) + (has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []))" expressions: - - expression: >- - !has(object.spec.securityContext) || + - expression: >- + (!has(object.spec.securityContext) || !has(object.spec.securityContext.seLinuxOptions) || - (!has(object.spec.securityContext.seLinuxOptions.user) && !has(object.spec.securityContext.seLinuxOptions.role)) - message: >- - Setting the SELinux user or role is forbidden. The fields - spec.securityContext.seLinuxOptions.user and spec.securityContext.seLinuxOptions.role must be unset. - - - expression: >- - object.spec.containers.all(container, !has(container.securityContext) || - !has(container.securityContext.seLinuxOptions) || - (!has(container.securityContext.seLinuxOptions.user) && !has(container.securityContext.seLinuxOptions.role))) - message: >- - Setting the SELinux user or role is forbidden. The fields - spec.containers[*].securityContext.seLinuxOptions.user and spec.containers[*].securityContext.seLinuxOptions.role must be unset. - - - expression: >- - !has(object.spec.initContainers) || - object.spec.initContainers.all(container, !has(container.securityContext) || - !has(container.securityContext.seLinuxOptions) || - (!has(container.securityContext.seLinuxOptions.user) && !has(container.securityContext.seLinuxOptions.role))) - message: >- - Setting the SELinux user or role is forbidden. The fields - spec.initContainers[*].securityContext.seLinuxOptions.user and spec.initContainers[*].securityContext.seLinuxOptions.role must be unset. - - - expression: >- - !has(object.spec.ephemeralContainers) || - object.spec.ephemeralContainers.all(container, !has(container.securityContext) || + (!has(object.spec.securityContext.seLinuxOptions.user) && !has(object.spec.securityContext.seLinuxOptions.role))) && + variables.allContainerTypes.all(container, + !has(container.securityContext) || !has(container.securityContext.seLinuxOptions) || (!has(container.securityContext.seLinuxOptions.user) && !has(container.securityContext.seLinuxOptions.role))) message: >- - Setting the SELinux user or role is forbidden. The fields - spec.ephemeralContainers[*].securityContext.seLinuxOptions.user and spec.ephemeralContainers[*].securityContext.seLinuxOptions.role must be unset. - + Setting the SELinux user or role is forbidden. The fields seLinuxOptions.user and seLinuxOptions.role must be unset. + ``` diff --git a/content/en/policies/pod-security-cel/baseline/restrict-seccomp/restrict-seccomp.md b/content/en/policies/pod-security-cel/baseline/restrict-seccomp/restrict-seccomp.md index dd85e0bf1..f0b113538 100644 --- a/content/en/policies/pod-security-cel/baseline/restrict-seccomp/restrict-seccomp.md +++ b/content/en/policies/pod-security-cel/baseline/restrict-seccomp/restrict-seccomp.md @@ -43,47 +43,20 @@ spec: - UPDATE validate: cel: + variables: + - name: allContainers + expression: "(object.spec.containers + (has(object.spec.initContainers) ? object.spec.initContainers : []) + (has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []))" + - name: allowedProfileTypes + expression: "['RuntimeDefault', 'Localhost']" expressions: - expression: >- - !has(object.spec.securityContext) || - !has(object.spec.securityContext.seccompProfile) || - !has(object.spec.securityContext.seccompProfile.type) || - object.spec.securityContext.seccompProfile.type == 'RuntimeDefault' || - object.spec.securityContext.seccompProfile.type == 'Localhost' - message: >- - Use of custom Seccomp profiles is disallowed. The field - spec.securityContext.seccompProfile.type must be unset or set to `RuntimeDefault` or `Localhost`. - - - expression: >- - object.spec.containers.all(container, !has(container.securityContext) || - !has(container.securityContext.seccompProfile) || - !has(container.securityContext.seccompProfile.type) || - container.securityContext.seccompProfile.type == 'RuntimeDefault' || - container.securityContext.seccompProfile.type == 'Localhost') + (object.spec.?securityContext.?seccompProfile.?type.orValue('Localhost') + in variables.allowedProfileTypes) && + (variables.allContainers.all(container, + container.?securityContext.?seccompProfile.?type.orValue('Localhost') + in variables.allowedProfileTypes)) message: >- Use of custom Seccomp profiles is disallowed. The field spec.containers[*].securityContext.seccompProfile.type must be unset or set to `RuntimeDefault` or `Localhost`. - - expression: >- - !has(object.spec.initContainers) || - object.spec.initContainers.all(container, !has(container.securityContext) || - !has(container.securityContext.seccompProfile) || - !has(container.securityContext.seccompProfile.type) || - container.securityContext.seccompProfile.type == 'RuntimeDefault' || - container.securityContext.seccompProfile.type == 'Localhost') - message: >- - Use of custom Seccomp profiles is disallowed. The field - spec.initContainers[*].securityContext.seccompProfile.type must be unset or set to `RuntimeDefault` or `Localhost`. - - - expression: >- - !has(object.spec.ephemeralContainers) || - object.spec.ephemeralContainers.all(container, !has(container.securityContext) || - !has(container.securityContext.seccompProfile) || - !has(container.securityContext.seccompProfile.type) || - container.securityContext.seccompProfile.type == 'RuntimeDefault' || - container.securityContext.seccompProfile.type == 'Localhost') - message: >- - Use of custom Seccomp profiles is disallowed. The field - spec.ephemeralContainers[*].securityContext.seccompProfile.type must be unset or set to `RuntimeDefault` or `Localhost`. - ``` diff --git a/content/en/policies/pod-security-cel/baseline/restrict-sysctls/restrict-sysctls.md b/content/en/policies/pod-security-cel/baseline/restrict-sysctls/restrict-sysctls.md index 47a68ccaa..acea8c77f 100644 --- a/content/en/policies/pod-security-cel/baseline/restrict-sysctls/restrict-sysctls.md +++ b/content/en/policies/pod-security-cel/baseline/restrict-sysctls/restrict-sysctls.md @@ -46,16 +46,13 @@ spec: - UPDATE validate: cel: + variables: + - name: allowedSysctls + expression: "['kernel.shm_rmid_forced','net.ipv4.ip_local_port_range','net.ipv4.ip_unprivileged_port_start','net.ipv4.tcp_syncookies','net.ipv4.ping_group_range']" expressions: - expression: >- - !has(object.spec.securityContext) || - !has(object.spec.securityContext.sysctls) || - object.spec.securityContext.sysctls.all(sysctl, !has(sysctl.name) || - sysctl.name == 'kernel.shm_rmid_forced' || - sysctl.name == 'net.ipv4.ip_local_port_range' || - sysctl.name == 'net.ipv4.ip_unprivileged_port_start' || - sysctl.name == 'net.ipv4.tcp_syncookies' || - sysctl.name == 'net.ipv4.ping_group_range') + object.spec.?securityContext.?sysctls.orValue([]).all(sysctl, sysctl == '' || + has(sysctl.name) && sysctl.name in variables.allowedSysctls) message: >- Setting additional sysctls above the allowed type is disallowed. The field spec.securityContext.sysctls must be unset or not use any other names diff --git a/content/en/policies/pod-security-cel/restricted/disallow-privilege-escalation/disallow-privilege-escalation.md b/content/en/policies/pod-security-cel/restricted/disallow-privilege-escalation/disallow-privilege-escalation.md index 5a546b099..d074b44f4 100644 --- a/content/en/policies/pod-security-cel/restricted/disallow-privilege-escalation/disallow-privilege-escalation.md +++ b/content/en/policies/pod-security-cel/restricted/disallow-privilege-escalation/disallow-privilege-escalation.md @@ -42,31 +42,18 @@ spec: - UPDATE validate: cel: + variables: + - name: allContainers + expression: >- + object.spec.containers + + object.spec.?initContainers.orValue([]) + + object.spec.?ephemeralContainers.orValue([]) expressions: - expression: >- - object.spec.containers.all(container, has(container.securityContext) && - has(container.securityContext.allowPrivilegeEscalation) && - container.securityContext.allowPrivilegeEscalation == false) + variables.allContainers.all(container, + container.?securityContext.allowPrivilegeEscalation.orValue(true) == false) message: >- - Privilege escalation is disallowed. The field - spec.containers[*].securityContext.allowPrivilegeEscalation must be set to `false`. + Privilege escalation is disallowed. + All containers must set the securityContext.allowPrivilegeEscalation field to `false`. - - expression: >- - !has(object.spec.initContainers) || - object.spec.initContainers.all(container, has(container.securityContext) && - has(container.securityContext.allowPrivilegeEscalation) && - container.securityContext.allowPrivilegeEscalation == false) - message: >- - Privilege escalation is disallowed. The field - spec.initContainers[*].securityContext.allowPrivilegeEscalation must be set to `false`. - - - expression: >- - !has(object.spec.ephemeralContainers) || - object.spec.ephemeralContainers.all(container, has(container.securityContext) && - has(container.securityContext.allowPrivilegeEscalation) && - container.securityContext.allowPrivilegeEscalation == false) - message: >- - Privilege escalation is disallowed. The field - spec.ephemeralContainers[*].securityContext.allowPrivilegeEscalation must be set to `false`. - ``` diff --git a/content/en/policies/pod-security/baseline/disallow-capabilities/disallow-capabilities.md b/content/en/policies/pod-security/baseline/disallow-capabilities/disallow-capabilities.md index e60a26e1c..bd59988aa 100644 --- a/content/en/policies/pod-security/baseline/disallow-capabilities/disallow-capabilities.md +++ b/content/en/policies/pod-security/baseline/disallow-capabilities/disallow-capabilities.md @@ -27,7 +27,7 @@ metadata: policies.kyverno.io/description: >- Adding capabilities beyond those listed in the policy must be disallowed. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: adding-capabilities diff --git a/content/en/policies/pod-security/baseline/disallow-host-namespaces/disallow-host-namespaces.md b/content/en/policies/pod-security/baseline/disallow-host-namespaces/disallow-host-namespaces.md index e1d1c2950..1701b4cde 100644 --- a/content/en/policies/pod-security/baseline/disallow-host-namespaces/disallow-host-namespaces.md +++ b/content/en/policies/pod-security/baseline/disallow-host-namespaces/disallow-host-namespaces.md @@ -29,7 +29,7 @@ metadata: privileges. Pods should not be allowed access to host namespaces. This policy ensures fields which make use of these host namespaces are unset or set to `false`. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: host-namespaces diff --git a/content/en/policies/pod-security/baseline/disallow-host-path/disallow-host-path.md b/content/en/policies/pod-security/baseline/disallow-host-path/disallow-host-path.md index 71e55404e..0b9ef495e 100644 --- a/content/en/policies/pod-security/baseline/disallow-host-path/disallow-host-path.md +++ b/content/en/policies/pod-security/baseline/disallow-host-path/disallow-host-path.md @@ -28,7 +28,7 @@ metadata: Using host resources can be used to access shared data or escalate privileges and should not be allowed. This policy ensures no hostPath volumes are in use. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: host-path diff --git a/content/en/policies/pod-security/baseline/disallow-host-ports-range/disallow-host-ports-range.md b/content/en/policies/pod-security/baseline/disallow-host-ports-range/disallow-host-ports-range.md index ca6b36269..888163a72 100644 --- a/content/en/policies/pod-security/baseline/disallow-host-ports-range/disallow-host-ports-range.md +++ b/content/en/policies/pod-security/baseline/disallow-host-ports-range/disallow-host-ports-range.md @@ -31,7 +31,7 @@ metadata: or to a value of zero. This policy is mutually exclusive of the disallow-host-ports policy. Note that Kubernetes Pod Security Admission does not support the host port range rule. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: host-port-range diff --git a/content/en/policies/pod-security/baseline/disallow-host-ports/disallow-host-ports.md b/content/en/policies/pod-security/baseline/disallow-host-ports/disallow-host-ports.md index a389b4e7c..e5a00e1f1 100644 --- a/content/en/policies/pod-security/baseline/disallow-host-ports/disallow-host-ports.md +++ b/content/en/policies/pod-security/baseline/disallow-host-ports/disallow-host-ports.md @@ -28,7 +28,7 @@ metadata: allowed, or at minimum restricted to a known list. This policy ensures the `hostPort` field is unset or set to `0`. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: host-ports-none diff --git a/content/en/policies/pod-security/baseline/disallow-host-process/disallow-host-process.md b/content/en/policies/pod-security/baseline/disallow-host-process/disallow-host-process.md index 0974c4591..ae00d010a 100644 --- a/content/en/policies/pod-security/baseline/disallow-host-process/disallow-host-process.md +++ b/content/en/policies/pod-security/baseline/disallow-host-process/disallow-host-process.md @@ -29,7 +29,7 @@ metadata: policy. HostProcess pods are an alpha feature as of Kubernetes v1.22. This policy ensures the `hostProcess` field, if present, is set to `false`. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: host-process-containers diff --git a/content/en/policies/pod-security/baseline/disallow-privileged-containers/disallow-privileged-containers.md b/content/en/policies/pod-security/baseline/disallow-privileged-containers/disallow-privileged-containers.md index 007728d4c..9e24db2c0 100644 --- a/content/en/policies/pod-security/baseline/disallow-privileged-containers/disallow-privileged-containers.md +++ b/content/en/policies/pod-security/baseline/disallow-privileged-containers/disallow-privileged-containers.md @@ -27,7 +27,7 @@ metadata: Privileged mode disables most security mechanisms and must not be allowed. This policy ensures Pods do not call for privileged mode. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: privileged-containers diff --git a/content/en/policies/pod-security/baseline/disallow-proc-mount/disallow-proc-mount.md b/content/en/policies/pod-security/baseline/disallow-proc-mount/disallow-proc-mount.md index 1b5043216..ca0ca7143 100644 --- a/content/en/policies/pod-security/baseline/disallow-proc-mount/disallow-proc-mount.md +++ b/content/en/policies/pod-security/baseline/disallow-proc-mount/disallow-proc-mount.md @@ -29,7 +29,7 @@ metadata: to deviate from the `Default` procMount requires setting a feature gate at the API server. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: check-proc-mount diff --git a/content/en/policies/pod-security/baseline/disallow-selinux/disallow-selinux.md b/content/en/policies/pod-security/baseline/disallow-selinux/disallow-selinux.md index 31b673a2c..4a095653d 100644 --- a/content/en/policies/pod-security/baseline/disallow-selinux/disallow-selinux.md +++ b/content/en/policies/pod-security/baseline/disallow-selinux/disallow-selinux.md @@ -27,7 +27,7 @@ metadata: SELinux options can be used to escalate privileges and should not be allowed. This policy ensures that the `seLinuxOptions` field is undefined. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: selinux-type diff --git a/content/en/policies/pod-security/baseline/restrict-apparmor-profiles/restrict-apparmor-profiles.md b/content/en/policies/pod-security/baseline/restrict-apparmor-profiles/restrict-apparmor-profiles.md index 30b81af49..871984e3a 100644 --- a/content/en/policies/pod-security/baseline/restrict-apparmor-profiles/restrict-apparmor-profiles.md +++ b/content/en/policies/pod-security/baseline/restrict-apparmor-profiles/restrict-apparmor-profiles.md @@ -30,7 +30,7 @@ metadata: overrides to an allowed set of profiles. This policy ensures Pods do not specify any other AppArmor profiles than `runtime/default` or `localhost/*`. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: app-armor diff --git a/content/en/policies/pod-security/baseline/restrict-seccomp/restrict-seccomp.md b/content/en/policies/pod-security/baseline/restrict-seccomp/restrict-seccomp.md index b751ba733..04c0e29bd 100644 --- a/content/en/policies/pod-security/baseline/restrict-seccomp/restrict-seccomp.md +++ b/content/en/policies/pod-security/baseline/restrict-seccomp/restrict-seccomp.md @@ -29,7 +29,7 @@ metadata: set to `RuntimeDefault` or `Localhost`. spec: background: true - validationFailureAction: audit + validationFailureAction: Audit rules: - name: check-seccomp match: diff --git a/content/en/policies/pod-security/baseline/restrict-sysctls/restrict-sysctls.md b/content/en/policies/pod-security/baseline/restrict-sysctls/restrict-sysctls.md index 1b5d04239..c51108594 100644 --- a/content/en/policies/pod-security/baseline/restrict-sysctls/restrict-sysctls.md +++ b/content/en/policies/pod-security/baseline/restrict-sysctls/restrict-sysctls.md @@ -31,7 +31,7 @@ metadata: This policy ensures that only those "safe" subsets can be specified in a Pod. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: check-sysctls diff --git a/content/en/policies/pod-security/restricted/disallow-capabilities-strict/disallow-capabilities-strict.md b/content/en/policies/pod-security/restricted/disallow-capabilities-strict/disallow-capabilities-strict.md index 7f1d0cdc2..219f0b5ed 100644 --- a/content/en/policies/pod-security/restricted/disallow-capabilities-strict/disallow-capabilities-strict.md +++ b/content/en/policies/pod-security/restricted/disallow-capabilities-strict/disallow-capabilities-strict.md @@ -28,7 +28,7 @@ metadata: Adding capabilities other than `NET_BIND_SERVICE` is disallowed. In addition, all containers must explicitly drop `ALL` capabilities. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: require-drop-all diff --git a/content/en/policies/pod-security/restricted/disallow-privilege-escalation/disallow-privilege-escalation.md b/content/en/policies/pod-security/restricted/disallow-privilege-escalation/disallow-privilege-escalation.md index 23c9c026e..1a89adcc4 100644 --- a/content/en/policies/pod-security/restricted/disallow-privilege-escalation/disallow-privilege-escalation.md +++ b/content/en/policies/pod-security/restricted/disallow-privilege-escalation/disallow-privilege-escalation.md @@ -27,7 +27,7 @@ metadata: Privilege escalation, such as via set-user-ID or set-group-ID file mode, should not be allowed. This policy ensures the `allowPrivilegeEscalation` field is set to `false`. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: privilege-escalation diff --git a/content/en/policies/pod-security/restricted/require-run-as-non-root-user/require-run-as-non-root-user.md b/content/en/policies/pod-security/restricted/require-run-as-non-root-user/require-run-as-non-root-user.md index 9c70477b6..87c88ea99 100644 --- a/content/en/policies/pod-security/restricted/require-run-as-non-root-user/require-run-as-non-root-user.md +++ b/content/en/policies/pod-security/restricted/require-run-as-non-root-user/require-run-as-non-root-user.md @@ -27,7 +27,7 @@ metadata: Containers must be required to run as non-root users. This policy ensures `runAsUser` is either unset or set to a number greater than zero. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: run-as-non-root-user diff --git a/content/en/policies/pod-security/restricted/require-run-as-nonroot/require-run-as-nonroot.md b/content/en/policies/pod-security/restricted/require-run-as-nonroot/require-run-as-nonroot.md index b000fbd9a..712306b4f 100644 --- a/content/en/policies/pod-security/restricted/require-run-as-nonroot/require-run-as-nonroot.md +++ b/content/en/policies/pod-security/restricted/require-run-as-nonroot/require-run-as-nonroot.md @@ -28,7 +28,7 @@ metadata: `runAsNonRoot` is set to `true`. A known issue prevents a policy such as this using `anyPattern` from being persisted properly in Kubernetes 1.23.0-1.23.2. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: run-as-non-root diff --git a/content/en/policies/pod-security/restricted/restrict-seccomp-strict/restrict-seccomp-strict.md b/content/en/policies/pod-security/restricted/restrict-seccomp-strict/restrict-seccomp-strict.md index 64179b5a7..5b2ab572b 100644 --- a/content/en/policies/pod-security/restricted/restrict-seccomp-strict/restrict-seccomp-strict.md +++ b/content/en/policies/pod-security/restricted/restrict-seccomp-strict/restrict-seccomp-strict.md @@ -31,7 +31,7 @@ metadata: using `anyPattern` from being persisted properly in Kubernetes 1.23.0-1.23.2. spec: background: true - validationFailureAction: audit + validationFailureAction: Audit rules: - name: check-seccomp-strict match: diff --git a/content/en/policies/pod-security/restricted/restrict-volume-types/restrict-volume-types.md b/content/en/policies/pod-security/restricted/restrict-volume-types/restrict-volume-types.md index f4e4d0614..1a7b6a748 100644 --- a/content/en/policies/pod-security/restricted/restrict-volume-types/restrict-volume-types.md +++ b/content/en/policies/pod-security/restricted/restrict-volume-types/restrict-volume-types.md @@ -29,7 +29,7 @@ metadata: limits usage of non-core volume types to those defined through PersistentVolumes. This policy blocks any other type of volume other than those in the allow list. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: restricted-volumes diff --git a/content/en/policies/pod-security/subrule/podsecurity-subrule-baseline/podsecurity-subrule-baseline.md b/content/en/policies/pod-security/subrule/podsecurity-subrule-baseline/podsecurity-subrule-baseline.md index 4b57df84e..051b8f9e9 100644 --- a/content/en/policies/pod-security/subrule/podsecurity-subrule-baseline/podsecurity-subrule-baseline.md +++ b/content/en/policies/pod-security/subrule/podsecurity-subrule-baseline/podsecurity-subrule-baseline.md @@ -32,7 +32,7 @@ metadata: version of the Pod Security Standards cluster wide. spec: background: true - validationFailureAction: audit + validationFailureAction: Audit rules: - name: baseline match: diff --git a/content/en/policies/pod-security/subrule/restricted/restricted-exclude-capabilities/restricted-exclude-capabilities.md b/content/en/policies/pod-security/subrule/restricted/restricted-exclude-capabilities/restricted-exclude-capabilities.md index c1a7bcf1f..6c6fb6ea2 100644 --- a/content/en/policies/pod-security/subrule/restricted/restricted-exclude-capabilities/restricted-exclude-capabilities.md +++ b/content/en/policies/pod-security/subrule/restricted/restricted-exclude-capabilities/restricted-exclude-capabilities.md @@ -34,7 +34,7 @@ metadata: exempting `nginx` and `redis` container images from the Capabilities control check. spec: background: true - validationFailureAction: enforce + validationFailureAction: Enforce rules: - name: restricted-exempt-capabilities match: @@ -49,6 +49,6 @@ spec: exclude: - controlName: Capabilities images: - - nginx* + - ghcr.io/kyverno/test-nginx* - redis* ``` diff --git a/content/en/policies/pod-security/subrule/restricted/restricted-exclude-seccomp/restricted-exclude-seccomp.md b/content/en/policies/pod-security/subrule/restricted/restricted-exclude-seccomp/restricted-exclude-seccomp.md index d8d6ea216..fb10373ad 100644 --- a/content/en/policies/pod-security/subrule/restricted/restricted-exclude-seccomp/restricted-exclude-seccomp.md +++ b/content/en/policies/pod-security/subrule/restricted/restricted-exclude-seccomp/restricted-exclude-seccomp.md @@ -34,7 +34,7 @@ metadata: completely exempting Seccomp control check. spec: background: true - validationFailureAction: enforce + validationFailureAction: Enforce rules: - name: restricted-exempt-seccomp match: diff --git a/content/en/policies/pod-security/subrule/restricted/restricted-latest/restricted-latest.md b/content/en/policies/pod-security/subrule/restricted/restricted-latest/restricted-latest.md index 801d28b1b..422a7e5e1 100644 --- a/content/en/policies/pod-security/subrule/restricted/restricted-latest/restricted-latest.md +++ b/content/en/policies/pod-security/subrule/restricted/restricted-latest/restricted-latest.md @@ -32,7 +32,7 @@ metadata: restricted profile through the latest version of the Pod Security Standards cluster wide. spec: background: true - validationFailureAction: audit + validationFailureAction: Audit rules: - name: restricted match: diff --git a/content/en/policies/psa-cel/add-psa-namespace-reporting/add-psa-namespace-reporting.md b/content/en/policies/psa-cel/add-psa-namespace-reporting/add-psa-namespace-reporting.md new file mode 100644 index 000000000..c2c2ae947 --- /dev/null +++ b/content/en/policies/psa-cel/add-psa-namespace-reporting/add-psa-namespace-reporting.md @@ -0,0 +1,58 @@ +--- +title: "Add PSA Namespace Reporting in CEL expressions" +category: Pod Security Admission, EKS Best Practices in CEL +version: 1.11.0 +subject: Namespace +policyType: "validate" +description: > + This policy is valuable as it ensures that all namespaces within a Kubernetes cluster are labeled with Pod Security Admission (PSA) labels, which are crucial for defining security levels and ensuring that pods within a namespace operate under the defined Pod Security Standard (PSS). By enforcing namespace labeling, This policy audits namespaces to verify the presence of PSA labels. If a namespace is found without the required labels, it generates and maintain and ClusterPolicy Report in default namespace. This helps administrators identify namespaces that do not comply with the organization's security practices and take appropriate action to rectify the situation. +--- + +## Policy Definition +/psa-cel/add-psa-namespace-reporting/add-psa-namespace-reporting.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: add-psa-namespace-reporting + annotations: + policies.kyverno.io/title: Add PSA Namespace Reporting in CEL expressions + policies.kyverno.io/category: Pod Security Admission, EKS Best Practices in CEL + policies.kyverno.io/severity: medium + kyverno.io/kyverno-version: 1.11.0 + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/subject: Namespace + policies.kyverno.io/description: >- + This policy is valuable as it ensures that all namespaces within a Kubernetes + cluster are labeled with Pod Security Admission (PSA) labels, which are crucial + for defining security levels and ensuring that pods within a namespace operate + under the defined Pod Security Standard (PSS). By enforcing namespace labeling, + This policy audits namespaces to verify the presence of PSA labels. + If a namespace is found without the required labels, it generates and maintain + and ClusterPolicy Report in default namespace. + This helps administrators identify namespaces that do not comply with the + organization's security practices and take appropriate action to rectify the + situation. +spec: + validationFailureAction: Audit + background: true + rules: + - name: check-namespace-labels + match: + any: + - resources: + kinds: + - Namespace + operations: + - CREATE + - UPDATE + validate: + cel: + expressions: + - expression: "object.metadata.?labels.orValue([]).exists(label, label.startsWith('pod-security.kubernetes.io/') && object.metadata.labels[label] != '')" + message: This Namespace is missing a PSA label. + + +``` diff --git a/content/en/policies/psa-cel/deny-privileged-profile/deny-privileged-profile.md b/content/en/policies/psa-cel/deny-privileged-profile/deny-privileged-profile.md new file mode 100644 index 000000000..ff94bd21c --- /dev/null +++ b/content/en/policies/psa-cel/deny-privileged-profile/deny-privileged-profile.md @@ -0,0 +1,60 @@ +--- +title: "Deny Privileged Profile in CEL expressions" +category: Pod Security Admission in CEL expressions +version: 1.11.0 +subject: Namespace +policyType: "validate" +description: > + When Pod Security Admission (PSA) is enforced at the cluster level via an AdmissionConfiguration file which defines a default level at baseline or restricted, setting of a label at the `privileged` profile will effectively cause unrestricted workloads in that Namespace, overriding the cluster default. This may effectively represent a circumvention attempt and should be closely controlled. This policy ensures that only those holding the cluster-admin ClusterRole may create Namespaces which assign the label `pod-security.kubernetes.io/enforce=privileged`. +--- + +## Policy Definition +/psa-cel/deny-privileged-profile/deny-privileged-profile.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: deny-privileged-profile + annotations: + policies.kyverno.io/title: Deny Privileged Profile in CEL expressions + policies.kyverno.io/category: Pod Security Admission in CEL expressions + policies.kyverno.io/severity: medium + kyverno.io/kyverno-version: 1.11.0 + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/subject: Namespace + policies.kyverno.io/description: >- + When Pod Security Admission (PSA) is enforced at the cluster level + via an AdmissionConfiguration file which defines a default level at + baseline or restricted, setting of a label at the `privileged` profile + will effectively cause unrestricted workloads in that Namespace, overriding + the cluster default. This may effectively represent a circumvention attempt + and should be closely controlled. This policy ensures that only those holding + the cluster-admin ClusterRole may create Namespaces which assign the label + `pod-security.kubernetes.io/enforce=privileged`. +spec: + validationFailureAction: Audit + background: false + rules: + - name: check-privileged + match: + any: + - resources: + kinds: + - Namespace + selector: + matchLabels: + pod-security.kubernetes.io/enforce: privileged + exclude: + any: + - clusterRoles: + - cluster-admin + validate: + cel: + expressions: + - expression: "false" + message: Only cluster-admins may create Namespaces that allow setting the privileged level. + + +``` diff --git a/content/en/policies/psa/add-psa-namespace-reporting/add-psa-namespace-reporting.md b/content/en/policies/psa/add-psa-namespace-reporting/add-psa-namespace-reporting.md index fd952be6a..5986ed035 100644 --- a/content/en/policies/psa/add-psa-namespace-reporting/add-psa-namespace-reporting.md +++ b/content/en/policies/psa/add-psa-namespace-reporting/add-psa-namespace-reporting.md @@ -36,7 +36,7 @@ metadata: organization's security practices and take appropriate action to rectify the situation. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: check-namespace-labels diff --git a/content/en/policies/psa/deny-privileged-profile/deny-privileged-profile.md b/content/en/policies/psa/deny-privileged-profile/deny-privileged-profile.md index 2fd89145d..8010da33b 100644 --- a/content/en/policies/psa/deny-privileged-profile/deny-privileged-profile.md +++ b/content/en/policies/psa/deny-privileged-profile/deny-privileged-profile.md @@ -34,7 +34,7 @@ metadata: the cluster-admin ClusterRole may create Namespaces which assign the label `pod-security.kubernetes.io/enforce=privileged`. spec: - validationFailureAction: audit + validationFailureAction: Audit background: false rules: - name: check-privileged diff --git a/content/en/policies/psp-migration-cel/check-supplemental-groups/check-supplemental-groups.md b/content/en/policies/psp-migration-cel/check-supplemental-groups/check-supplemental-groups.md new file mode 100644 index 000000000..38536ad1c --- /dev/null +++ b/content/en/policies/psp-migration-cel/check-supplemental-groups/check-supplemental-groups.md @@ -0,0 +1,53 @@ +--- +title: "Check supplementalGroups in CEL expressions" +category: PSP Migration in CEL +version: 1.11.0 +subject: Pod +policyType: "validate" +description: > + Supplemental groups control which group IDs containers add and can coincide with restricted groups on the host. Pod Security Policies (PSP) allowed a range of these group IDs to be specified which were allowed. This policy ensures any Pod may only specify supplementalGroup IDs between 100-200 or 500-600. +--- + +## Policy Definition +/psp-migration-cel/check-supplemental-groups/check-supplemental-groups.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: psp-check-supplemental-groups + annotations: + policies.kyverno.io/title: Check supplementalGroups in CEL expressions + policies.kyverno.io/category: PSP Migration in CEL + policies.kyverno.io/severity: medium + kyverno.io/kyverno-version: 1.11.0 + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/subject: Pod + policies.kyverno.io/description: >- + Supplemental groups control which group IDs containers add and can coincide with + restricted groups on the host. Pod Security Policies (PSP) allowed a range of + these group IDs to be specified which were allowed. This policy ensures any Pod + may only specify supplementalGroup IDs between 100-200 or 500-600. +spec: + background: false + validationFailureAction: Audit + rules: + - name: supplementalgroup-ranges + match: + any: + - resources: + kinds: + - Pod + operations: + - CREATE + - UPDATE + validate: + cel: + expressions: + - expression: >- + object.spec.?securityContext.?supplementalGroups.orValue([]).all(supplementalGroup, (supplementalGroup >= 100 && supplementalGroup <= 200) || (supplementalGroup >= 500 && supplementalGroup <= 600)) + message: Any supplementalGroup ID must be within the range 100-200 or 500-600. + + +``` diff --git a/content/en/policies/psp-migration-cel/restrict-adding-capabilities/restrict-adding-capabilities.md b/content/en/policies/psp-migration-cel/restrict-adding-capabilities/restrict-adding-capabilities.md new file mode 100644 index 000000000..e63fd2a84 --- /dev/null +++ b/content/en/policies/psp-migration-cel/restrict-adding-capabilities/restrict-adding-capabilities.md @@ -0,0 +1,62 @@ +--- +title: "Restrict Adding Capabilities in CEL expressions" +category: PSP Migration in CEL +version: 1.11.0 +subject: Pod +policyType: "validate" +description: > + Adding capabilities is a way for containers in a Pod to request higher levels of ability than those with which they may be provisioned. Many capabilities allow system-level control and should be prevented. Pod Security Policies (PSP) allowed a list of "good" capabilities to be added. This policy checks ephemeralContainers, initContainers, and containers to ensure the only capabilities that can be added are either NET_BIND_SERVICE or CAP_CHOWN. +--- + +## Policy Definition +/psp-migration-cel/restrict-adding-capabilities/restrict-adding-capabilities.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: psp-restrict-adding-capabilities + annotations: + policies.kyverno.io/title: Restrict Adding Capabilities in CEL expressions + policies.kyverno.io/category: PSP Migration in CEL + policies.kyverno.io/severity: medium + kyverno.io/kyverno-version: 1.11.0 + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/subject: Pod + policies.kyverno.io/description: >- + Adding capabilities is a way for containers in a Pod to request higher levels + of ability than those with which they may be provisioned. Many capabilities + allow system-level control and should be prevented. Pod Security Policies (PSP) + allowed a list of "good" capabilities to be added. This policy checks + ephemeralContainers, initContainers, and containers to ensure the only + capabilities that can be added are either NET_BIND_SERVICE or CAP_CHOWN. +spec: + validationFailureAction: Audit + background: true + rules: + - name: allowed-capabilities + match: + any: + - resources: + kinds: + - Pod + operations: + - CREATE + - UPDATE + validate: + cel: + variables: + - name: allContainers + expression: "object.spec.containers + object.spec.?initContainers.orValue([]) + object.spec.?ephemeralContainers.orValue([])" + - name: allowedCapabilities + expression: "['NET_BIND_SERVICE', 'CAP_CHOWN']" + expressions: + - expression: >- + variables.allContainers.all(container, + container.?securityContext.?capabilities.?add.orValue([]).all(capability, capability in variables.allowedCapabilities)) + message: >- + Any capabilities added other than NET_BIND_SERVICE or CAP_CHOWN are disallowed. + + +``` diff --git a/content/en/policies/psp-migration-cel/restrict-runtimeClassName/restrict-runtimeClassName.md b/content/en/policies/psp-migration-cel/restrict-runtimeClassName/restrict-runtimeClassName.md new file mode 100644 index 000000000..f82430845 --- /dev/null +++ b/content/en/policies/psp-migration-cel/restrict-runtimeClassName/restrict-runtimeClassName.md @@ -0,0 +1,52 @@ +--- +title: "Restrict runtimeClass in CEL expressions" +category: PSP Migration in CEL +version: +subject: Pod +policyType: "validate" +description: > + The runtimeClass field of a Pod spec defines which container engine runtime should be used. In the previous Pod Security Policy controller, defining restrictions on which classes were allowed was permitted. Limiting runtime classes to only those which have been defined can prevent unintended running states or Pods which may not come online. This policy restricts the runtimeClass field to the values `prodclass` or `expclass`. +--- + +## Policy Definition +/psp-migration-cel/restrict-runtimeClassName/restrict-runtimeClassName.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-runtimeclass + annotations: + policies.kyverno.io/title: Restrict runtimeClass in CEL expressions + policies.kyverno.io/category: PSP Migration in CEL + policies.kyverno.io/subject: Pod + kyverno.io/kyverno-version: 1.12.1 + kyverno.io/kubernetes-version: "1.26-1.27" + pod-policies.kyverno.io/autogen-controllers: none + policies.kyverno.io/description: >- + The runtimeClass field of a Pod spec defines which container engine runtime should be used. + In the previous Pod Security Policy controller, defining restrictions on which classes were allowed + was permitted. Limiting runtime classes to only those which have been defined can prevent + unintended running states or Pods which may not come online. This policy restricts the runtimeClass + field to the values `prodclass` or `expclass`. +spec: + validationFailureAction: Enforce + background: false + rules: + - name: prodclass-or-expclass + match: + any: + - resources: + kinds: + - Pod + celPreconditions: + - name: "operation-should-be-create" + expression: "request.operation == 'CREATE'" + validate: + cel: + expressions: + - expression: "!has(object.spec.runtimeClassName) || object.spec.runtimeClassName in ['prodclass', 'expclass']" + message: Only the runtime classes prodclass or expclass may be used. + + +``` diff --git a/content/en/policies/psp-migration/check-supplemental-groups/check-supplemental-groups.md b/content/en/policies/psp-migration/check-supplemental-groups/check-supplemental-groups.md index 022258ea8..723c37790 100644 --- a/content/en/policies/psp-migration/check-supplemental-groups/check-supplemental-groups.md +++ b/content/en/policies/psp-migration/check-supplemental-groups/check-supplemental-groups.md @@ -31,7 +31,7 @@ metadata: may only specify supplementalGroup IDs between 100-200 or 500-600. spec: background: false - validationFailureAction: audit + validationFailureAction: Audit rules: - name: supplementalgroup-ranges match: diff --git a/content/en/policies/psp-migration/restrict-adding-capabilities/restrict-adding-capabilities.md b/content/en/policies/psp-migration/restrict-adding-capabilities/restrict-adding-capabilities.md index 3d8ba2f3a..c8b679276 100644 --- a/content/en/policies/psp-migration/restrict-adding-capabilities/restrict-adding-capabilities.md +++ b/content/en/policies/psp-migration/restrict-adding-capabilities/restrict-adding-capabilities.md @@ -32,7 +32,7 @@ metadata: ephemeralContainers, initContainers, and containers to ensure the only capabilities that can be added are either NET_BIND_SERVICE or CAP_CHOWN. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: allowed-capabilities diff --git a/content/en/policies/tekton-cel/block-tekton-task-runs/block-tekton-task-runs.md b/content/en/policies/tekton-cel/block-tekton-task-runs/block-tekton-task-runs.md new file mode 100644 index 000000000..d969f7290 --- /dev/null +++ b/content/en/policies/tekton-cel/block-tekton-task-runs/block-tekton-task-runs.md @@ -0,0 +1,54 @@ +--- +title: "Block Tekton TaskRun in CEL expressions" +category: Tekton in CEL +version: 1.11.0 +subject: TaskRun +policyType: "validate" +description: > + Restrict creation of TaskRun resources to the Tekton pipelines controller. +--- + +## Policy Definition +/tekton-cel/block-tekton-task-runs/block-tekton-task-runs.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: block-tekton-task-runs + annotations: + policies.kyverno.io/title: Block Tekton TaskRun in CEL expressions + policies.kyverno.io/category: Tekton in CEL + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: TaskRun + kyverno.io/kyverno-version: 1.11.0 + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/description: >- + Restrict creation of TaskRun resources to the Tekton pipelines controller. +spec: + validationFailureAction: Audit + background: false + rules: + - name: check-taskrun-user + match: + any: + - resources: + kinds: + - TaskRun + operations: + - CREATE + - UPDATE + exclude: + any: + - subjects: + - kind: User + name: "system:serviceaccount:tekton-pipelines:tekton-pipelines-controller" + validate: + cel: + expressions: + - expression: "false" + message: Creating a TaskRun is not allowed. + + +``` diff --git a/content/en/policies/tekton-cel/require-tekton-bundle/require-tekton-bundle.md b/content/en/policies/tekton-cel/require-tekton-bundle/require-tekton-bundle.md new file mode 100644 index 000000000..161cdced2 --- /dev/null +++ b/content/en/policies/tekton-cel/require-tekton-bundle/require-tekton-bundle.md @@ -0,0 +1,63 @@ +--- +title: "Require Tekton Bundle in CEL expressions" +category: Tekton in CEL +version: 1.11.0 +subject: TaskRun, PipelineRun +policyType: "validate" +description: > + PipelineRun and TaskRun resources must be executed from a bundle +--- + +## Policy Definition +/tekton-cel/require-tekton-bundle/require-tekton-bundle.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: require-tekton-bundle + annotations: + policies.kyverno.io/title: Require Tekton Bundle in CEL expressions + policies.kyverno.io/category: Tekton in CEL + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: TaskRun, PipelineRun + kyverno.io/kyverno-version: 1.11.0 + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/description: >- + PipelineRun and TaskRun resources must be executed from a bundle +spec: + validationFailureAction: Audit + background: true + rules: + - name: check-bundle-pipelinerun + match: + any: + - resources: + kinds: + - PipelineRun + operations: + - CREATE + - UPDATE + validate: + cel: + expressions: + - expression: "object.spec.?pipelineRef.?bundle.orValue('') != ''" + message: "A bundle is required." + - name: check-bundle-taskrun + match: + any: + - resources: + kinds: + - TaskRun + operations: + - CREATE + - UPDATE + validate: + cel: + expressions: + - expression: "object.spec.?taskRef.?bundle.orValue('') != ''" + message: "A bundle is required." + + +``` diff --git a/content/en/policies/tekton/block-tekton-task-runs/block-tekton-task-runs.md b/content/en/policies/tekton/block-tekton-task-runs/block-tekton-task-runs.md index 2196ec9fd..fea5b0982 100644 --- a/content/en/policies/tekton/block-tekton-task-runs/block-tekton-task-runs.md +++ b/content/en/policies/tekton/block-tekton-task-runs/block-tekton-task-runs.md @@ -27,7 +27,7 @@ metadata: policies.kyverno.io/description: >- Restrict creation of TaskRun resources to the Tekton pipelines controller. spec: - validationFailureAction: audit + validationFailureAction: Audit background: false rules: - name: check-taskrun-user diff --git a/content/en/policies/tekton/require-tekton-bundle/require-tekton-bundle.md b/content/en/policies/tekton/require-tekton-bundle/require-tekton-bundle.md index c92fe0c6b..fa62c31d6 100644 --- a/content/en/policies/tekton/require-tekton-bundle/require-tekton-bundle.md +++ b/content/en/policies/tekton/require-tekton-bundle/require-tekton-bundle.md @@ -27,7 +27,7 @@ metadata: policies.kyverno.io/description: >- PipelineRun and TaskRun resources must be executed from a bundle spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: check-bundle-pipelinerun diff --git a/content/en/policies/tekton/require-tekton-namespace-pipelinerun/require-tekton-namespace-pipelinerun.md b/content/en/policies/tekton/require-tekton-namespace-pipelinerun/require-tekton-namespace-pipelinerun.md index e27b9d730..706c952f8 100644 --- a/content/en/policies/tekton/require-tekton-namespace-pipelinerun/require-tekton-namespace-pipelinerun.md +++ b/content/en/policies/tekton/require-tekton-namespace-pipelinerun/require-tekton-namespace-pipelinerun.md @@ -27,7 +27,7 @@ metadata: policies.kyverno.io/description: >- A Namespace is required for a PipelineRun and may not be set to `default`. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: check-pipelinerun-namespace diff --git a/content/en/policies/tekton/require-tekton-securitycontext/require-tekton-securitycontext.md b/content/en/policies/tekton/require-tekton-securitycontext/require-tekton-securitycontext.md index 1ab05ca55..a2c111ef0 100644 --- a/content/en/policies/tekton/require-tekton-securitycontext/require-tekton-securitycontext.md +++ b/content/en/policies/tekton/require-tekton-securitycontext/require-tekton-securitycontext.md @@ -27,7 +27,7 @@ metadata: policies.kyverno.io/description: >- A securityContext is required for each TaskRun step. spec: - validationFailureAction: audit + validationFailureAction: Audit background: true rules: - name: check-step-securitycontext diff --git a/content/en/policies/tekton/verify-tekton-pipeline-bundle-signatures/verify-tekton-pipeline-bundle-signatures.md b/content/en/policies/tekton/verify-tekton-pipeline-bundle-signatures/verify-tekton-pipeline-bundle-signatures.md index 5d0c3b635..1a09ce41c 100644 --- a/content/en/policies/tekton/verify-tekton-pipeline-bundle-signatures/verify-tekton-pipeline-bundle-signatures.md +++ b/content/en/policies/tekton/verify-tekton-pipeline-bundle-signatures/verify-tekton-pipeline-bundle-signatures.md @@ -27,7 +27,7 @@ metadata: policies.kyverno.io/description: >- A signed bundle is required spec: - validationFailureAction: enforce + validationFailureAction: Enforce webhookTimeoutSeconds: 30 rules: - name: check-signature diff --git a/content/en/policies/tekton/verify-tekton-taskrun-signatures/verify-tekton-taskrun-signatures.md b/content/en/policies/tekton/verify-tekton-taskrun-signatures/verify-tekton-taskrun-signatures.md index e7fc26c56..779edddb8 100644 --- a/content/en/policies/tekton/verify-tekton-taskrun-signatures/verify-tekton-taskrun-signatures.md +++ b/content/en/policies/tekton/verify-tekton-taskrun-signatures/verify-tekton-taskrun-signatures.md @@ -27,7 +27,7 @@ metadata: policies.kyverno.io/description: >- A signed bundle is required. spec: - validationFailureAction: audit + validationFailureAction: Audit webhookTimeoutSeconds: 30 rules: - name: check-signature diff --git a/content/en/policies/tekton/verify-tekton-taskrun-vuln-scan/verify-tekton-taskrun-vuln-scan.md b/content/en/policies/tekton/verify-tekton-taskrun-vuln-scan/verify-tekton-taskrun-vuln-scan.md index 4c000c9f4..3580c7af6 100644 --- a/content/en/policies/tekton/verify-tekton-taskrun-vuln-scan/verify-tekton-taskrun-vuln-scan.md +++ b/content/en/policies/tekton/verify-tekton-taskrun-vuln-scan/verify-tekton-taskrun-vuln-scan.md @@ -28,7 +28,7 @@ metadata: A signed bundle is required and a vulnerability scan made by Grype must return no vulnerabilities greater than 8.0. spec: - validationFailureAction: audit + validationFailureAction: Audit webhookTimeoutSeconds: 30 rules: - name: check-signature diff --git a/content/en/policies/traefik-cel/disallow-default-tlsoptions/disallow-default-tlsoptions.md b/content/en/policies/traefik-cel/disallow-default-tlsoptions/disallow-default-tlsoptions.md new file mode 100644 index 000000000..62950113b --- /dev/null +++ b/content/en/policies/traefik-cel/disallow-default-tlsoptions/disallow-default-tlsoptions.md @@ -0,0 +1,53 @@ +--- +title: "Disallow Default TLSOptions in CEL expressions" +category: Traefik in CEL +version: +subject: TLSOption +policyType: "validate" +description: > + The TLSOption CustomResource sets cluster-wide TLS configuration options for Traefik when none are specified in a TLS router. Since this can take effect for all Ingress resources, creating the `default` TLSOption is a restricted operation. This policy ensures that only a cluster-admin can create the `default` TLSOption resource. +--- + +## Policy Definition +/traefik-cel/disallow-default-tlsoptions/disallow-default-tlsoptions.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-default-tlsoptions + annotations: + policies.kyverno.io/title: Disallow Default TLSOptions in CEL expressions + policies.kyverno.io/category: Traefik in CEL + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: TLSOption + kyverno.io/kyverno-version: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/description: >- + The TLSOption CustomResource sets cluster-wide TLS configuration options for Traefik when + none are specified in a TLS router. Since this can take effect for all Ingress resources, + creating the `default` TLSOption is a restricted operation. This policy ensures that + only a cluster-admin can create the `default` TLSOption resource. +spec: + validationFailureAction: Audit + background: false + rules: + - name: disallow-default-tlsoptions + match: + any: + - resources: + names: + - default + kinds: + - TLSOption + exclude: + clusterRoles: + - cluster-admin + validate: + cel: + expressions: + - expression: "false" + message: "Only cluster administrators are allowed to set default TLSOptions." + + +``` diff --git a/content/en/policies/traefik/disallow-default-tlsoptions/disallow-default-tlsoptions.md b/content/en/policies/traefik/disallow-default-tlsoptions/disallow-default-tlsoptions.md index 499412508..37514af49 100644 --- a/content/en/policies/traefik/disallow-default-tlsoptions/disallow-default-tlsoptions.md +++ b/content/en/policies/traefik/disallow-default-tlsoptions/disallow-default-tlsoptions.md @@ -29,7 +29,7 @@ metadata: creating the `default` TLSOption is a restricted operation. This policy ensures that only a cluster-admin can create the `default` TLSOption resource. spec: - validationFailureAction: audit + validationFailureAction: Audit background: false rules: - name: disallow-default-tlsoptions diff --git a/content/en/policies/velero-cel/block-velero-restore/block-velero-restore.md b/content/en/policies/velero-cel/block-velero-restore/block-velero-restore.md new file mode 100644 index 000000000..53b003fc3 --- /dev/null +++ b/content/en/policies/velero-cel/block-velero-restore/block-velero-restore.md @@ -0,0 +1,54 @@ +--- +title: "Block Velero Restore to Protected Namespace in CEL expressions" +category: Velero in CEL +version: +subject: Restore +policyType: "validate" +description: > + Velero allows on backup and restore operations and is designed to be run with full cluster admin permissions. It allows on cross namespace restore operations, which means you can restore backup of namespace A to namespace B. This policy protect restore operation into system or any protected namespaces, listed in deny condition section. It checks the Restore CRD object and its namespaceMapping field. If destination match protected namespace then operation fails and warning message is throw. +--- + +## Policy Definition +/velero-cel/block-velero-restore/block-velero-restore.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: block-velero-restore + annotations: + policies.kyverno.io/title: Block Velero Restore to Protected Namespace in CEL expressions + policies.kyverno.io/category: Velero in CEL + policies.kyverno.io/subject: Restore + kyverno.io/kyverno-version: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/description: >- + Velero allows on backup and restore operations and is designed to be run with full cluster admin permissions. + It allows on cross namespace restore operations, which means you can restore backup of namespace A to namespace B. + This policy protect restore operation into system or any protected namespaces, listed in deny condition section. + It checks the Restore CRD object and its namespaceMapping field. If destination match protected namespace + then operation fails and warning message is throw. +spec: + validationFailureAction: Audit + background: false + rules: + - name: block-velero-restore-to-protected-namespace + match: + any: + - resources: + kinds: + - velero.io/v1/Restore + operations: + - CREATE + - UPDATE + validate: + cel: + variables: + - name: namespaceMappingValues + expression: "has(object.spec.namespaceMapping) ? object.spec.namespaceMapping.map(nsmap, object.spec.namespaceMapping[nsmap]) : []" + expressions: + - expression: "!variables.namespaceMappingValues.exists(val, val in ['kube-system', 'kube-node-lease'])" + messageExpression: "'Warning! Restore to protected namespace: ' + variables.namespaceMappingValues.join(', ') + ' is not allowed!'" + + +``` diff --git a/content/en/policies/velero-cel/validate-cron-schedule/validate-cron-schedule.md b/content/en/policies/velero-cel/validate-cron-schedule/validate-cron-schedule.md new file mode 100644 index 000000000..56745ee53 --- /dev/null +++ b/content/en/policies/velero-cel/validate-cron-schedule/validate-cron-schedule.md @@ -0,0 +1,49 @@ +--- +title: "Validate Schedule in CEL expressions" +category: Velero in CEL +version: +subject: Schedule +policyType: "validate" +description: > + A Velero Schedule is given in Cron format and must be accurate to ensure operation. This policy validates that the schedule is a valid Cron format. +--- + +## Policy Definition +/velero-cel/validate-cron-schedule/validate-cron-schedule.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: validate-cron-schedule + annotations: + policies.kyverno.io/title: Validate Schedule in CEL expressions + policies.kyverno.io/category: Velero in CEL + policies.kyverno.io/subject: Schedule + kyverno.io/kyverno-version: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/description: >- + A Velero Schedule is given in Cron format and must be accurate to ensure + operation. This policy validates that the schedule is a valid Cron format. +spec: + background: true + validationFailureAction: Audit + rules: + - name: validate-cron + match: + any: + - resources: + kinds: + - velero.io/v1/Schedule + operations: + - CREATE + - UPDATE + validate: + cel: + expressions: + - expression: >- + object.spec.schedule.matches('^((?:\\*|[0-5]?[0-9](?:(?:-[0-5]?[0-9])|(?:,[0-5]?[0-9])+)?)(?:\\/[0-9]+)?)\\s+((?:\\*|(?:1?[0-9]|2[0-3])(?:(?:-(?:1?[0-9]|2[0-3]))|(?:,(?:1?[0-9]|2[0-3]))+)?)(?:\\/[0-9]+)?)\\s+((?:\\*|(?:[1-9]|[1-2][0-9]|3[0-1])(?:(?:-(?:[1-9]|[1-2][0-9]|3[0-1]))|(?:,(?:[1-9]|[1-2][0-9]|3[0-1]))+)?)(?:\\/[0-9]+)?)\\s+((?:\\*|(?:[1-9]|1[0-2])(?:(?:-(?:[1-9]|1[0-2]))|(?:,(?:[1-9]|1[0-2]))+)?)(?:\\/[0-9]+)?)\\s+((?:\\*|[0-7](?:-[0-7]|(?:,[0-7])+)?)(?:\\/[0-9]+)?)$') + message: The backup schedule must be in a valid cron format. + + +``` diff --git a/content/en/policies/velero/block-velero-restore/block-velero-restore.md b/content/en/policies/velero/block-velero-restore/block-velero-restore.md index e9ceb8b5e..9d9970280 100644 --- a/content/en/policies/velero/block-velero-restore/block-velero-restore.md +++ b/content/en/policies/velero/block-velero-restore/block-velero-restore.md @@ -27,7 +27,7 @@ metadata: It checks the Restore CRD object and its namespaceMapping field. If destination match protected namespace then operation fails and warning message is throw. spec: - validationFailureAction: audit + validationFailureAction: Audit background: false rules: - name: block-velero-restore-to-protected-namespace diff --git a/content/en/policies/velero/validate-cron-schedule/validate-cron-schedule.md b/content/en/policies/velero/validate-cron-schedule/validate-cron-schedule.md index 21cbbe131..99877a03b 100644 --- a/content/en/policies/velero/validate-cron-schedule/validate-cron-schedule.md +++ b/content/en/policies/velero/validate-cron-schedule/validate-cron-schedule.md @@ -25,7 +25,7 @@ metadata: operation. This policy validates that the schedule is a valid Cron format. spec: background: true - validationFailureAction: audit + validationFailureAction: Audit rules: - name: validate-cron match: diff --git a/content/en/policies/windows-security/require-run-as-containeruser/require-run-as-containeruser.md b/content/en/policies/windows-security/require-run-as-containeruser/require-run-as-containeruser.md new file mode 100644 index 000000000..bf66dd93a --- /dev/null +++ b/content/en/policies/windows-security/require-run-as-containeruser/require-run-as-containeruser.md @@ -0,0 +1,59 @@ +--- +title: "Require Run As ContainerUser (Windows)" +category: Windows Security +version: +subject: Pod +policyType: "validate" +description: > + Containers must be required to run as ContainerUser. This policy ensures that the fields spec.securityContext.windowsOptions.runAsUserName, spec.containers[*].securityContext.windowsOptions.runAsUserName, spec.initContainers[*].securityContext.windowsOptions.runAsUserName, and is either unset or set to ContainerUser. +--- + +## Policy Definition +/windows-security/require-run-as-containeruser/require-run-as-containeruser.yaml + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: require-run-as-containeruser + annotations: + policies.kyverno.io/title: Require Run As ContainerUser (Windows) + policies.kyverno.io/category: Windows Security + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + kyverno.io/kyverno-version: 1.6.0 + kyverno.io/kubernetes-version: "1.22-1.28" + policies.kyverno.io/description: >- + Containers must be required to run as ContainerUser. This policy ensures that the fields + spec.securityContext.windowsOptions.runAsUserName, + spec.containers[*].securityContext.windowsOptions.runAsUserName, + spec.initContainers[*].securityContext.windowsOptions.runAsUserName, + and is either unset or set to ContainerUser. +spec: + validationFailureAction: Audit + background: true + rules: + - name: require-run-as-containeruser + match: + any: + - resources: + kinds: + - Pod + validate: + message: >- + Running the container as ContainerAdministrator,NT AUTHORITY\NETWORK SERVICE, NT AUTHORITY\LOCAL SERVICE is not allowed. + pattern: + spec: + =(securityContext): + =(windowsOptions): + =(runAsUserName): "ContainerUser" + =(initContainers): + - =(securityContext): + =(windowsOptions): + =(runAsUserName): "ContainerUser" + containers: + - =(securityContext): + =(windowsOptions): + =(runAsUserName): "ContainerUser" + +```