From 7908f02cb1ebd34e251b30e7d67713196d784253 Mon Sep 17 00:00:00 2001 From: Chandan-DK Date: Mon, 3 Jun 2024 18:01:12 +0530 Subject: [PATCH] feat: add best practices policies in CEL expressions (#925) * copy restrict-node-port Signed-off-by: Chandan-DK * convert restrict-node-port to cel Signed-off-by: Chandan-DK * move resource files to test folders to avoid cross referencing Signed-off-by: Chandan-DK * copy require-labels Signed-off-by: Chandan-DK * convert require-labels to cel Signed-off-by: Chandan-DK * copy restrict-service-external-ips Signed-off-by: Chandan-DK * convert restrict-service-external-ips to cel Signed-off-by: Chandan-DK * copy require-ro-rootfs Signed-off-by: Chandan-DK * convert require-ro-rootfs to cel Signed-off-by: Chandan-DK * copy restrict-image-registries Signed-off-by: Chandan-DK * convert restrict-image-registries to cel Signed-off-by: Chandan-DK * copy disallow-latest-tag Signed-off-by: Chandan-DK * convert disallow-latest-tag to cel Signed-off-by: Chandan-DK * copy disallow-default-namespace Signed-off-by: Chandan-DK * convert disallow-default-namespace to cel Signed-off-by: Chandan-DK * copy disallow-helm-tiller Signed-off-by: Chandan-DK * convert disallow-helm-tiller to cel Signed-off-by: Chandan-DK * copy disallow-empty-ingress-host Signed-off-by: Chandan-DK * set original disallow-empty-ingress-host to Audit Signed-off-by: Chandan-DK * convert disallow-empty-ingress-host to cel Signed-off-by: Chandan-DK * patch cel policy to set it to Enforce in chainsaw test Signed-off-by: Chandan-DK * fix: update semantically wrong chainsaw test resources in original require-drop-all policy Signed-off-by: Chandan-DK * copy require-drop-all Signed-off-by: Chandan-DK * convert require-drop-all to cel Signed-off-by: Chandan-DK * update workflow to test policies in best-practices-cel folder Signed-off-by: Chandan-DK * fix duplicate container names in require-probes chainsaw test Signed-off-by: Chandan-DK * copy require-probes Signed-off-by: Chandan-DK * convert require-probes to cel Signed-off-by: Chandan-DK * require-ro-rootfs: fix selector does not match template labels Signed-off-by: Chandan-DK * require-ro-rootfs: fix duplicate container names Signed-off-by: Chandan-DK * disallow-helm-tiller: fix invalid container naming Signed-off-by: Chandan-DK * require-labels: fix selector does not match template labels Signed-off-by: Chandan-DK * restrict-image-registries: fix selector does not match template labels Signed-off-by: Chandan-DK * rename file for clarity Signed-off-by: Chandan-DK * copy disallow-cri-sock-mount Signed-off-by: Chandan-DK * convert disallow-cri-sock-mount to cel Signed-off-by: Chandan-DK * remove duplicate expressins in require-drop-all Signed-off-by: Chandan-DK * rename file for clarity Signed-off-by: Chandan-DK * require-drop-cap-net-raw: fix duplicate container names Signed-off-by: Chandan-DK * copy require-drop-cap-net-raw Signed-off-by: Chandan-DK * rename pods to distinguish them Signed-off-by: Chandan-DK * convert require-drop-cap-net-raw to cel Signed-off-by: Chandan-DK * copy require-pod-requests-limits Signed-off-by: Chandan-DK * convert require-pod-requests-limits to cel Signed-off-by: Chandan-DK * rename files for clarity Signed-off-by: Chandan-DK * add new line at end of file where not present Signed-off-by: Chandan-DK * calculate digests Signed-off-by: Chandan-DK * add new lines Signed-off-by: Chandan-DK * update digests Signed-off-by: Chandan-DK * remove celPreconditions until it behaves as expected Related to issue https://github.com/kyverno/kyverno/issues/9884 Signed-off-by: Chandan-DK * update digests Signed-off-by: Chandan-DK * remove wrong test step The update to goodpod01 fails not due to Kyverno blocking it, but rather because Kubernetes doesn't permit such modifications on pods. Signed-off-by: Chandan-DK * use variables to remove duplicate logic Signed-off-by: Chandan-DK * remove unnecessary whitespace in require-ro-rootfs Signed-off-by: Chandan-DK * use namespaceObject variable Signed-off-by: Chandan-DK * Combine expressions into 1 rule to generate VAPs Signed-off-by: Chandan-DK * copy kyverno tests for disallow-default-namespace Signed-off-by: Chandan-DK * fix issue caused in cel policies tests due to chainsaw templating Signed-off-by: Chandan-DK --------- Signed-off-by: Chandan-DK Co-authored-by: Chip Zoller Co-authored-by: Mariam Fahmy Co-authored-by: Jim Bugwadia --- .github/workflows/test.yml | 1 + .../.chainsaw-test/chainsaw-test.yaml | 51 ++++++ .../.chainsaw-test/good-pod.yaml | 16 ++ .../.chainsaw-test/pod-containerd-sock.yaml | 16 ++ .../.chainsaw-test/pod-cri-dockerd-sock.yaml | 16 ++ .../.chainsaw-test/pod-crio-sock.yaml | 16 ++ .../.chainsaw-test/pod-docker-sock.yaml | 16 ++ .../.chainsaw-test/pod-emptydir-vol.yaml | 15 ++ .../.chainsaw-test/pod-no-volumes.yaml | 13 ++ .../.chainsaw-test/policy-ready.yaml | 7 + .../.kyverno-test/kyverno-test.yaml | 22 +++ .../.kyverno-test/resource.yaml | 32 ++++ .../artifacthub-pkg.yml | 25 +++ .../disallow-cri-sock-mount.yaml | 58 +++++++ .../.chainsaw-test/chainsaw-test.yaml | 56 +++++++ .../.chainsaw-test/deploy-default.yaml | 24 +++ .../.chainsaw-test/ds-default.yaml | 21 +++ .../.chainsaw-test/good-resources.yaml | 98 +++++++++++ .../.chainsaw-test/job-default.yaml | 16 ++ .../.chainsaw-test/ns.yaml | 5 + .../.chainsaw-test/pod-default.yaml | 13 ++ .../.chainsaw-test/policy-ready.yaml | 7 + .../.chainsaw-test/ss-default.yaml | 24 +++ .../.kyverno-test/kyverno-test.yaml | 34 ++++ .../.kyverno-test/resource.yaml | 67 ++++++++ .../artifacthub-pkg.yml | 24 +++ .../disallow-default-namespace.yaml | 50 ++++++ .../.chainsaw-test/chainsaw-test.yaml | 42 +++++ .../.chainsaw-test/good-ingress.yaml | 27 +++ .../.chainsaw-test/no-host-fail-first.yaml | 26 +++ .../.chainsaw-test/no-host-ingress.yaml | 18 ++ .../.chainsaw-test/no-host-success-first.yaml | 26 +++ .../.chainsaw-test/policy-ready.yaml | 7 + .../.kyverno-test/kyverno-test.yaml | 22 +++ .../.kyverno-test/resource.yaml | 45 +++++ .../artifacthub-pkg.yml | 24 +++ .../disallow-empty-ingress-host.yaml | 33 ++++ .../.chainsaw-test/bad-deploy.yaml | 22 +++ .../.chainsaw-test/bad-pod-fail-first.yaml | 11 ++ .../.chainsaw-test/bad-pod-success-first.yaml | 11 ++ .../.chainsaw-test/bad-pod.yaml | 9 + .../.chainsaw-test/chainsaw-test.yaml | 49 ++++++ .../.chainsaw-test/good-deploy.yaml | 21 +++ .../.chainsaw-test/good-pod.yaml | 11 ++ .../.chainsaw-test/policy-ready.yaml | 7 + .../.kyverno-test/kyverno-test.yaml | 36 ++++ .../.kyverno-test/resource.yaml | 83 ++++++++++ .../disallow-helm-tiller/artifacthub-pkg.yml | 24 +++ .../disallow-helm-tiller.yaml | 33 ++++ .../bad-pod-latest-fail-first.yaml | 11 ++ .../bad-pod-latest-success-first.yaml | 11 ++ .../.chainsaw-test/bad-pod-no-tag.yaml | 33 ++++ .../.chainsaw-test/chainsaw-test.yaml | 42 +++++ .../.chainsaw-test/good-pod.yaml | 9 + .../.chainsaw-test/policy-ready.yaml | 7 + .../.kyverno-test/kyverno-test.yaml | 48 ++++++ .../.kyverno-test/resource.yaml | 122 ++++++++++++++ .../disallow-latest-tag/artifacthub-pkg.yml | 24 +++ .../disallow-latest-tag.yaml | 34 ++++ .../.chainsaw-test/bad-pod-containers.yaml | 62 +++++++ .../.chainsaw-test/bad-pod-corner.yaml | 55 +++++++ .../bad-pod-initcontainers.yaml | 48 ++++++ .../.chainsaw-test/bad-podcontrollers.yaml | 154 ++++++++++++++++++ .../.chainsaw-test/chainsaw-test.yaml | 51 ++++++ .../.chainsaw-test/good-pod.yaml | 28 ++++ .../.chainsaw-test/good-podcontrollers.yaml | 87 ++++++++++ .../.chainsaw-test/policy-ready.yaml | 7 + .../.kyverno-test/kyverno-test.yaml | 22 +++ .../.kyverno-test/resource.yaml | 38 +++++ .../require-drop-all/artifacthub-pkg.yml | 24 +++ .../require-drop-all/require-drop-all.yaml | 41 +++++ .../.chainsaw-test/bad-pod-containers.yaml | 62 +++++++ .../.chainsaw-test/bad-pod-corner.yaml | 52 ++++++ .../bad-pod-initcontainers.yaml | 48 ++++++ .../.chainsaw-test/bad-podcontrollers.yaml | 154 ++++++++++++++++++ .../.chainsaw-test/chainsaw-test.yaml | 51 ++++++ .../.chainsaw-test/good-pod.yaml | 26 +++ .../.chainsaw-test/good-podcontrollers.yaml | 87 ++++++++++ .../.chainsaw-test/policy-ready.yaml | 7 + .../.kyverno-test/kyverno-test.yaml | 23 +++ .../.kyverno-test/resource.yaml | 45 +++++ .../artifacthub-pkg.yml | 24 +++ .../require-drop-cap-net-raw.yaml | 43 +++++ .../.chainsaw-test/bad-pod-nolabel.yaml | 9 + .../.chainsaw-test/bad-pod-somelabel.yaml | 11 ++ .../.chainsaw-test/bad-podcontrollers.yaml | 36 ++++ .../.chainsaw-test/chainsaw-test.yaml | 44 +++++ .../.chainsaw-test/good-podcontrollers.yaml | 39 +++++ .../.chainsaw-test/good-pods.yaml | 23 +++ .../.chainsaw-test/policy-ready.yaml | 7 + .../.kyverno-test/kyverno-test.yaml | 24 +++ .../.kyverno-test/resource.yaml | 43 +++++ .../require-labels/artifacthub-pkg.yml | 24 +++ .../require-labels/require-labels.yaml | 34 ++++ .../.chainsaw-test/bad-pod-nolimit.yaml | 15 ++ .../.chainsaw-test/bad-pod-nores.yaml | 38 +++++ .../.chainsaw-test/bad-pod-nothing.yaml | 12 ++ .../.chainsaw-test/bad-podcontrollers.yaml | 49 ++++++ .../.chainsaw-test/chainsaw-test.yaml | 49 ++++++ .../.chainsaw-test/good-podcontrollers.yaml | 61 +++++++ .../.chainsaw-test/good-pods.yaml | 42 +++++ .../.chainsaw-test/policy-ready.yaml | 7 + .../.kyverno-test/kyverno-test.yaml | 25 +++ .../.kyverno-test/resource.yaml | 87 ++++++++++ .../artifacthub-pkg.yml | 25 +++ .../require-pod-requests-limits.yaml | 41 +++++ .../.chainsaw-test/bad-pod-notall.yaml | 38 +++++ .../.chainsaw-test/bad-pod-nothing.yaml | 7 +- .../.chainsaw-test/bad-podcontrollers.yaml | 24 +++ .../.chainsaw-test/chainsaw-test.yaml | 44 +++++ .../.chainsaw-test/good-podcontrollers.yaml | 28 ++++ .../.chainsaw-test/good-pods.yaml | 50 ++++++ .../.chainsaw-test/policy-ready.yaml | 7 + .../.kyverno-test/kyverno-test.yaml | 26 +++ .../.kyverno-test/resource.yaml | 111 +++++++++++++ .../require-probes/artifacthub-pkg.yml | 25 +++ .../require-probes/require-probes.yaml | 40 +++++ .../.chainsaw-test/bad-pod-false.yaml | 11 ++ .../.chainsaw-test/bad-pod-notall.yaml | 26 +++ .../.chainsaw-test/bad-pod-nothing.yaml | 9 + .../.chainsaw-test/bad-podcontrollers.yaml | 41 +++++ .../.chainsaw-test/chainsaw-test.yaml | 49 ++++++ .../.chainsaw-test/good-podcontrollers.yaml | 45 +++++ .../.chainsaw-test/good-pods.yaml | 26 +++ .../.chainsaw-test/policy-ready.yaml | 7 + .../.kyverno-test/kyverno-test.yaml | 25 +++ .../.kyverno-test/resource.yaml | 59 +++++++ .../require-ro-rootfs/artifacthub-pkg.yml | 25 +++ .../require-ro-rootfs/require-ro-rootfs.yaml | 36 ++++ .../.chainsaw-test/bad-pod-false.yaml | 9 + .../.chainsaw-test/bad-pod-noregistry.yaml | 9 + .../.chainsaw-test/bad-pod-notall.yaml | 22 +++ .../.chainsaw-test/bad-podcontrollers.yaml | 141 ++++++++++++++++ .../.chainsaw-test/chainsaw-test.yaml | 64 ++++++++ .../.chainsaw-test/good-podcontrollers.yaml | 49 ++++++ .../.chainsaw-test/good-pods.yaml | 35 ++++ .../.chainsaw-test/policy-ready.yaml | 7 + .../.kyverno-test/kyverno-test.yaml | 27 +++ .../.kyverno-test/resource.yaml | 69 ++++++++ .../artifacthub-pkg.yml | 25 +++ .../restrict-image-registries.yaml | 36 ++++ .../.chainsaw-test/bad-service-nodeport.yaml | 13 ++ .../.chainsaw-test/chainsaw-test.yaml | 32 ++++ .../.chainsaw-test/good-services.yaml | 25 +++ .../.chainsaw-test/policy-ready.yaml | 7 + .../.kyverno-test/kyverno-test.yaml | 23 +++ .../.kyverno-test/resource.yaml | 39 +++++ .../restrict-node-port/artifacthub-pkg.yml | 24 +++ .../restrict-node-port.yaml | 33 ++++ .../.chainsaw-test/bad-service-oneip.yaml | 14 ++ .../.chainsaw-test/bad-service-twoeip.yaml | 15 ++ .../.chainsaw-test/chainsaw-test.yaml | 37 +++++ .../.chainsaw-test/good-services.yaml | 12 ++ .../.chainsaw-test/policy-ready.yaml | 7 + .../.kyverno-test/kyverno-test.yaml | 23 +++ .../.kyverno-test/resource.yaml | 41 +++++ .../artifacthub-pkg.yml | 24 +++ .../restrict-service-external-ips.yaml | 36 ++++ .../.chainsaw-test/chainsaw-test.yaml | 2 +- ...tep-01-assert-1.yaml => policy-ready.yaml} | 0 .../.chainsaw-test/chainsaw-test.yaml | 4 +- ...{chainsaw-step-02-apply-1.yaml => ns.yaml} | 0 ...tep-01-assert-1.yaml => policy-ready.yaml} | 0 .../.chainsaw-test/chainsaw-test.yaml | 8 + .../artifacthub-pkg.yml | 2 +- .../disallow-empty-ingress-host.yaml | 2 +- .../.chainsaw-test/bad-deploy.yaml | 2 +- .../.chainsaw-test/chainsaw-test.yaml | 2 +- ...tep-01-assert-1.yaml => policy-ready.yaml} | 0 .../.chainsaw-test/chainsaw-test.yaml | 2 +- ...tep-01-assert-1.yaml => policy-ready.yaml} | 0 .../.chainsaw-test/bad-pod-corner.yaml | 8 +- .../.chainsaw-test/chainsaw-test.yaml | 2 +- ...tep-01-assert-1.yaml => policy-ready.yaml} | 0 .../.chainsaw-test/bad-pod-corner.yaml | 8 +- .../bad-pod-initcontainers.yaml | 4 +- .../.chainsaw-test/chainsaw-test.yaml | 2 +- ...tep-01-assert-1.yaml => policy-ready.yaml} | 0 .../.chainsaw-test/bad-podcontrollers.yaml | 2 +- .../.chainsaw-test/chainsaw-test.yaml | 2 +- ...tep-01-assert-1.yaml => policy-ready.yaml} | 0 .../.chainsaw-test/chainsaw-test.yaml | 2 +- ...tep-01-assert-1.yaml => policy-ready.yaml} | 0 .../.chainsaw-test/bad-pod-notall.yaml | 4 +- .../.chainsaw-test/chainsaw-test.yaml | 10 +- ...tep-01-assert-1.yaml => policy-ready.yaml} | 0 .../.chainsaw-test/bad-pod-notall.yaml | 4 +- .../.chainsaw-test/bad-podcontrollers.yaml | 2 +- .../.chainsaw-test/chainsaw-test.yaml | 2 +- ...tep-01-assert-1.yaml => policy-ready.yaml} | 0 .../.chainsaw-test/bad-podcontrollers.yaml | 6 +- .../.chainsaw-test/chainsaw-test.yaml | 2 +- ...tep-01-assert-1.yaml => policy-ready.yaml} | 0 .../.chainsaw-test/chainsaw-test.yaml | 2 +- ...tep-01-assert-1.yaml => policy-ready.yaml} | 0 .../.chainsaw-test/chainsaw-test.yaml | 2 +- ...tep-01-assert-1.yaml => policy-ready.yaml} | 0 197 files changed, 5354 insertions(+), 46 deletions(-) create mode 100755 best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/chainsaw-test.yaml create mode 100644 best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/good-pod.yaml create mode 100644 best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/pod-containerd-sock.yaml create mode 100644 best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/pod-cri-dockerd-sock.yaml create mode 100644 best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/pod-crio-sock.yaml create mode 100644 best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/pod-docker-sock.yaml create mode 100644 best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/pod-emptydir-vol.yaml create mode 100644 best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/pod-no-volumes.yaml create mode 100755 best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/policy-ready.yaml create mode 100644 best-practices-cel/disallow-cri-sock-mount/.kyverno-test/kyverno-test.yaml create mode 100644 best-practices-cel/disallow-cri-sock-mount/.kyverno-test/resource.yaml create mode 100644 best-practices-cel/disallow-cri-sock-mount/artifacthub-pkg.yml create mode 100644 best-practices-cel/disallow-cri-sock-mount/disallow-cri-sock-mount.yaml create mode 100755 best-practices-cel/disallow-default-namespace/.chainsaw-test/chainsaw-test.yaml create mode 100644 best-practices-cel/disallow-default-namespace/.chainsaw-test/deploy-default.yaml create mode 100644 best-practices-cel/disallow-default-namespace/.chainsaw-test/ds-default.yaml create mode 100644 best-practices-cel/disallow-default-namespace/.chainsaw-test/good-resources.yaml create mode 100644 best-practices-cel/disallow-default-namespace/.chainsaw-test/job-default.yaml create mode 100755 best-practices-cel/disallow-default-namespace/.chainsaw-test/ns.yaml create mode 100644 best-practices-cel/disallow-default-namespace/.chainsaw-test/pod-default.yaml create mode 100755 best-practices-cel/disallow-default-namespace/.chainsaw-test/policy-ready.yaml create mode 100644 best-practices-cel/disallow-default-namespace/.chainsaw-test/ss-default.yaml create mode 100644 best-practices-cel/disallow-default-namespace/.kyverno-test/kyverno-test.yaml create mode 100644 best-practices-cel/disallow-default-namespace/.kyverno-test/resource.yaml create mode 100644 best-practices-cel/disallow-default-namespace/artifacthub-pkg.yml create mode 100644 best-practices-cel/disallow-default-namespace/disallow-default-namespace.yaml create mode 100755 best-practices-cel/disallow-empty-ingress-host/.chainsaw-test/chainsaw-test.yaml create mode 100644 best-practices-cel/disallow-empty-ingress-host/.chainsaw-test/good-ingress.yaml create mode 100644 best-practices-cel/disallow-empty-ingress-host/.chainsaw-test/no-host-fail-first.yaml create mode 100644 best-practices-cel/disallow-empty-ingress-host/.chainsaw-test/no-host-ingress.yaml create mode 100644 best-practices-cel/disallow-empty-ingress-host/.chainsaw-test/no-host-success-first.yaml create mode 100644 best-practices-cel/disallow-empty-ingress-host/.chainsaw-test/policy-ready.yaml create mode 100644 best-practices-cel/disallow-empty-ingress-host/.kyverno-test/kyverno-test.yaml create mode 100644 best-practices-cel/disallow-empty-ingress-host/.kyverno-test/resource.yaml create mode 100644 best-practices-cel/disallow-empty-ingress-host/artifacthub-pkg.yml create mode 100644 best-practices-cel/disallow-empty-ingress-host/disallow-empty-ingress-host.yaml create mode 100644 best-practices-cel/disallow-helm-tiller/.chainsaw-test/bad-deploy.yaml create mode 100644 best-practices-cel/disallow-helm-tiller/.chainsaw-test/bad-pod-fail-first.yaml create mode 100644 best-practices-cel/disallow-helm-tiller/.chainsaw-test/bad-pod-success-first.yaml create mode 100644 best-practices-cel/disallow-helm-tiller/.chainsaw-test/bad-pod.yaml create mode 100755 best-practices-cel/disallow-helm-tiller/.chainsaw-test/chainsaw-test.yaml create mode 100644 best-practices-cel/disallow-helm-tiller/.chainsaw-test/good-deploy.yaml create mode 100644 best-practices-cel/disallow-helm-tiller/.chainsaw-test/good-pod.yaml create mode 100755 best-practices-cel/disallow-helm-tiller/.chainsaw-test/policy-ready.yaml create mode 100644 best-practices-cel/disallow-helm-tiller/.kyverno-test/kyverno-test.yaml create mode 100644 best-practices-cel/disallow-helm-tiller/.kyverno-test/resource.yaml create mode 100644 best-practices-cel/disallow-helm-tiller/artifacthub-pkg.yml create mode 100644 best-practices-cel/disallow-helm-tiller/disallow-helm-tiller.yaml create mode 100644 best-practices-cel/disallow-latest-tag/.chainsaw-test/bad-pod-latest-fail-first.yaml create mode 100644 best-practices-cel/disallow-latest-tag/.chainsaw-test/bad-pod-latest-success-first.yaml create mode 100644 best-practices-cel/disallow-latest-tag/.chainsaw-test/bad-pod-no-tag.yaml create mode 100755 best-practices-cel/disallow-latest-tag/.chainsaw-test/chainsaw-test.yaml create mode 100644 best-practices-cel/disallow-latest-tag/.chainsaw-test/good-pod.yaml create mode 100755 best-practices-cel/disallow-latest-tag/.chainsaw-test/policy-ready.yaml create mode 100644 best-practices-cel/disallow-latest-tag/.kyverno-test/kyverno-test.yaml create mode 100644 best-practices-cel/disallow-latest-tag/.kyverno-test/resource.yaml create mode 100644 best-practices-cel/disallow-latest-tag/artifacthub-pkg.yml create mode 100644 best-practices-cel/disallow-latest-tag/disallow-latest-tag.yaml create mode 100644 best-practices-cel/require-drop-all/.chainsaw-test/bad-pod-containers.yaml create mode 100644 best-practices-cel/require-drop-all/.chainsaw-test/bad-pod-corner.yaml create mode 100644 best-practices-cel/require-drop-all/.chainsaw-test/bad-pod-initcontainers.yaml create mode 100644 best-practices-cel/require-drop-all/.chainsaw-test/bad-podcontrollers.yaml create mode 100755 best-practices-cel/require-drop-all/.chainsaw-test/chainsaw-test.yaml create mode 100644 best-practices-cel/require-drop-all/.chainsaw-test/good-pod.yaml create mode 100644 best-practices-cel/require-drop-all/.chainsaw-test/good-podcontrollers.yaml create mode 100755 best-practices-cel/require-drop-all/.chainsaw-test/policy-ready.yaml create mode 100644 best-practices-cel/require-drop-all/.kyverno-test/kyverno-test.yaml create mode 100644 best-practices-cel/require-drop-all/.kyverno-test/resource.yaml create mode 100644 best-practices-cel/require-drop-all/artifacthub-pkg.yml create mode 100644 best-practices-cel/require-drop-all/require-drop-all.yaml create mode 100644 best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/bad-pod-containers.yaml create mode 100644 best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/bad-pod-corner.yaml create mode 100644 best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/bad-pod-initcontainers.yaml create mode 100644 best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/bad-podcontrollers.yaml create mode 100755 best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/chainsaw-test.yaml create mode 100644 best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/good-pod.yaml create mode 100644 best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/good-podcontrollers.yaml create mode 100755 best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/policy-ready.yaml create mode 100644 best-practices-cel/require-drop-cap-net-raw/.kyverno-test/kyverno-test.yaml create mode 100644 best-practices-cel/require-drop-cap-net-raw/.kyverno-test/resource.yaml create mode 100644 best-practices-cel/require-drop-cap-net-raw/artifacthub-pkg.yml create mode 100644 best-practices-cel/require-drop-cap-net-raw/require-drop-cap-net-raw.yaml create mode 100644 best-practices-cel/require-labels/.chainsaw-test/bad-pod-nolabel.yaml create mode 100644 best-practices-cel/require-labels/.chainsaw-test/bad-pod-somelabel.yaml create mode 100644 best-practices-cel/require-labels/.chainsaw-test/bad-podcontrollers.yaml create mode 100755 best-practices-cel/require-labels/.chainsaw-test/chainsaw-test.yaml create mode 100644 best-practices-cel/require-labels/.chainsaw-test/good-podcontrollers.yaml create mode 100644 best-practices-cel/require-labels/.chainsaw-test/good-pods.yaml create mode 100755 best-practices-cel/require-labels/.chainsaw-test/policy-ready.yaml create mode 100644 best-practices-cel/require-labels/.kyverno-test/kyverno-test.yaml create mode 100644 best-practices-cel/require-labels/.kyverno-test/resource.yaml create mode 100644 best-practices-cel/require-labels/artifacthub-pkg.yml create mode 100644 best-practices-cel/require-labels/require-labels.yaml create mode 100644 best-practices-cel/require-pod-requests-limits/.chainsaw-test/bad-pod-nolimit.yaml create mode 100644 best-practices-cel/require-pod-requests-limits/.chainsaw-test/bad-pod-nores.yaml create mode 100644 best-practices-cel/require-pod-requests-limits/.chainsaw-test/bad-pod-nothing.yaml create mode 100644 best-practices-cel/require-pod-requests-limits/.chainsaw-test/bad-podcontrollers.yaml create mode 100755 best-practices-cel/require-pod-requests-limits/.chainsaw-test/chainsaw-test.yaml create mode 100644 best-practices-cel/require-pod-requests-limits/.chainsaw-test/good-podcontrollers.yaml create mode 100644 best-practices-cel/require-pod-requests-limits/.chainsaw-test/good-pods.yaml create mode 100755 best-practices-cel/require-pod-requests-limits/.chainsaw-test/policy-ready.yaml create mode 100644 best-practices-cel/require-pod-requests-limits/.kyverno-test/kyverno-test.yaml create mode 100644 best-practices-cel/require-pod-requests-limits/.kyverno-test/resource.yaml create mode 100644 best-practices-cel/require-pod-requests-limits/artifacthub-pkg.yml create mode 100644 best-practices-cel/require-pod-requests-limits/require-pod-requests-limits.yaml create mode 100644 best-practices-cel/require-probes/.chainsaw-test/bad-pod-notall.yaml rename best-practices/require-probes/.chainsaw-test/bad-pod-update.yaml => best-practices-cel/require-probes/.chainsaw-test/bad-pod-nothing.yaml (57%) create mode 100644 best-practices-cel/require-probes/.chainsaw-test/bad-podcontrollers.yaml create mode 100755 best-practices-cel/require-probes/.chainsaw-test/chainsaw-test.yaml create mode 100644 best-practices-cel/require-probes/.chainsaw-test/good-podcontrollers.yaml create mode 100644 best-practices-cel/require-probes/.chainsaw-test/good-pods.yaml create mode 100755 best-practices-cel/require-probes/.chainsaw-test/policy-ready.yaml create mode 100644 best-practices-cel/require-probes/.kyverno-test/kyverno-test.yaml create mode 100644 best-practices-cel/require-probes/.kyverno-test/resource.yaml create mode 100644 best-practices-cel/require-probes/artifacthub-pkg.yml create mode 100644 best-practices-cel/require-probes/require-probes.yaml create mode 100644 best-practices-cel/require-ro-rootfs/.chainsaw-test/bad-pod-false.yaml create mode 100644 best-practices-cel/require-ro-rootfs/.chainsaw-test/bad-pod-notall.yaml create mode 100644 best-practices-cel/require-ro-rootfs/.chainsaw-test/bad-pod-nothing.yaml create mode 100644 best-practices-cel/require-ro-rootfs/.chainsaw-test/bad-podcontrollers.yaml create mode 100755 best-practices-cel/require-ro-rootfs/.chainsaw-test/chainsaw-test.yaml create mode 100644 best-practices-cel/require-ro-rootfs/.chainsaw-test/good-podcontrollers.yaml create mode 100644 best-practices-cel/require-ro-rootfs/.chainsaw-test/good-pods.yaml create mode 100755 best-practices-cel/require-ro-rootfs/.chainsaw-test/policy-ready.yaml create mode 100644 best-practices-cel/require-ro-rootfs/.kyverno-test/kyverno-test.yaml create mode 100644 best-practices-cel/require-ro-rootfs/.kyverno-test/resource.yaml create mode 100644 best-practices-cel/require-ro-rootfs/artifacthub-pkg.yml create mode 100644 best-practices-cel/require-ro-rootfs/require-ro-rootfs.yaml create mode 100644 best-practices-cel/restrict-image-registries/.chainsaw-test/bad-pod-false.yaml create mode 100644 best-practices-cel/restrict-image-registries/.chainsaw-test/bad-pod-noregistry.yaml create mode 100644 best-practices-cel/restrict-image-registries/.chainsaw-test/bad-pod-notall.yaml create mode 100644 best-practices-cel/restrict-image-registries/.chainsaw-test/bad-podcontrollers.yaml create mode 100755 best-practices-cel/restrict-image-registries/.chainsaw-test/chainsaw-test.yaml create mode 100644 best-practices-cel/restrict-image-registries/.chainsaw-test/good-podcontrollers.yaml create mode 100644 best-practices-cel/restrict-image-registries/.chainsaw-test/good-pods.yaml create mode 100755 best-practices-cel/restrict-image-registries/.chainsaw-test/policy-ready.yaml create mode 100644 best-practices-cel/restrict-image-registries/.kyverno-test/kyverno-test.yaml create mode 100644 best-practices-cel/restrict-image-registries/.kyverno-test/resource.yaml create mode 100644 best-practices-cel/restrict-image-registries/artifacthub-pkg.yml create mode 100644 best-practices-cel/restrict-image-registries/restrict-image-registries.yaml create mode 100644 best-practices-cel/restrict-node-port/.chainsaw-test/bad-service-nodeport.yaml create mode 100755 best-practices-cel/restrict-node-port/.chainsaw-test/chainsaw-test.yaml create mode 100644 best-practices-cel/restrict-node-port/.chainsaw-test/good-services.yaml create mode 100755 best-practices-cel/restrict-node-port/.chainsaw-test/policy-ready.yaml create mode 100644 best-practices-cel/restrict-node-port/.kyverno-test/kyverno-test.yaml create mode 100644 best-practices-cel/restrict-node-port/.kyverno-test/resource.yaml create mode 100644 best-practices-cel/restrict-node-port/artifacthub-pkg.yml create mode 100644 best-practices-cel/restrict-node-port/restrict-node-port.yaml create mode 100644 best-practices-cel/restrict-service-external-ips/.chainsaw-test/bad-service-oneip.yaml create mode 100644 best-practices-cel/restrict-service-external-ips/.chainsaw-test/bad-service-twoeip.yaml create mode 100755 best-practices-cel/restrict-service-external-ips/.chainsaw-test/chainsaw-test.yaml create mode 100644 best-practices-cel/restrict-service-external-ips/.chainsaw-test/good-services.yaml create mode 100755 best-practices-cel/restrict-service-external-ips/.chainsaw-test/policy-ready.yaml create mode 100644 best-practices-cel/restrict-service-external-ips/.kyverno-test/kyverno-test.yaml create mode 100644 best-practices-cel/restrict-service-external-ips/.kyverno-test/resource.yaml create mode 100644 best-practices-cel/restrict-service-external-ips/artifacthub-pkg.yml create mode 100644 best-practices-cel/restrict-service-external-ips/restrict-service-external-ips.yaml rename best-practices/disallow-cri-sock-mount/.chainsaw-test/{chainsaw-step-01-assert-1.yaml => policy-ready.yaml} (100%) rename best-practices/disallow-default-namespace/.chainsaw-test/{chainsaw-step-02-apply-1.yaml => ns.yaml} (100%) rename best-practices/disallow-default-namespace/.chainsaw-test/{chainsaw-step-01-assert-1.yaml => policy-ready.yaml} (100%) rename best-practices/disallow-helm-tiller/.chainsaw-test/{chainsaw-step-01-assert-1.yaml => policy-ready.yaml} (100%) rename best-practices/disallow-latest-tag/.chainsaw-test/{chainsaw-step-01-assert-1.yaml => policy-ready.yaml} (100%) rename best-practices/require-drop-all/.chainsaw-test/{chainsaw-step-01-assert-1.yaml => policy-ready.yaml} (100%) rename best-practices/require-drop-cap-net-raw/.chainsaw-test/{chainsaw-step-01-assert-1.yaml => policy-ready.yaml} (100%) rename best-practices/require-labels/.chainsaw-test/{chainsaw-step-01-assert-1.yaml => policy-ready.yaml} (100%) rename best-practices/require-pod-requests-limits/.chainsaw-test/{chainsaw-step-01-assert-1.yaml => policy-ready.yaml} (100%) rename best-practices/require-probes/.chainsaw-test/{chainsaw-step-01-assert-1.yaml => policy-ready.yaml} (100%) rename best-practices/require-ro-rootfs/.chainsaw-test/{chainsaw-step-01-assert-1.yaml => policy-ready.yaml} (100%) rename best-practices/restrict-image-registries/.chainsaw-test/{chainsaw-step-01-assert-1.yaml => policy-ready.yaml} (100%) rename best-practices/restrict-node-port/.chainsaw-test/{chainsaw-step-01-assert-1.yaml => policy-ready.yaml} (100%) rename best-practices/restrict-service-external-ips/.chainsaw-test/{chainsaw-step-01-assert-1.yaml => policy-ready.yaml} (100%) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c97b7ca47..43fa88d1d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -32,6 +32,7 @@ jobs: - ^argo$ - ^aws$ - ^best-practices$ + - ^best-practices-cel$ - ^castai$ - ^cert-manager$ - ^consul$ diff --git a/best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/chainsaw-test.yaml b/best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..869ffb436 --- /dev/null +++ b/best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,51 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: disallow-cri-sock-mount +spec: + steps: + - name: step-01 + try: + - apply: + file: ../disallow-cri-sock-mount.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: disallow-container-sock-mounts + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: good-pod.yaml + - apply: + expect: + - check: + ($error != null): true + file: pod-containerd-sock.yaml + - apply: + expect: + - check: + ($error != null): true + file: pod-docker-sock.yaml + - apply: + expect: + - check: + ($error != null): true + file: pod-crio-sock.yaml + - apply: + expect: + - check: + ($error != null): true + file: pod-cri-dockerd-sock.yaml + - apply: + file: pod-emptydir-vol.yaml + - apply: + file: pod-no-volumes.yaml + diff --git a/best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/good-pod.yaml b/best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/good-pod.yaml new file mode 100644 index 000000000..997d06743 --- /dev/null +++ b/best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/good-pod.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 +spec: + containers: + - name: myshell + image: "ubuntu:18.04" + command: + - /bin/sleep + - "300" + volumes: + - name: data + hostPath: + path: /data + diff --git a/best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/pod-containerd-sock.yaml b/best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/pod-containerd-sock.yaml new file mode 100644 index 000000000..59a9b9660 --- /dev/null +++ b/best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/pod-containerd-sock.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Pod +metadata: + name: pod-with-containerd-sock-mount +spec: + containers: + - name: myshell + image: "ubuntu:18.04" + command: + - /bin/sleep + - "300" + volumes: + - name: dockersock + hostPath: + path: /var/run/containerd/containerd.sock + diff --git a/best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/pod-cri-dockerd-sock.yaml b/best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/pod-cri-dockerd-sock.yaml new file mode 100644 index 000000000..c5a6c87bd --- /dev/null +++ b/best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/pod-cri-dockerd-sock.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Pod +metadata: + name: pod-with-cri-dockerd-sock-mount +spec: + containers: + - name: myshell + image: "ubuntu:18.04" + command: + - /bin/sleep + - "300" + volumes: + - name: dockersock + hostPath: + path: /var/run/cri-dockerd.sock + diff --git a/best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/pod-crio-sock.yaml b/best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/pod-crio-sock.yaml new file mode 100644 index 000000000..78325a06b --- /dev/null +++ b/best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/pod-crio-sock.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Pod +metadata: + name: pod-with-crio-sock-mount +spec: + containers: + - name: myshell + image: "ubuntu:18.04" + command: + - /bin/sleep + - "300" + volumes: + - name: dockersock + hostPath: + path: /var/run/crio/crio.sock + diff --git a/best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/pod-docker-sock.yaml b/best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/pod-docker-sock.yaml new file mode 100644 index 000000000..072596f62 --- /dev/null +++ b/best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/pod-docker-sock.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Pod +metadata: + name: pod-with-docker-sock-mount +spec: + containers: + - name: myshell + image: "ubuntu:18.04" + command: + - /bin/sleep + - "300" + volumes: + - name: dockersock + hostPath: + path: /var/run/docker.sock + diff --git a/best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/pod-emptydir-vol.yaml b/best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/pod-emptydir-vol.yaml new file mode 100644 index 000000000..d9fc1691f --- /dev/null +++ b/best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/pod-emptydir-vol.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: pod-with-emptydir-volume +spec: + containers: + - name: busybox + image: busybox:1.35 + command: + - sleep + - "3600" + volumes: + - name: mydir + emptyDir: {} + diff --git a/best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/pod-no-volumes.yaml b/best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/pod-no-volumes.yaml new file mode 100644 index 000000000..2609b3d82 --- /dev/null +++ b/best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/pod-no-volumes.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Pod +metadata: + name: pod-with-no-volumes +spec: + automountServiceAccountToken: false + containers: + - name: busybox + image: busybox:1.35 + command: + - sleep + - "3600" + diff --git a/best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/policy-ready.yaml b/best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..24674e4c7 --- /dev/null +++ b/best-practices-cel/disallow-cri-sock-mount/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-container-sock-mounts +status: + ready: true + diff --git a/best-practices-cel/disallow-cri-sock-mount/.kyverno-test/kyverno-test.yaml b/best-practices-cel/disallow-cri-sock-mount/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..f95fe7634 --- /dev/null +++ b/best-practices-cel/disallow-cri-sock-mount/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,22 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: disallow-cri-sock-mount +policies: +- ../disallow-cri-sock-mount.yaml +resources: +- resource.yaml +results: +- kind: Pod + policy: disallow-container-sock-mounts + resources: + - pod-with-docker-sock-mount + result: fail + rule: validate-socket-mounts +- kind: Pod + policy: disallow-container-sock-mounts + resources: + - goodpod01 + result: pass + rule: validate-socket-mounts + diff --git a/best-practices-cel/disallow-cri-sock-mount/.kyverno-test/resource.yaml b/best-practices-cel/disallow-cri-sock-mount/.kyverno-test/resource.yaml new file mode 100644 index 000000000..788e14cf7 --- /dev/null +++ b/best-practices-cel/disallow-cri-sock-mount/.kyverno-test/resource.yaml @@ -0,0 +1,32 @@ +apiVersion: v1 +kind: Pod +metadata: + name: pod-with-docker-sock-mount +spec: + containers: + - name: myshell + image: "ubuntu:18.04" + command: + - /bin/sleep + - "300" + volumes: + - name: dockersock + hostPath: + path: /var/run/docker.sock +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 +spec: + containers: + - name: myshell + image: "ubuntu:18.04" + command: + - /bin/sleep + - "300" + volumes: + - name: data + hostPath: + path: /data + diff --git a/best-practices-cel/disallow-cri-sock-mount/artifacthub-pkg.yml b/best-practices-cel/disallow-cri-sock-mount/artifacthub-pkg.yml new file mode 100644 index 000000000..0c1b038ab --- /dev/null +++ b/best-practices-cel/disallow-cri-sock-mount/artifacthub-pkg.yml @@ -0,0 +1,25 @@ +name: disallow-cri-sock-mount-cel +version: 1.0.0 +displayName: Disallow CRI socket mounts in CEL expressions +description: >- + Container daemon socket bind mounts allows access to the container engine on the node. This access can be used for privilege escalation and to manage containers outside of Kubernetes, and hence should not be allowed. This policy validates that the sockets used for CRI engines Docker, Containerd, and CRI-O are not used. In addition 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. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/best-practices-cel/disallow-cri-sock-mount/disallow-cri-sock-mount.yaml + ``` +keywords: + - kyverno + - Best Practices + - EKS Best Practices + - CEL Expressions +readme: | + Container daemon socket bind mounts allows access to the container engine on the node. This access can be used for privilege escalation and to manage containers outside of Kubernetes, and hence should not be allowed. This policy validates that the sockets used for CRI engines Docker, Containerd, and CRI-O are not used. In addition 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. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Best Practices, EKS Best Practices in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Pod" +digest: 0b91de77f8a6da0cafea457e0ba9eb14f0b8eb6bbcb56419a4e9de09c860753d +createdAt: "2024-03-14T15:59:52Z" + diff --git a/best-practices-cel/disallow-cri-sock-mount/disallow-cri-sock-mount.yaml b/best-practices-cel/disallow-cri-sock-mount/disallow-cri-sock-mount.yaml new file mode 100644 index 000000000..3351e4eb5 --- /dev/null +++ b/best-practices-cel/disallow-cri-sock-mount/disallow-cri-sock-mount.yaml @@ -0,0 +1,58 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-container-sock-mounts + annotations: + policies.kyverno.io/title: Disallow CRI socket mounts in CEL expressions + policies.kyverno.io/category: Best Practices, EKS Best Practices 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: >- + Container daemon socket bind mounts allows access to the container engine on the + node. This access can be used for privilege escalation and to manage containers + outside of Kubernetes, and hence should not be allowed. This policy validates that + the sockets used for CRI engines Docker, Containerd, and CRI-O are not used. In addition + 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 + background: true + rules: + - name: validate-socket-mounts + match: + any: + - resources: + kinds: + - Pod + validate: + cel: + variables: + - name: hasVolumes + expression: "!has(object.spec.volumes)" + - name: volumes + expression: "object.spec.volumes" + - name: volumesWithHostPath + expression: "variables.volumes.filter(volume, has(volume.hostPath))" + expressions: + - expression: >- + variables.hasVolumes || + variables.volumesWithHostPath.all(volume, !volume.hostPath.path.matches('/var/run/docker.sock')) + message: "Use of the Docker Unix socket is not allowed." + + - expression: >- + variables.hasVolumes || + variables.volumesWithHostPath.all(volume, !volume.hostPath.path.matches('/var/run/containerd/containerd.sock')) + message: "Use of the Containerd Unix socket is not allowed." + + - expression: >- + variables.hasVolumes || + variables.volumesWithHostPath.all(volume, !volume.hostPath.path.matches('/var/run/crio/crio.sock')) + message: "Use of the CRI-O Unix socket is not allowed." + + - expression: >- + variables.hasVolumes || + variables.volumesWithHostPath.all(volume, !volume.hostPath.path.matches('/var/run/cri-dockerd.sock')) + message: "Use of the Docker CRI socket is not allowed." + diff --git a/best-practices-cel/disallow-default-namespace/.chainsaw-test/chainsaw-test.yaml b/best-practices-cel/disallow-default-namespace/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..3201f549b --- /dev/null +++ b/best-practices-cel/disallow-default-namespace/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,56 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: disallow-default-namespace +spec: + steps: + - name: step-01 + try: + - apply: + file: ../disallow-default-namespace.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: disallow-default-namespace + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: ns.yaml + - name: step-03 + try: + - apply: + file: good-resources.yaml + - apply: + expect: + - check: + ($error != null): true + file: pod-default.yaml + - apply: + expect: + - check: + ($error != null): true + file: ds-default.yaml + - apply: + expect: + - check: + ($error != null): true + file: job-default.yaml + - apply: + expect: + - check: + ($error != null): true + file: ss-default.yaml + - apply: + expect: + - check: + ($error != null): true + file: deploy-default.yaml + diff --git a/best-practices-cel/disallow-default-namespace/.chainsaw-test/deploy-default.yaml b/best-practices-cel/disallow-default-namespace/.chainsaw-test/deploy-default.yaml new file mode 100644 index 000000000..2d193c349 --- /dev/null +++ b/best-practices-cel/disallow-default-namespace/.chainsaw-test/deploy-default.yaml @@ -0,0 +1,24 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: busybox + name: bad-busybox + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + template: + metadata: + labels: + app: busybox + spec: + containers: + - image: busybox:v1.35 + name: busybox + command: + - "sleep" + - "3000" + diff --git a/best-practices-cel/disallow-default-namespace/.chainsaw-test/ds-default.yaml b/best-practices-cel/disallow-default-namespace/.chainsaw-test/ds-default.yaml new file mode 100644 index 000000000..98be9a803 --- /dev/null +++ b/best-practices-cel/disallow-default-namespace/.chainsaw-test/ds-default.yaml @@ -0,0 +1,21 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: bad-daemonset + namespace: default +spec: + selector: + matchLabels: + name: good-daemonset + template: + metadata: + labels: + name: good-daemonset + spec: + containers: + - image: busybox:v1.35 + name: busybox + command: + - "sleep" + - "3000" + diff --git a/best-practices-cel/disallow-default-namespace/.chainsaw-test/good-resources.yaml b/best-practices-cel/disallow-default-namespace/.chainsaw-test/good-resources.yaml new file mode 100644 index 000000000..9d3b757a7 --- /dev/null +++ b/best-practices-cel/disallow-default-namespace/.chainsaw-test/good-resources.yaml @@ -0,0 +1,98 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 + namespace: not-default-ns +spec: + containers: + - name: busybox + image: "busybox:v1.35" + command: + - "sleep" + - "3000" +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: busybox + name: busybox + namespace: not-default-ns +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + template: + metadata: + labels: + app: busybox + spec: + containers: + - image: busybox:v1.35 + name: busybox + command: + - "sleep" + - "3000" +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: good-daemonset + namespace: not-default-ns +spec: + selector: + matchLabels: + name: good-daemonset + template: + metadata: + labels: + name: good-daemonset + spec: + containers: + - image: busybox:v1.35 + name: busybox + command: + - "sleep" + - "3000" +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: good-job + namespace: not-default-ns +spec: + template: + spec: + containers: + - image: busybox:v1.35 + name: busybox + command: + - "sleep" + - "3000" + restartPolicy: Never +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: good-statefulset + namespace: not-default-ns +spec: + selector: + matchLabels: + app: busybox + serviceName: "busyservice" + replicas: 1 + minReadySeconds: 10 + template: + metadata: + labels: + app: busybox + spec: + containers: + - image: busybox:v1.35 + name: busybox + command: + - "sleep" + - "3000" + diff --git a/best-practices-cel/disallow-default-namespace/.chainsaw-test/job-default.yaml b/best-practices-cel/disallow-default-namespace/.chainsaw-test/job-default.yaml new file mode 100644 index 000000000..6507f7b52 --- /dev/null +++ b/best-practices-cel/disallow-default-namespace/.chainsaw-test/job-default.yaml @@ -0,0 +1,16 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: bad-job + namespace: default +spec: + template: + spec: + containers: + - image: busybox:v1.35 + name: busybox + command: + - "sleep" + - "3000" + restartPolicy: Never + diff --git a/best-practices-cel/disallow-default-namespace/.chainsaw-test/ns.yaml b/best-practices-cel/disallow-default-namespace/.chainsaw-test/ns.yaml new file mode 100755 index 000000000..31d4f3f6d --- /dev/null +++ b/best-practices-cel/disallow-default-namespace/.chainsaw-test/ns.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: not-default-ns + diff --git a/best-practices-cel/disallow-default-namespace/.chainsaw-test/pod-default.yaml b/best-practices-cel/disallow-default-namespace/.chainsaw-test/pod-default.yaml new file mode 100644 index 000000000..f961230d8 --- /dev/null +++ b/best-practices-cel/disallow-default-namespace/.chainsaw-test/pod-default.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 + namespace: default +spec: + containers: + - name: busybox + image: "busybox:v1.35" + command: + - "sleep" + - "3000" + diff --git a/best-practices-cel/disallow-default-namespace/.chainsaw-test/policy-ready.yaml b/best-practices-cel/disallow-default-namespace/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..1ce933d92 --- /dev/null +++ b/best-practices-cel/disallow-default-namespace/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-default-namespace +status: + ready: true + diff --git a/best-practices-cel/disallow-default-namespace/.chainsaw-test/ss-default.yaml b/best-practices-cel/disallow-default-namespace/.chainsaw-test/ss-default.yaml new file mode 100644 index 000000000..aacb55f86 --- /dev/null +++ b/best-practices-cel/disallow-default-namespace/.chainsaw-test/ss-default.yaml @@ -0,0 +1,24 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: good-statefulset + namespace: default +spec: + selector: + matchLabels: + app: busybox + serviceName: "busyservice" + replicas: 1 + minReadySeconds: 10 + template: + metadata: + labels: + app: busybox + spec: + containers: + - image: busybox:v1.35 + name: busybox + command: + - "sleep" + - "3000" + diff --git a/best-practices-cel/disallow-default-namespace/.kyverno-test/kyverno-test.yaml b/best-practices-cel/disallow-default-namespace/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..f4eb1a74a --- /dev/null +++ b/best-practices-cel/disallow-default-namespace/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,34 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: disallow-default-namespace +policies: +- ../disallow-default-namespace.yaml +resources: +- resource.yaml +results: +- kind: Pod + policy: disallow-default-namespace + resources: + - badpod01 + result: fail + rule: validate-namespace +- kind: Pod + policy: disallow-default-namespace + resources: + - goodpod01 + result: pass + rule: validate-namespace +- kind: Deployment + policy: disallow-default-namespace + resources: + - baddeployment01 + result: fail + rule: validate-podcontroller-namespace +- kind: Deployment + policy: disallow-default-namespace + resources: + - gooddeployment01 + result: pass + rule: validate-podcontroller-namespace + diff --git a/best-practices-cel/disallow-default-namespace/.kyverno-test/resource.yaml b/best-practices-cel/disallow-default-namespace/.kyverno-test/resource.yaml new file mode 100644 index 000000000..6a9b6d05f --- /dev/null +++ b/best-practices-cel/disallow-default-namespace/.kyverno-test/resource.yaml @@ -0,0 +1,67 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 + namespace: default + labels: + app: myapp +spec: + containers: + - name: nginx + image: nginx +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 + namespace: foo + labels: + app: myapp +spec: + containers: + - name: nginx + image: nginx +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: baddeployment01 + labels: + app: busybox +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + template: + metadata: + labels: + app: busybox + spec: + containers: + - image: busybox:1.28 + name: busybox + command: ["sleep", "9999"] +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gooddeployment01 + labels: + app: busybox + namespace: foo +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + template: + metadata: + labels: + app: busybox + spec: + containers: + - image: busybox:1.28 + name: busybox + command: ["sleep", "9999"] + diff --git a/best-practices-cel/disallow-default-namespace/artifacthub-pkg.yml b/best-practices-cel/disallow-default-namespace/artifacthub-pkg.yml new file mode 100644 index 000000000..a1e3896fd --- /dev/null +++ b/best-practices-cel/disallow-default-namespace/artifacthub-pkg.yml @@ -0,0 +1,24 @@ +name: disallow-default-namespace-cel +version: 1.0.0 +displayName: Disallow Default Namespace in CEL expressions +description: >- + Kubernetes Namespaces are an optional feature that provide a way to segment and isolate cluster resources across multiple applications and users. As a best practice, workloads should be isolated with Namespaces. Namespaces should be required and the default (empty) Namespace should not be used. This policy validates that Pods specify a Namespace name other than `default`. Rule auto-generation is disabled here due to Pod controllers need to specify the `namespace` field under the top-level `metadata` object and not at the Pod template level. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/best-practices-cel/disallow-default-namespace/disallow-default-namespace.yaml + ``` +keywords: + - kyverno + - Multi-Tenancy + - CEL Expressions +readme: | + Kubernetes Namespaces are an optional feature that provide a way to segment and isolate cluster resources across multiple applications and users. As a best practice, workloads should be isolated with Namespaces. Namespaces should be required and the default (empty) Namespace should not be used. This policy validates that Pods specify a Namespace name other than `default`. Rule auto-generation is disabled here due to Pod controllers need to specify the `namespace` field under the top-level `metadata` object and not at the Pod template level. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Multi-Tenancy in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Pod" +digest: ab82cba43ef60cf84553fd3119a13db17cc1bc97d8d9a71526b7d3a636c6ce2b +createdAt: "2024-03-08T06:15:05Z" + diff --git a/best-practices-cel/disallow-default-namespace/disallow-default-namespace.yaml b/best-practices-cel/disallow-default-namespace/disallow-default-namespace.yaml new file mode 100644 index 000000000..70a09fefd --- /dev/null +++ b/best-practices-cel/disallow-default-namespace/disallow-default-namespace.yaml @@ -0,0 +1,50 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-default-namespace + annotations: + pod-policies.kyverno.io/autogen-controllers: none + policies.kyverno.io/title: Disallow Default Namespace in CEL expressions + policies.kyverno.io/minversion: 1.11.0 + policies.kyverno.io/category: Multi-Tenancy in CEL + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + policies.kyverno.io/description: >- + Kubernetes Namespaces are an optional feature that provide a way to segment and + isolate cluster resources across multiple applications and users. As a best + practice, workloads should be isolated with Namespaces. Namespaces should be required + and the default (empty) Namespace should not be used. This policy validates that Pods + specify a Namespace name other than `default`. Rule auto-generation is disabled here + 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 + background: true + rules: + - name: validate-namespace + match: + any: + - resources: + kinds: + - Pod + validate: + cel: + expressions: + - expression: "namespaceObject.metadata.name != 'default'" + message: "Using 'default' namespace is not allowed." + - name: validate-podcontroller-namespace + match: + any: + - resources: + kinds: + - DaemonSet + - Deployment + - Job + - StatefulSet + validate: + cel: + expressions: + - expression: "namespaceObject.metadata.name != 'default'" + message: "Using 'default' namespace is not allowed for pod controllers." + diff --git a/best-practices-cel/disallow-empty-ingress-host/.chainsaw-test/chainsaw-test.yaml b/best-practices-cel/disallow-empty-ingress-host/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..6dfc3e124 --- /dev/null +++ b/best-practices-cel/disallow-empty-ingress-host/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,42 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: disallow-empty-ingress-host +spec: + steps: + - name: step-01 + try: + - apply: + file: ../disallow-empty-ingress-host.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: disallow-empty-ingress-host + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: good-ingress.yaml + - apply: + expect: + - check: + ($error != null): true + file: no-host-ingress.yaml + - apply: + expect: + - check: + ($error != null): true + file: no-host-fail-first.yaml + - apply: + expect: + - check: + ($error != null): true + file: no-host-success-first.yaml + diff --git a/best-practices-cel/disallow-empty-ingress-host/.chainsaw-test/good-ingress.yaml b/best-practices-cel/disallow-empty-ingress-host/.chainsaw-test/good-ingress.yaml new file mode 100644 index 000000000..6eead42ed --- /dev/null +++ b/best-practices-cel/disallow-empty-ingress-host/.chainsaw-test/good-ingress.yaml @@ -0,0 +1,27 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: ingress-wildcard-host +spec: + rules: + - host: "foo.bar.com" + http: + paths: + - pathType: Prefix + path: "/bar" + backend: + service: + name: service1 + port: + number: 80 + - host: "*.foo.com" + http: + paths: + - pathType: Prefix + path: "/foo" + backend: + service: + name: service2 + port: + number: 80 + diff --git a/best-practices-cel/disallow-empty-ingress-host/.chainsaw-test/no-host-fail-first.yaml b/best-practices-cel/disallow-empty-ingress-host/.chainsaw-test/no-host-fail-first.yaml new file mode 100644 index 000000000..9e130859b --- /dev/null +++ b/best-practices-cel/disallow-empty-ingress-host/.chainsaw-test/no-host-fail-first.yaml @@ -0,0 +1,26 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: ingress-host +spec: + rules: + - http: + paths: + - pathType: Prefix + path: "/bar" + backend: + service: + name: service1 + port: + number: 80 + - host: "bar.foo.com" + http: + paths: + - pathType: Prefix + path: "/foo" + backend: + service: + name: service2 + port: + number: 80 + diff --git a/best-practices-cel/disallow-empty-ingress-host/.chainsaw-test/no-host-ingress.yaml b/best-practices-cel/disallow-empty-ingress-host/.chainsaw-test/no-host-ingress.yaml new file mode 100644 index 000000000..9da802d65 --- /dev/null +++ b/best-practices-cel/disallow-empty-ingress-host/.chainsaw-test/no-host-ingress.yaml @@ -0,0 +1,18 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: minimal-ingress + annotations: + nginx.ingress.kubernetes.io/rewrite-target: / +spec: + rules: + - http: + paths: + - path: /testpath + pathType: Prefix + backend: + service: + name: test + port: + number: 80 + diff --git a/best-practices-cel/disallow-empty-ingress-host/.chainsaw-test/no-host-success-first.yaml b/best-practices-cel/disallow-empty-ingress-host/.chainsaw-test/no-host-success-first.yaml new file mode 100644 index 000000000..3ceca1142 --- /dev/null +++ b/best-practices-cel/disallow-empty-ingress-host/.chainsaw-test/no-host-success-first.yaml @@ -0,0 +1,26 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: ingress-host +spec: + rules: + - host: "bar.foo.com" + http: + paths: + - pathType: Prefix + path: "/bar" + backend: + service: + name: service1 + port: + number: 80 + - http: + paths: + - pathType: Prefix + path: "/foo" + backend: + service: + name: service2 + port: + number: 80 + diff --git a/best-practices-cel/disallow-empty-ingress-host/.chainsaw-test/policy-ready.yaml b/best-practices-cel/disallow-empty-ingress-host/.chainsaw-test/policy-ready.yaml new file mode 100644 index 000000000..9a61e3f0d --- /dev/null +++ b/best-practices-cel/disallow-empty-ingress-host/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-empty-ingress-host +status: + ready: true + diff --git a/best-practices-cel/disallow-empty-ingress-host/.kyverno-test/kyverno-test.yaml b/best-practices-cel/disallow-empty-ingress-host/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..99d221a80 --- /dev/null +++ b/best-practices-cel/disallow-empty-ingress-host/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,22 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: disallow-empty-ingress-host +policies: +- ../disallow-empty-ingress-host.yaml +resources: +- resource.yaml +results: +- kind: Ingress + policy: disallow-empty-ingress-host + resources: + - minimal-ingress + result: fail + rule: disallow-empty-ingress-host +- kind: Ingress + policy: disallow-empty-ingress-host + resources: + - ingress-wildcard-host + result: pass + rule: disallow-empty-ingress-host + diff --git a/best-practices-cel/disallow-empty-ingress-host/.kyverno-test/resource.yaml b/best-practices-cel/disallow-empty-ingress-host/.kyverno-test/resource.yaml new file mode 100644 index 000000000..1c48af4ef --- /dev/null +++ b/best-practices-cel/disallow-empty-ingress-host/.kyverno-test/resource.yaml @@ -0,0 +1,45 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: ingress-wildcard-host +spec: + rules: + - host: "foo.bar.com" + http: + paths: + - pathType: Prefix + path: "/bar" + backend: + service: + name: service1 + port: + number: 80 + - host: "*.foo.com" + http: + paths: + - pathType: Prefix + path: "/foo" + backend: + service: + name: service2 + port: + number: 80 +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: minimal-ingress + annotations: + nginx.ingress.kubernetes.io/rewrite-target: / +spec: + rules: + - http: + paths: + - path: /testpath + pathType: Prefix + backend: + service: + name: test + port: + number: 80 + diff --git a/best-practices-cel/disallow-empty-ingress-host/artifacthub-pkg.yml b/best-practices-cel/disallow-empty-ingress-host/artifacthub-pkg.yml new file mode 100644 index 000000000..43a417ede --- /dev/null +++ b/best-practices-cel/disallow-empty-ingress-host/artifacthub-pkg.yml @@ -0,0 +1,24 @@ +name: disallow-empty-ingress-host-cel +version: 1.0.0 +displayName: Disallow empty Ingress host in CEL expressions +description: >- + An ingress resource needs to define an actual host name in order to be valid. This policy ensures that there is a hostname for each rule defined. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/best-practices-cel/disallow-empty-ingress-host/disallow-empty-ingress-host.yaml + ``` +keywords: + - kyverno + - Best Practices + - CEL Expressions +readme: | + An ingress resource needs to define an actual host name in order to be valid. This policy ensures that there is a hostname for each rule defined. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Best Practices in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Ingress" +digest: 9cb3d5814cea4a34de185ce8fd469762a83ef93b910e70b2e6a9ec953e65448c +createdAt: "2024-03-09T14:19:51Z" + diff --git a/best-practices-cel/disallow-empty-ingress-host/disallow-empty-ingress-host.yaml b/best-practices-cel/disallow-empty-ingress-host/disallow-empty-ingress-host.yaml new file mode 100644 index 000000000..6a243a03d --- /dev/null +++ b/best-practices-cel/disallow-empty-ingress-host/disallow-empty-ingress-host.yaml @@ -0,0 +1,33 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-empty-ingress-host + annotations: + policies.kyverno.io/title: Disallow empty Ingress host in CEL expressions + policies.kyverno.io/category: Best Practices in CEL + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Ingress + policies.kyverno.io/description: >- + An ingress resource needs to define an actual host name + in order to be valid. This policy ensures that there is a + hostname for each rule defined. +spec: + validationFailureAction: Audit + background: false + rules: + - name: disallow-empty-ingress-host + match: + any: + - resources: + kinds: + - Ingress + validate: + cel: + expressions: + - expression: >- + !has(object.spec.rules) || + object.spec.rules.all(rule, has(rule.host) && has(rule.http)) + message: "The Ingress host name must be defined, not empty." + diff --git a/best-practices-cel/disallow-helm-tiller/.chainsaw-test/bad-deploy.yaml b/best-practices-cel/disallow-helm-tiller/.chainsaw-test/bad-deploy.yaml new file mode 100644 index 000000000..bf734c173 --- /dev/null +++ b/best-practices-cel/disallow-helm-tiller/.chainsaw-test/bad-deploy.yaml @@ -0,0 +1,22 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: baddeployment-ht + labels: + app: busybox +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + template: + metadata: + labels: + app: busybox + spec: + containers: + - image: busybox + name: busybox + - image: docker.io/tiller:latest + name: helm-tiller + diff --git a/best-practices-cel/disallow-helm-tiller/.chainsaw-test/bad-pod-fail-first.yaml b/best-practices-cel/disallow-helm-tiller/.chainsaw-test/bad-pod-fail-first.yaml new file mode 100644 index 000000000..8bb9976d8 --- /dev/null +++ b/best-practices-cel/disallow-helm-tiller/.chainsaw-test/bad-pod-fail-first.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod02-ht +spec: + containers: + - name: helm-tiller + image: docker.io/tiller:latest + - name: somebox + image: busybox:1.35 + diff --git a/best-practices-cel/disallow-helm-tiller/.chainsaw-test/bad-pod-success-first.yaml b/best-practices-cel/disallow-helm-tiller/.chainsaw-test/bad-pod-success-first.yaml new file mode 100644 index 000000000..0080cc324 --- /dev/null +++ b/best-practices-cel/disallow-helm-tiller/.chainsaw-test/bad-pod-success-first.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod03-ht +spec: + containers: + - name: somebox + image: busybox:1.35 + - name: helm-tiller + image: docker.io/tiller:latest + diff --git a/best-practices-cel/disallow-helm-tiller/.chainsaw-test/bad-pod.yaml b/best-practices-cel/disallow-helm-tiller/.chainsaw-test/bad-pod.yaml new file mode 100644 index 000000000..789e0bcaa --- /dev/null +++ b/best-practices-cel/disallow-helm-tiller/.chainsaw-test/bad-pod.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod01-ht +spec: + containers: + - name: helm-tiller + image: docker.io/tiller:latest + diff --git a/best-practices-cel/disallow-helm-tiller/.chainsaw-test/chainsaw-test.yaml b/best-practices-cel/disallow-helm-tiller/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..7ca0071c4 --- /dev/null +++ b/best-practices-cel/disallow-helm-tiller/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,49 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: disallow-helm-tiller +spec: + steps: + - name: step-01 + try: + - apply: + file: ../disallow-helm-tiller.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: disallow-helm-tiller + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: good-pod.yaml + - apply: + file: good-deploy.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-pod.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-deploy.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-pod-fail-first.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-pod-success-first.yaml + diff --git a/best-practices-cel/disallow-helm-tiller/.chainsaw-test/good-deploy.yaml b/best-practices-cel/disallow-helm-tiller/.chainsaw-test/good-deploy.yaml new file mode 100644 index 000000000..3e280723c --- /dev/null +++ b/best-practices-cel/disallow-helm-tiller/.chainsaw-test/good-deploy.yaml @@ -0,0 +1,21 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gooddeployment-ht + labels: + app: busybox +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + template: + metadata: + labels: + app: busybox + spec: + containers: + - image: busybox:v1.35 + name: busybox + command: ["sleep", "3600"] + diff --git a/best-practices-cel/disallow-helm-tiller/.chainsaw-test/good-pod.yaml b/best-practices-cel/disallow-helm-tiller/.chainsaw-test/good-pod.yaml new file mode 100644 index 000000000..a4dba0e32 --- /dev/null +++ b/best-practices-cel/disallow-helm-tiller/.chainsaw-test/good-pod.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod-ht +spec: + containers: + - name: busybox + image: busybox:v1.35 + - name: nothelmbox + image: busybox:v1.35 + diff --git a/best-practices-cel/disallow-helm-tiller/.chainsaw-test/policy-ready.yaml b/best-practices-cel/disallow-helm-tiller/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..ee708ab7e --- /dev/null +++ b/best-practices-cel/disallow-helm-tiller/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-helm-tiller +status: + ready: true + diff --git a/best-practices-cel/disallow-helm-tiller/.kyverno-test/kyverno-test.yaml b/best-practices-cel/disallow-helm-tiller/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..b5bbcbdb1 --- /dev/null +++ b/best-practices-cel/disallow-helm-tiller/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,36 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: disallow-helm-tiller +policies: +- ../disallow-helm-tiller.yaml +resources: +- resource.yaml +results: +- kind: Deployment + policy: disallow-helm-tiller + resources: + - baddeployment01 + result: fail + rule: validate-helm-tiller +- kind: Pod + policy: disallow-helm-tiller + resources: + - badpod01 + - badpod02 + result: fail + rule: validate-helm-tiller +- kind: Deployment + policy: disallow-helm-tiller + resources: + - gooddeployment01 + result: pass + rule: validate-helm-tiller +- kind: Pod + policy: disallow-helm-tiller + resources: + - goodpod01 + - goodpod02 + result: pass + rule: validate-helm-tiller + diff --git a/best-practices-cel/disallow-helm-tiller/.kyverno-test/resource.yaml b/best-practices-cel/disallow-helm-tiller/.kyverno-test/resource.yaml new file mode 100644 index 000000000..6c2a16502 --- /dev/null +++ b/best-practices-cel/disallow-helm-tiller/.kyverno-test/resource.yaml @@ -0,0 +1,83 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 +spec: + containers: + - name: helm-tiller + image: docker.io/tiller:latest +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod02 +spec: + containers: + - name: busybox + image: busybox:1.28 + - name: helm-tiller + image: docker.io/tiller:latest +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 +spec: + containers: + - name: busybox + image: busybox +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod02 +spec: + containers: + - name: busybox + image: busybox + - name: nginx + image: nginx +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gooddeployment01 + labels: + app: busybox + namespace: foo +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + template: + metadata: + labels: + app: busybox + spec: + containers: + - image: busybox:1.28 + name: busybox + command: ["sleep", "9999"] +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: baddeployment01 + labels: + app: busybox + namespace: foo +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + template: + metadata: + labels: + app: busybox + spec: + containers: + - image: docker.io/tiller:latest + name: helm-tiller + diff --git a/best-practices-cel/disallow-helm-tiller/artifacthub-pkg.yml b/best-practices-cel/disallow-helm-tiller/artifacthub-pkg.yml new file mode 100644 index 000000000..6e9077843 --- /dev/null +++ b/best-practices-cel/disallow-helm-tiller/artifacthub-pkg.yml @@ -0,0 +1,24 @@ +name: disallow-helm-tiller-cel +version: 1.0.0 +displayName: Disallow Helm Tiller in CEL expressions +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`. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/best-practices-cel/disallow-helm-tiller/disallow-helm-tiller.yaml + ``` +keywords: + - kyverno + - Sample + - CEL Expressions +readme: | + 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`. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Sample in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Pod" +digest: 68bd8e1cf068759dc436032f3bcb1204992b84ba33498ffd76b744329976769e +createdAt: "2024-03-08T06:30:37Z" + diff --git a/best-practices-cel/disallow-helm-tiller/disallow-helm-tiller.yaml b/best-practices-cel/disallow-helm-tiller/disallow-helm-tiller.yaml new file mode 100644 index 000000000..f439c5bed --- /dev/null +++ b/best-practices-cel/disallow-helm-tiller/disallow-helm-tiller.yaml @@ -0,0 +1,33 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-helm-tiller + annotations: + policies.kyverno.io/title: Disallow Helm Tiller in CEL expressions + policies.kyverno.io/category: Sample in CEL + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + 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 + Tiller for these reasons. This policy validates that there is not an image + containing the name `tiller`. +spec: + validationFailureAction: Audit + background: true + rules: + - name: validate-helm-tiller + match: + any: + - resources: + kinds: + - Pod + validate: + cel: + expressions: + - expression: "object.spec.containers.all(container, !container.image.contains('tiller'))" + message: "Helm Tiller is not allowed" + diff --git a/best-practices-cel/disallow-latest-tag/.chainsaw-test/bad-pod-latest-fail-first.yaml b/best-practices-cel/disallow-latest-tag/.chainsaw-test/bad-pod-latest-fail-first.yaml new file mode 100644 index 000000000..8c0b1647f --- /dev/null +++ b/best-practices-cel/disallow-latest-tag/.chainsaw-test/bad-pod-latest-fail-first.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod-latest +spec: + containers: + - name: busybox + image: busybox:latest + - name: nginx + image: nginx:1.35 + diff --git a/best-practices-cel/disallow-latest-tag/.chainsaw-test/bad-pod-latest-success-first.yaml b/best-practices-cel/disallow-latest-tag/.chainsaw-test/bad-pod-latest-success-first.yaml new file mode 100644 index 000000000..a0d5d9557 --- /dev/null +++ b/best-practices-cel/disallow-latest-tag/.chainsaw-test/bad-pod-latest-success-first.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod-latest +spec: + containers: + - name: nginx + image: nginx:1.35 + - name: busybox + image: busybox:latest + diff --git a/best-practices-cel/disallow-latest-tag/.chainsaw-test/bad-pod-no-tag.yaml b/best-practices-cel/disallow-latest-tag/.chainsaw-test/bad-pod-no-tag.yaml new file mode 100644 index 000000000..8645ee32e --- /dev/null +++ b/best-practices-cel/disallow-latest-tag/.chainsaw-test/bad-pod-no-tag.yaml @@ -0,0 +1,33 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod-no-tag +spec: + containers: + - name: busybox + image: busybox + - name: nginx + image: nginx:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod-no-tag +spec: + containers: + - name: nginx + image: nginx:1.35 + - name: busybox + image: busybox +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod-no-tag +spec: + containers: + - name: busybox + image: busybox + - name: nginx + image: nginx:latest + diff --git a/best-practices-cel/disallow-latest-tag/.chainsaw-test/chainsaw-test.yaml b/best-practices-cel/disallow-latest-tag/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..d87f9311f --- /dev/null +++ b/best-practices-cel/disallow-latest-tag/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,42 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: disallow-latest-tag +spec: + steps: + - name: step-01 + try: + - apply: + file: ../disallow-latest-tag.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: disallow-latest-tag + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: good-pod.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-pod-latest-fail-first.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-pod-latest-success-first.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-pod-no-tag.yaml + diff --git a/best-practices-cel/disallow-latest-tag/.chainsaw-test/good-pod.yaml b/best-practices-cel/disallow-latest-tag/.chainsaw-test/good-pod.yaml new file mode 100644 index 000000000..588b2187c --- /dev/null +++ b/best-practices-cel/disallow-latest-tag/.chainsaw-test/good-pod.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod-ht +spec: + containers: + - name: busybox + image: busybox:v1.35 + diff --git a/best-practices-cel/disallow-latest-tag/.chainsaw-test/policy-ready.yaml b/best-practices-cel/disallow-latest-tag/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..86e057994 --- /dev/null +++ b/best-practices-cel/disallow-latest-tag/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-latest-tag +status: + ready: true + diff --git a/best-practices-cel/disallow-latest-tag/.kyverno-test/kyverno-test.yaml b/best-practices-cel/disallow-latest-tag/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..b7a1f2a16 --- /dev/null +++ b/best-practices-cel/disallow-latest-tag/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,48 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: disallow-latest-tag +policies: +- ../disallow-latest-tag.yaml +resources: +- resource.yaml +results: +- kind: Deployment + policy: disallow-latest-tag + resources: + - baddeployment01 + result: fail + rule: require-and-validate-image-tag +- kind: Pod + policy: disallow-latest-tag + resources: + - badpod01 + - badpod02 + result: fail + rule: require-and-validate-image-tag +- kind: Deployment + policy: disallow-latest-tag + resources: + - gooddeployment01 + result: pass + rule: require-and-validate-image-tag +- kind: Pod + policy: disallow-latest-tag + resources: + - myapp-pod + result: pass + rule: require-and-validate-image-tag +- kind: Deployment + policy: disallow-latest-tag + resources: + - vit-baddeployment01 + result: fail + rule: require-and-validate-image-tag +- kind: Pod + policy: disallow-latest-tag + resources: + - vit-badpod01 + - vit-badpod02 + result: fail + rule: require-and-validate-image-tag + diff --git a/best-practices-cel/disallow-latest-tag/.kyverno-test/resource.yaml b/best-practices-cel/disallow-latest-tag/.kyverno-test/resource.yaml new file mode 100644 index 000000000..f4f709070 --- /dev/null +++ b/best-practices-cel/disallow-latest-tag/.kyverno-test/resource.yaml @@ -0,0 +1,122 @@ +apiVersion: v1 +kind: Pod +metadata: + name: myapp-pod + labels: + app: myapp +spec: + containers: + - name: nginx + image: nginx:1.12 +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 + labels: + app: myapp +spec: + containers: + - name: nginx + image: nginx +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod02 + labels: + app: myapp +spec: + containers: + - name: busybox + image: busybox:1.28 + - name: nginx + image: nginx +--- +apiVersion: v1 +kind: Pod +metadata: + name: vit-badpod01 + labels: + app: myapp +spec: + containers: + - name: nginx + image: nginx:latest +--- +apiVersion: v1 +kind: Pod +metadata: + name: vit-badpod02 + labels: + app: myapp +spec: + containers: + - name: busybox + image: busybox:1.28 + - name: nginx + image: nginx:latest +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gooddeployment01 + labels: + app: busybox +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + template: + metadata: + labels: + app: busybox + spec: + containers: + - image: busybox:1.28 + name: busybox + command: ["sleep", "9999"] +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: baddeployment01 + labels: + app: busybox +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + template: + metadata: + labels: + app: busybox + spec: + containers: + - image: busybox + name: busybox + command: ["sleep", "9999"] +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: vit-baddeployment01 + labels: + app: busybox +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + template: + metadata: + labels: + app: busybox + spec: + containers: + - image: busybox:latest + name: busybox + command: ["sleep", "9999"] + diff --git a/best-practices-cel/disallow-latest-tag/artifacthub-pkg.yml b/best-practices-cel/disallow-latest-tag/artifacthub-pkg.yml new file mode 100644 index 000000000..6507d2f0c --- /dev/null +++ b/best-practices-cel/disallow-latest-tag/artifacthub-pkg.yml @@ -0,0 +1,24 @@ +name: disallow-latest-tag-cel +version: 1.0.0 +displayName: Disallow Latest Tag in CEL expressions +description: >- + The ':latest' tag is mutable and can lead to unexpected errors if the image changes. A best practice is to use an immutable tag that maps to a specific version of an application Pod. This policy validates that the image specifies a tag and that it is not called `latest`. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/best-practices-cel/disallow-latest-tag/disallow-latest-tag.yaml + ``` +keywords: + - kyverno + - Best Practices + - CEL Expressions +readme: | + The ':latest' tag is mutable and can lead to unexpected errors if the image changes. A best practice is to use an immutable tag that maps to a specific version of an application Pod. This policy validates that the image specifies a tag and that it is not called `latest`. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Best Practices in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Pod" +digest: a477c5213f24a7096495b438a30733d4bbea2da32b2e1f8f71696d72d68d7704 +createdAt: "2024-03-07T20:17:11Z" + diff --git a/best-practices-cel/disallow-latest-tag/disallow-latest-tag.yaml b/best-practices-cel/disallow-latest-tag/disallow-latest-tag.yaml new file mode 100644 index 000000000..6c3b1e74d --- /dev/null +++ b/best-practices-cel/disallow-latest-tag/disallow-latest-tag.yaml @@ -0,0 +1,34 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-latest-tag + annotations: + policies.kyverno.io/title: Disallow Latest Tag in CEL expressions + policies.kyverno.io/category: Best Practices in CEL + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + policies.kyverno.io/description: >- + The ':latest' tag is mutable and can lead to unexpected errors if the + image changes. A best practice is to use an immutable tag that maps to + a specific version of an application Pod. This policy validates that the image + specifies a tag and that it is not called `latest`. +spec: + validationFailureAction: Audit + background: true + rules: + - name: require-and-validate-image-tag + match: + any: + - resources: + kinds: + - Pod + validate: + cel: + expressions: + - expression: "object.spec.containers.all(container, container.image.contains(':'))" + message: "An image tag is required." + - expression: "object.spec.containers.all(container, !container.image.endsWith(':latest'))" + message: "Using a mutable image tag e.g. 'latest' is not allowed." + diff --git a/best-practices-cel/require-drop-all/.chainsaw-test/bad-pod-containers.yaml b/best-practices-cel/require-drop-all/.chainsaw-test/bad-pod-containers.yaml new file mode 100644 index 000000000..0584b0c55 --- /dev/null +++ b/best-practices-cel/require-drop-all/.chainsaw-test/bad-pod-containers.yaml @@ -0,0 +1,62 @@ +apiVersion: v1 +kind: Pod +metadata: + name: add-capabilities-bad +spec: + initContainers: + - name: init + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + - name: init2 + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + containers: + - name: add-capabilities + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + - name: add-capabilities-again + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: add-capabilities-bad +spec: + initContainers: + - name: init + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + - name: init2 + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + containers: + - name: add-capabilities-again + image: busybox:1.35 + - name: add-capabilities + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + diff --git a/best-practices-cel/require-drop-all/.chainsaw-test/bad-pod-corner.yaml b/best-practices-cel/require-drop-all/.chainsaw-test/bad-pod-corner.yaml new file mode 100644 index 000000000..bad0b495a --- /dev/null +++ b/best-practices-cel/require-drop-all/.chainsaw-test/bad-pod-corner.yaml @@ -0,0 +1,55 @@ +apiVersion: v1 +kind: Pod +metadata: + name: add-capabilities-bad +spec: + containers: + - name: add-capabilities + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + - name: add-capabilities-again + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW +--- +apiVersion: v1 +kind: Pod +metadata: + name: add-capabilities-bad +spec: + containers: + - name: add-capabilities + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + - name: add-capabilities-again + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL +--- +apiVersion: v1 +kind: Pod +metadata: + name: add-capabilities-bad +spec: + containers: + - name: init + image: busybox:1.35 + securityContext: + capabilities: + drop: + - ALL + - name: init-again + image: busybox:1.35 + diff --git a/best-practices-cel/require-drop-all/.chainsaw-test/bad-pod-initcontainers.yaml b/best-practices-cel/require-drop-all/.chainsaw-test/bad-pod-initcontainers.yaml new file mode 100644 index 000000000..de67854b4 --- /dev/null +++ b/best-practices-cel/require-drop-all/.chainsaw-test/bad-pod-initcontainers.yaml @@ -0,0 +1,48 @@ +apiVersion: v1 +kind: Pod +metadata: + name: add-capabilities-bad +spec: + initContainers: + - name: init + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + - name: init2 + image: busybox:1.35 + containers: + - name: add-capabilities + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL +--- +apiVersion: v1 +kind: Pod +metadata: + name: add-capabilities-bad +spec: + initContainers: + - name: init + image: busybox:1.35 + - name: init2 + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + containers: + - name: add-capabilities + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + diff --git a/best-practices-cel/require-drop-all/.chainsaw-test/bad-podcontrollers.yaml b/best-practices-cel/require-drop-all/.chainsaw-test/bad-podcontrollers.yaml new file mode 100644 index 000000000..254904bfb --- /dev/null +++ b/best-practices-cel/require-drop-all/.chainsaw-test/bad-podcontrollers.yaml @@ -0,0 +1,154 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: dropall-baddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + initContainers: + - name: init + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + - name: init2 + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + containers: + - name: add-capabilities + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + - name: add-capabilities-again + image: busybox:1.35 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: dropall-baddeployment02 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + initContainers: + - name: init + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + - name: init2 + image: busybox:1.35 + containers: + - name: add-capabilities + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + - name: add-capabilities-again + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: dropall-badcronjob01 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + initContainers: + - name: init + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + - name: init2 + image: busybox:1.35 + containers: + - name: add-capabilities + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + - name: add-capabilities-again + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: dropall-badcronjob02 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + initContainers: + - name: init + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + - name: init2 + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + containers: + - name: add-capabilities + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + - name: add-capabilities-again + image: busybox:1.35 + diff --git a/best-practices-cel/require-drop-all/.chainsaw-test/chainsaw-test.yaml b/best-practices-cel/require-drop-all/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..fef0c209b --- /dev/null +++ b/best-practices-cel/require-drop-all/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,51 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: require-drop-all +spec: + # disable templating because it can cause issues with CEL expressions + template: false + steps: + - name: step-01 + try: + - apply: + file: ../require-drop-all.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: drop-all-capabilities + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: good-pod.yaml + - apply: + file: good-podcontrollers.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-pod-containers.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-pod-initcontainers.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-pod-corner.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-podcontrollers.yaml + diff --git a/best-practices-cel/require-drop-all/.chainsaw-test/good-pod.yaml b/best-practices-cel/require-drop-all/.chainsaw-test/good-pod.yaml new file mode 100644 index 000000000..c8dc9dc3a --- /dev/null +++ b/best-practices-cel/require-drop-all/.chainsaw-test/good-pod.yaml @@ -0,0 +1,28 @@ +apiVersion: v1 +kind: Pod +metadata: + name: add-capabilities-good +spec: + initContainers: + - name: init + image: busybox:1.35 + securityContext: + capabilities: + drop: + - ALL + containers: + - name: add-capabilities + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + - name: add-capabilities-again + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + diff --git a/best-practices-cel/require-drop-all/.chainsaw-test/good-podcontrollers.yaml b/best-practices-cel/require-drop-all/.chainsaw-test/good-podcontrollers.yaml new file mode 100644 index 000000000..ddbf2e531 --- /dev/null +++ b/best-practices-cel/require-drop-all/.chainsaw-test/good-podcontrollers.yaml @@ -0,0 +1,87 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: dropall-gooddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + initContainers: + - name: init + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + - name: init2 + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + containers: + - name: add-capabilities + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + - name: add-capabilities-again + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: dropall-goodcronjob01 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + initContainers: + - name: init + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + - name: init2 + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + containers: + - name: add-capabilities + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + - name: add-capabilities-again + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + diff --git a/best-practices-cel/require-drop-all/.chainsaw-test/policy-ready.yaml b/best-practices-cel/require-drop-all/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..8a4a66d15 --- /dev/null +++ b/best-practices-cel/require-drop-all/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: drop-all-capabilities +status: + ready: true + diff --git a/best-practices-cel/require-drop-all/.kyverno-test/kyverno-test.yaml b/best-practices-cel/require-drop-all/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..448b3f723 --- /dev/null +++ b/best-practices-cel/require-drop-all/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,22 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: require-drop-all +policies: +- ../require-drop-all.yaml +resources: +- resource.yaml +results: +- kind: Pod + policy: drop-all-capabilities + resources: + - add-capabilities-bad + result: fail + rule: require-drop-all +- kind: Pod + policy: drop-all-capabilities + resources: + - add-capabilities + result: pass + rule: require-drop-all + diff --git a/best-practices-cel/require-drop-all/.kyverno-test/resource.yaml b/best-practices-cel/require-drop-all/.kyverno-test/resource.yaml new file mode 100644 index 000000000..c687d0672 --- /dev/null +++ b/best-practices-cel/require-drop-all/.kyverno-test/resource.yaml @@ -0,0 +1,38 @@ +apiVersion: v1 +kind: Pod +metadata: + name: add-capabilities +spec: + initContainers: + - name: init + image: gcr.io/google-samples/node-hello:1.0 + securityContext: + capabilities: + drop: + - ALL + containers: + - name: add-capabilities + image: gcr.io/google-samples/node-hello:1.0 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL +--- +apiVersion: v1 +kind: Pod +metadata: + name: add-capabilities-bad +spec: + initContainers: + - name: init + image: gcr.io/google-samples/node-hello:1.0 + containers: + - name: add-capabilities + image: gcr.io/google-samples/node-hello:1.0 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - ALL + diff --git a/best-practices-cel/require-drop-all/artifacthub-pkg.yml b/best-practices-cel/require-drop-all/artifacthub-pkg.yml new file mode 100644 index 000000000..737bd1c04 --- /dev/null +++ b/best-practices-cel/require-drop-all/artifacthub-pkg.yml @@ -0,0 +1,24 @@ +name: require-drop-all-cel +version: 1.0.0 +displayName: Drop All Capabilities in CEL expressions +description: >- + Capabilities permit privileged actions without giving full root access. All capabilities should be dropped from a Pod, with only those required added back. This policy ensures that all containers explicitly specify the `drop: ["ALL"]` 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. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/best-practices-cel/require-drop-all/require-drop-all.yaml + ``` +keywords: + - kyverno + - Best Practices + - CEL Expressions +readme: | + Capabilities permit privileged actions without giving full root access. All capabilities should be dropped from a Pod, with only those required added back. This policy ensures that all containers explicitly specify the `drop: ["ALL"]` 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. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Best Practices in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Pod" +digest: ccf9ef87f6686a93ce044ade6cbe9e68be85679f9a5b315a61eeb0aeafe9ef15 +createdAt: "2024-03-10T05:05:42Z" + diff --git a/best-practices-cel/require-drop-all/require-drop-all.yaml b/best-practices-cel/require-drop-all/require-drop-all.yaml new file mode 100644 index 000000000..5dd9c317c --- /dev/null +++ b/best-practices-cel/require-drop-all/require-drop-all.yaml @@ -0,0 +1,41 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: drop-all-capabilities + annotations: + policies.kyverno.io/title: Drop All Capabilities in CEL expressions + policies.kyverno.io/category: Best Practices in CEL + policies.kyverno.io/severity: medium + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/minversion: 1.11.0 + policies.kyverno.io/subject: Pod + policies.kyverno.io/description: >- + Capabilities permit privileged actions without giving full root access. All + capabilities should be dropped from a Pod, with only those required added back. + This policy ensures that all containers explicitly specify the `drop: ["ALL"]` + 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 + background: true + rules: + - name: require-drop-all + match: + any: + - resources: + kinds: + - Pod + 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: >- + 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')) + message: "Containers must drop `ALL` capabilities." + diff --git a/best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/bad-pod-containers.yaml b/best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/bad-pod-containers.yaml new file mode 100644 index 000000000..c539b4c54 --- /dev/null +++ b/best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/bad-pod-containers.yaml @@ -0,0 +1,62 @@ +apiVersion: v1 +kind: Pod +metadata: + name: drop-capnetraw-bad01 +spec: + initContainers: + - name: init + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW + - name: init2 + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW + containers: + - name: add-capabilities + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW + - name: add-capabilities-again + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: drop-capnetraw-bad02 +spec: + initContainers: + - name: init + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW + - name: init2 + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW + containers: + - name: add-capabilities-again + image: busybox:1.35 + - name: add-capabilities + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW + diff --git a/best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/bad-pod-corner.yaml b/best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/bad-pod-corner.yaml new file mode 100644 index 000000000..a055093a4 --- /dev/null +++ b/best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/bad-pod-corner.yaml @@ -0,0 +1,52 @@ +apiVersion: v1 +kind: Pod +metadata: + name: add-capabilities-bad-001 +spec: + containers: + - name: add-capabilities + image: busybox:1.35 + securityContext: + capabilities: + drop: + - CAP_NET_RAW + - name: add-capabilities-again + image: busybox:1.35 + securityContext: + capabilities: + drop: + - CAP_NET_RAW +--- +apiVersion: v1 +kind: Pod +metadata: + name: add-capabilities-bad-002 +spec: + containers: + - name: add-capabilities + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + - name: add-capabilities-again + image: busybox:1.35 + securityContext: + capabilities: + drop: + - CAP_NET_RAW +--- +apiVersion: v1 +kind: Pod +metadata: + name: add-capabilities-good +spec: + containers: + - name: init + image: busybox:1.35 + securityContext: + capabilities: + drop: + - CAP_NET_RAW + - name: init-again + image: busybox:1.35 + diff --git a/best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/bad-pod-initcontainers.yaml b/best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/bad-pod-initcontainers.yaml new file mode 100644 index 000000000..a4eb4653f --- /dev/null +++ b/best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/bad-pod-initcontainers.yaml @@ -0,0 +1,48 @@ +apiVersion: v1 +kind: Pod +metadata: + name: add-capabilities-bad-1 +spec: + initContainers: + - name: init + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW + - name: init2 + image: busybox:1.35 + containers: + - name: add-capabilities + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW +--- +apiVersion: v1 +kind: Pod +metadata: + name: add-capabilities-bad-2 +spec: + initContainers: + - name: init + image: busybox:1.35 + - name: init2 + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW + containers: + - name: add-capabilities + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW + diff --git a/best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/bad-podcontrollers.yaml b/best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/bad-podcontrollers.yaml new file mode 100644 index 000000000..5bfc7255b --- /dev/null +++ b/best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/bad-podcontrollers.yaml @@ -0,0 +1,154 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: dropall-baddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + initContainers: + - name: init + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW + - name: init2 + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW + containers: + - name: add-capabilities + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW + - name: add-capabilities-again + image: busybox:1.35 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: dropall-baddeployment02 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + initContainers: + - name: init + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW + - name: init2 + image: busybox:1.35 + containers: + - name: add-capabilities + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW + - name: add-capabilities-again + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: dropall-badcronjob01 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + initContainers: + - name: init + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW + - name: init2 + image: busybox:1.35 + containers: + - name: add-capabilities + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW + - name: add-capabilities-again + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: dropall-badcronjob02 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + initContainers: + - name: init + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW + - name: init2 + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW + containers: + - name: add-capabilities + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW + - name: add-capabilities-again + image: busybox:1.35 + diff --git a/best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/chainsaw-test.yaml b/best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..5d9861e55 --- /dev/null +++ b/best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,51 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: require-drop-cap-net-raw +spec: + # disable templating because it can cause issues with CEL expressions + template: false + steps: + - name: step-01 + try: + - apply: + file: ../require-drop-cap-net-raw.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: drop-cap-net-raw + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: good-pod.yaml + - apply: + file: good-podcontrollers.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-pod-containers.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-pod-initcontainers.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-pod-corner.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-podcontrollers.yaml + diff --git a/best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/good-pod.yaml b/best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/good-pod.yaml new file mode 100644 index 000000000..39741ccf6 --- /dev/null +++ b/best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/good-pod.yaml @@ -0,0 +1,26 @@ +apiVersion: v1 +kind: Pod +metadata: + name: drop-capnetraw-good +spec: + initContainers: + - name: init + image: busybox:1.35 + securityContext: + capabilities: + drop: + - CAP_NET_RAW + containers: + - name: add-capabilities + image: busybox:1.35 + securityContext: + capabilities: + drop: + - CAP_NET_RAW + - name: add-capabilities-again + image: busybox:1.35 + securityContext: + capabilities: + drop: + - CAP_NET_RAW + diff --git a/best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/good-podcontrollers.yaml b/best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/good-podcontrollers.yaml new file mode 100644 index 000000000..364041d70 --- /dev/null +++ b/best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/good-podcontrollers.yaml @@ -0,0 +1,87 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: dropcapnetraw-gooddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + initContainers: + - name: init + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW + - name: init2 + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW + containers: + - name: add-capabilities + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW + - name: add-capabilities-again + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: dropcapnetraw-goodcronjob01 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + initContainers: + - name: init + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW + - name: init2 + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW + containers: + - name: add-capabilities + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW + - name: add-capabilities-again + image: busybox:1.35 + securityContext: + capabilities: + add: ["SYS_TIME"] + drop: + - CAP_NET_RAW + diff --git a/best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/policy-ready.yaml b/best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..d82e1d543 --- /dev/null +++ b/best-practices-cel/require-drop-cap-net-raw/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: drop-cap-net-raw +status: + ready: true + diff --git a/best-practices-cel/require-drop-cap-net-raw/.kyverno-test/kyverno-test.yaml b/best-practices-cel/require-drop-cap-net-raw/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..0d98c50aa --- /dev/null +++ b/best-practices-cel/require-drop-cap-net-raw/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,23 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: require-drop-cap-net-raw +policies: +- ../require-drop-cap-net-raw.yaml +resources: +- resource.yaml +results: +- kind: Pod + policy: drop-cap-net-raw + resources: + - badpod01 + - badpod02 + result: fail + rule: require-drop-cap-net-raw +- kind: Pod + policy: drop-cap-net-raw + resources: + - drop-good + result: pass + rule: require-drop-cap-net-raw + diff --git a/best-practices-cel/require-drop-cap-net-raw/.kyverno-test/resource.yaml b/best-practices-cel/require-drop-cap-net-raw/.kyverno-test/resource.yaml new file mode 100644 index 000000000..c3ed3af81 --- /dev/null +++ b/best-practices-cel/require-drop-cap-net-raw/.kyverno-test/resource.yaml @@ -0,0 +1,45 @@ +apiVersion: v1 +kind: Pod +metadata: + name: drop-good +spec: + initContainers: + - name: init + image: gcr.io/google-samples/node-hello:1.0 + securityContext: + capabilities: + drop: ["CAP_NET_RAW"] + containers: + - name: add-capabilities + image: gcr.io/google-samples/node-hello:1.0 + securityContext: + capabilities: + drop: ["CAP_NET_RAW"] +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 +spec: + initContainers: + - name: init + image: gcr.io/google-samples/node-hello:1.0 + securityContext: + capabilities: + drop: ["CAP_NET_RAW"] + containers: + - name: add-capabilities + image: gcr.io/google-samples/node-hello:1.0 + securityContext: + capabilities: + drop: ["CAP_CHOWN"] +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod02 +spec: + containers: + - name: add-capabilities + image: gcr.io/google-samples/node-hello:1.0 + diff --git a/best-practices-cel/require-drop-cap-net-raw/artifacthub-pkg.yml b/best-practices-cel/require-drop-cap-net-raw/artifacthub-pkg.yml new file mode 100644 index 000000000..53e42ed4b --- /dev/null +++ b/best-practices-cel/require-drop-cap-net-raw/artifacthub-pkg.yml @@ -0,0 +1,24 @@ +name: require-drop-cap-net-raw-cel +version: 1.0.0 +displayName: Drop CAP_NET_RAW in CEL expressions +description: >- + Capabilities permit privileged actions without giving full root access. The CAP_NET_RAW capability, enabled by default, allows processes in a container to forge packets and bind to any interface potentially leading to MitM attacks. This policy ensures that all containers explicitly drop the CAP_NET_RAW 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. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/best-practices-cel/require-drop-cap-net-raw/require-drop-cap-net-raw.yaml + ``` +keywords: + - kyverno + - Best Practices + - CEL Expressions +readme: | + Capabilities permit privileged actions without giving full root access. The CAP_NET_RAW capability, enabled by default, allows processes in a container to forge packets and bind to any interface potentially leading to MitM attacks. This policy ensures that all containers explicitly drop the CAP_NET_RAW 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. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Best Practices in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Pod" +digest: a85254bf47f0ec7a3f95139285257228f8f4571f7328ce3652a850d7e901b8c0 +createdAt: "2024-03-15T03:05:47Z" + diff --git a/best-practices-cel/require-drop-cap-net-raw/require-drop-cap-net-raw.yaml b/best-practices-cel/require-drop-cap-net-raw/require-drop-cap-net-raw.yaml new file mode 100644 index 000000000..4b8e23222 --- /dev/null +++ b/best-practices-cel/require-drop-cap-net-raw/require-drop-cap-net-raw.yaml @@ -0,0 +1,43 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: drop-cap-net-raw + annotations: + policies.kyverno.io/title: Drop CAP_NET_RAW in CEL expressions + policies.kyverno.io/category: Best Practices in CEL + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + policies.kyverno.io/description: >- + Capabilities permit privileged actions without giving full root access. The + CAP_NET_RAW capability, enabled by default, allows processes in a container to + forge packets and bind to any interface potentially leading to MitM attacks. + This policy ensures that all containers explicitly drop the CAP_NET_RAW + 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 + background: true + rules: + - name: require-drop-cap-net-raw + match: + any: + - resources: + kinds: + - Pod + 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: >- + 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')) + message: >- + Containers must drop the `CAP_NET_RAW` capability. + diff --git a/best-practices-cel/require-labels/.chainsaw-test/bad-pod-nolabel.yaml b/best-practices-cel/require-labels/.chainsaw-test/bad-pod-nolabel.yaml new file mode 100644 index 000000000..7fbad4d90 --- /dev/null +++ b/best-practices-cel/require-labels/.chainsaw-test/bad-pod-nolabel.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod-nolabel +spec: + containers: + - name: busybox + image: busybox:1.35 + diff --git a/best-practices-cel/require-labels/.chainsaw-test/bad-pod-somelabel.yaml b/best-practices-cel/require-labels/.chainsaw-test/bad-pod-somelabel.yaml new file mode 100644 index 000000000..a59c30368 --- /dev/null +++ b/best-practices-cel/require-labels/.chainsaw-test/bad-pod-somelabel.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod-somelabel + labels: + my.io/foo: bar +spec: + containers: + - name: busybox + image: busybox:1.35 + diff --git a/best-practices-cel/require-labels/.chainsaw-test/bad-podcontrollers.yaml b/best-practices-cel/require-labels/.chainsaw-test/bad-podcontrollers.yaml new file mode 100644 index 000000000..28ac33460 --- /dev/null +++ b/best-practices-cel/require-labels/.chainsaw-test/bad-podcontrollers.yaml @@ -0,0 +1,36 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: reqlabels-baddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + containers: + - name: busybox + image: busybox:1.35 +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: reqlabels-badcronjob01 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + metadata: + labels: + foo: bar + spec: + restartPolicy: OnFailure + containers: + - name: busybox + image: busybox:1.35 + diff --git a/best-practices-cel/require-labels/.chainsaw-test/chainsaw-test.yaml b/best-practices-cel/require-labels/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..736a57ff0 --- /dev/null +++ b/best-practices-cel/require-labels/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,44 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: require-labels +spec: + steps: + - name: step-01 + try: + - apply: + file: ../require-labels.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: require-labels + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: good-pods.yaml + - apply: + file: good-podcontrollers.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-pod-nolabel.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-pod-somelabel.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-podcontrollers.yaml + diff --git a/best-practices-cel/require-labels/.chainsaw-test/good-podcontrollers.yaml b/best-practices-cel/require-labels/.chainsaw-test/good-podcontrollers.yaml new file mode 100644 index 000000000..189506972 --- /dev/null +++ b/best-practices-cel/require-labels/.chainsaw-test/good-podcontrollers.yaml @@ -0,0 +1,39 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: reqlabels-gooddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + foo: bar + app.kubernetes.io/name: bar + template: + metadata: + labels: + foo: bar + app.kubernetes.io/name: bar + spec: + containers: + - name: busybox + image: busybox:1.35 +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: reqlabels-goodcronjob01 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + metadata: + labels: + foo: bar + app.kubernetes.io/name: bar + spec: + restartPolicy: OnFailure + containers: + - name: busybox + image: busybox:1.35 + diff --git a/best-practices-cel/require-labels/.chainsaw-test/good-pods.yaml b/best-practices-cel/require-labels/.chainsaw-test/good-pods.yaml new file mode 100644 index 000000000..a9d4d01d1 --- /dev/null +++ b/best-practices-cel/require-labels/.chainsaw-test/good-pods.yaml @@ -0,0 +1,23 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01-label + labels: + app.kubernetes.io/name: busybox +spec: + containers: + - name: busybox + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod02-label + labels: + foo: bar + app.kubernetes.io/name: busybox +spec: + containers: + - name: busybox + image: busybox:1.35 + diff --git a/best-practices-cel/require-labels/.chainsaw-test/policy-ready.yaml b/best-practices-cel/require-labels/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..90301b18d --- /dev/null +++ b/best-practices-cel/require-labels/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: require-labels +status: + ready: true + diff --git a/best-practices-cel/require-labels/.kyverno-test/kyverno-test.yaml b/best-practices-cel/require-labels/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..a04b287cc --- /dev/null +++ b/best-practices-cel/require-labels/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,24 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: require-labels +policies: +- ../require-labels.yaml +resources: +- resource.yaml +results: +- kind: Pod + policy: require-labels + resources: + - badpod01 + - badpod02 + result: fail + rule: check-for-labels +- kind: Pod + policy: require-labels + resources: + - goodpod01 + - goodpod02 + result: pass + rule: check-for-labels + diff --git a/best-practices-cel/require-labels/.kyverno-test/resource.yaml b/best-practices-cel/require-labels/.kyverno-test/resource.yaml new file mode 100644 index 000000000..95d5b6250 --- /dev/null +++ b/best-practices-cel/require-labels/.kyverno-test/resource.yaml @@ -0,0 +1,43 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 +spec: + containers: + - name: nginx + image: nginx:1.12 +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod02 + labels: + my.io/foo: bar +spec: + containers: + - name: nginx + image: nginx:1.12 +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 + labels: + app.kubernetes.io/name: nginx +spec: + containers: + - name: nginx + image: nginx:1.12 +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod02 + labels: + foo: bar + app.kubernetes.io/name: nginx +spec: + containers: + - name: nginx + image: nginx:1.12 + diff --git a/best-practices-cel/require-labels/artifacthub-pkg.yml b/best-practices-cel/require-labels/artifacthub-pkg.yml new file mode 100644 index 000000000..4ec582c4a --- /dev/null +++ b/best-practices-cel/require-labels/artifacthub-pkg.yml @@ -0,0 +1,24 @@ +name: require-labels-cel +version: 1.0.0 +displayName: Require Labels in CEL expressions +description: >- + Define and use labels that identify semantic attributes of your application or Deployment. A common set of labels allows tools to work collaboratively, describing objects in a common manner that 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. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/best-practices-cel/require-labels/require-labels.yaml + ``` +keywords: + - kyverno + - Best Practices + - CEL Expressions +readme: | + Define and use labels that identify semantic attributes of your application or Deployment. A common set of labels allows tools to work collaboratively, describing objects in a common manner that 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. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Best Practices in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Pod, Label" +digest: 8d6468a51c9a06d26d61874840ff5d0dbda8fe1b4afc9674dcb823a6df0965f7 +createdAt: "2024-03-06T19:31:45Z" + diff --git a/best-practices-cel/require-labels/require-labels.yaml b/best-practices-cel/require-labels/require-labels.yaml new file mode 100644 index 000000000..f4321ca2a --- /dev/null +++ b/best-practices-cel/require-labels/require-labels.yaml @@ -0,0 +1,34 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: require-labels + annotations: + policies.kyverno.io/title: Require Labels in CEL expressions + policies.kyverno.io/category: Best Practices in CEL + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod, Label + policies.kyverno.io/description: >- + Define and use labels that identify semantic attributes of your application or Deployment. + A common set of labels allows tools to work collaboratively, describing objects in a common manner that + 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 + background: true + rules: + - name: check-for-labels + match: + any: + - resources: + kinds: + - Pod + validate: + cel: + expressions: + - expression: >- + has(object.metadata.labels) && + 'app.kubernetes.io/name' in object.metadata.labels && object.metadata.labels['app.kubernetes.io/name'] != "" + message: "The label `app.kubernetes.io/name` is required." + diff --git a/best-practices-cel/require-pod-requests-limits/.chainsaw-test/bad-pod-nolimit.yaml b/best-practices-cel/require-pod-requests-limits/.chainsaw-test/bad-pod-nolimit.yaml new file mode 100644 index 000000000..3ec91afb5 --- /dev/null +++ b/best-practices-cel/require-pod-requests-limits/.chainsaw-test/bad-pod-nolimit.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod-nolimit + labels: + app: myapp +spec: + containers: + - name: busybox + image: busybox:1.35 + resources: + requests: + memory: "256Mi" + cpu: "0.5" + diff --git a/best-practices-cel/require-pod-requests-limits/.chainsaw-test/bad-pod-nores.yaml b/best-practices-cel/require-pod-requests-limits/.chainsaw-test/bad-pod-nores.yaml new file mode 100644 index 000000000..15789fbda --- /dev/null +++ b/best-practices-cel/require-pod-requests-limits/.chainsaw-test/bad-pod-nores.yaml @@ -0,0 +1,38 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod-nores + labels: + app: myapp +spec: + containers: + - name: busybox + image: busybox:1.35 + - name: busybox-again + image: busybox:1.35 + resources: + requests: + memory: "256Mi" + cpu: "0.5" + limits: + memory: "256Mi" +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod-nores + labels: + app: myapp +spec: + containers: + - name: busybox + image: busybox:1.35 + resources: + requests: + memory: "256Mi" + cpu: "0.5" + limits: + memory: "256Mi" + - name: busybox-again + image: busybox:1.35 + diff --git a/best-practices-cel/require-pod-requests-limits/.chainsaw-test/bad-pod-nothing.yaml b/best-practices-cel/require-pod-requests-limits/.chainsaw-test/bad-pod-nothing.yaml new file mode 100644 index 000000000..795085c5b --- /dev/null +++ b/best-practices-cel/require-pod-requests-limits/.chainsaw-test/bad-pod-nothing.yaml @@ -0,0 +1,12 @@ + +apiVersion: v1 +kind: Pod +metadata: + name: badpod-nothing + labels: + app: myapp +spec: + containers: + - name: busybox + image: busybox:v1.35 + diff --git a/best-practices-cel/require-pod-requests-limits/.chainsaw-test/bad-podcontrollers.yaml b/best-practices-cel/require-pod-requests-limits/.chainsaw-test/bad-podcontrollers.yaml new file mode 100644 index 000000000..69c12e6dd --- /dev/null +++ b/best-practices-cel/require-pod-requests-limits/.chainsaw-test/bad-podcontrollers.yaml @@ -0,0 +1,49 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: reqpodlimits-baddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + foo: bar + template: + metadata: + labels: + foo: bar + spec: + containers: + - name: busybox + image: busybox + - name: busybox-again + image: busybox + resources: + requests: + memory: "50Mi" + cpu: "100m" + limits: + memory: "100Mi" +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: reqpodlimits-badcronjob01 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + containers: + - name: busybox + image: busybox + - name: busybox-again + image: busybox + resources: + requests: + memory: "50Mi" + cpu: "100m" + limits: + memory: "100Mi" + diff --git a/best-practices-cel/require-pod-requests-limits/.chainsaw-test/chainsaw-test.yaml b/best-practices-cel/require-pod-requests-limits/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..3341b2924 --- /dev/null +++ b/best-practices-cel/require-pod-requests-limits/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,49 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: require-pod-requests-limits +spec: + steps: + - name: step-01 + try: + - apply: + file: ../require-pod-requests-limits.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: require-requests-limits + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: good-pods.yaml + - apply: + file: good-podcontrollers.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-pod-nolimit.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-pod-nores.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-pod-nothing.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-podcontrollers.yaml + diff --git a/best-practices-cel/require-pod-requests-limits/.chainsaw-test/good-podcontrollers.yaml b/best-practices-cel/require-pod-requests-limits/.chainsaw-test/good-podcontrollers.yaml new file mode 100644 index 000000000..9dc42294a --- /dev/null +++ b/best-practices-cel/require-pod-requests-limits/.chainsaw-test/good-podcontrollers.yaml @@ -0,0 +1,61 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: reqpodlimits-gooddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + foo: bar + template: + metadata: + labels: + foo: bar + spec: + containers: + - name: busybox + image: busybox + resources: + requests: + memory: "50Mi" + cpu: "100m" + limits: + memory: "100Mi" + - name: busybox-again + image: busybox + resources: + requests: + memory: "50Mi" + cpu: "100m" + limits: + memory: "100Mi" +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: reqpodlimits-goodcronjob01 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + containers: + - name: busybox + image: busybox + resources: + requests: + memory: "50Mi" + cpu: "100m" + limits: + memory: "100Mi" + - name: busybox-again + image: busybox + resources: + requests: + memory: "50Mi" + cpu: "100m" + limits: + memory: "100Mi" + diff --git a/best-practices-cel/require-pod-requests-limits/.chainsaw-test/good-pods.yaml b/best-practices-cel/require-pod-requests-limits/.chainsaw-test/good-pods.yaml new file mode 100644 index 000000000..55a53791e --- /dev/null +++ b/best-practices-cel/require-pod-requests-limits/.chainsaw-test/good-pods.yaml @@ -0,0 +1,42 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 + labels: + app: myapp +spec: + containers: + - name: busybox + image: busybox + resources: + requests: + memory: "50Mi" + cpu: "100m" + limits: + memory: "100Mi" +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod02 + labels: + app: myapp +spec: + containers: + - name: busybox + image: busybox + resources: + requests: + memory: "50Mi" + cpu: "100m" + limits: + memory: "100Mi" + - name: busybox-again + image: busybox + resources: + requests: + memory: "50Mi" + cpu: "100m" + limits: + memory: "100Mi" + diff --git a/best-practices-cel/require-pod-requests-limits/.chainsaw-test/policy-ready.yaml b/best-practices-cel/require-pod-requests-limits/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..b874ffaeb --- /dev/null +++ b/best-practices-cel/require-pod-requests-limits/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: require-requests-limits +status: + ready: true + diff --git a/best-practices-cel/require-pod-requests-limits/.kyverno-test/kyverno-test.yaml b/best-practices-cel/require-pod-requests-limits/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..657d5d5cc --- /dev/null +++ b/best-practices-cel/require-pod-requests-limits/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,25 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: require-requests-limits +policies: +- ../require-pod-requests-limits.yaml +resources: +- resource.yaml +results: +- kind: Pod + policy: require-requests-limits + resources: + - badpod01 + - badpod02 + - badpod03 + result: fail + rule: validate-resources +- kind: Pod + policy: require-requests-limits + resources: + - goodpod01 + - goodpod02 + result: pass + rule: validate-resources + diff --git a/best-practices-cel/require-pod-requests-limits/.kyverno-test/resource.yaml b/best-practices-cel/require-pod-requests-limits/.kyverno-test/resource.yaml new file mode 100644 index 000000000..73962a2dc --- /dev/null +++ b/best-practices-cel/require-pod-requests-limits/.kyverno-test/resource.yaml @@ -0,0 +1,87 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 + labels: + app: myapp +spec: + containers: + - name: nginx + image: nginx + resources: + requests: + memory: "256Mi" + cpu: "0.5" + limits: + memory: "256Mi" +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod02 + labels: + app: myapp +spec: + containers: + - name: busybox + image: busybox + resources: + requests: + memory: "50Mi" + cpu: "100m" + limits: + memory: "100Mi" + - name: nginx + image: nginx + resources: + requests: + memory: "256Mi" + cpu: "0.5" + limits: + memory: "256Mi" +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 + labels: + app: myapp +spec: + containers: + - name: nginx + image: nginx +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod02 + labels: + app: myapp +spec: + containers: + - name: nginx + image: nginx + resources: + requests: + memory: "256Mi" + cpu: "0.5" +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod03 + labels: + app: myapp +spec: + containers: + - name: busybox + image: busybox + - name: nginx + image: nginx + resources: + requests: + memory: "256Mi" + cpu: "0.5" + limits: + memory: "256Mi" + diff --git a/best-practices-cel/require-pod-requests-limits/artifacthub-pkg.yml b/best-practices-cel/require-pod-requests-limits/artifacthub-pkg.yml new file mode 100644 index 000000000..24e1e8a86 --- /dev/null +++ b/best-practices-cel/require-pod-requests-limits/artifacthub-pkg.yml @@ -0,0 +1,25 @@ +name: require-pod-requests-limits-cel +version: 1.0.0 +displayName: Require Limits and Requests in CEL expressions +description: >- + As application workloads share cluster resources, it is important to limit resources requested and consumed by each Pod. It is recommended to require resource requests and limits per Pod, especially for memory and CPU. If a Namespace level request or limit is specified, defaults will automatically be applied to each Pod based on the LimitRange configuration. This policy validates that all containers have something specified for memory and CPU requests and memory limits. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/best-practices-cel/require-pod-requests-limits/require-pod-requests-limits.yaml + ``` +keywords: + - kyverno + - Best Practices + - EKS Best Practices + - CEL Expressions +readme: | + As application workloads share cluster resources, it is important to limit resources requested and consumed by each Pod. It is recommended to require resource requests and limits per Pod, especially for memory and CPU. If a Namespace level request or limit is specified, defaults will automatically be applied to each Pod based on the LimitRange configuration. This policy validates that all containers have something specified for memory and CPU requests and memory limits. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Best Practices, EKS Best Practices in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Pod" +digest: 9ffe67ea0a581f0373ab2dda4a48f4a3e589301c4a51a1e058494016d1f4228b +createdAt: "2024-03-15T03:34:10Z" + diff --git a/best-practices-cel/require-pod-requests-limits/require-pod-requests-limits.yaml b/best-practices-cel/require-pod-requests-limits/require-pod-requests-limits.yaml new file mode 100644 index 000000000..1c241e150 --- /dev/null +++ b/best-practices-cel/require-pod-requests-limits/require-pod-requests-limits.yaml @@ -0,0 +1,41 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: require-requests-limits + annotations: + policies.kyverno.io/title: Require Limits and Requests in CEL expressions + policies.kyverno.io/category: Best Practices, EKS Best Practices 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: >- + As application workloads share cluster resources, it is important to limit resources + requested and consumed by each Pod. It is recommended to require resource requests and + limits per Pod, especially for memory and CPU. If a Namespace level request or limit is specified, + defaults will automatically be applied to each Pod based on the LimitRange configuration. + This policy validates that all containers have something specified for memory and CPU + requests and memory limits. +spec: + validationFailureAction: Audit + background: true + rules: + - name: validate-resources + match: + any: + - resources: + kinds: + - Pod + validate: + cel: + expressions: + - expression: >- + object.spec.containers.all(container, + has(container.resources) && + has(container.resources.requests) && + has(container.resources.requests.memory) && + has(container.resources.requests.cpu) && + has(container.resources.limits) && + has(container.resources.limits.memory)) + message: "CPU and memory resource requests and limits are required." + diff --git a/best-practices-cel/require-probes/.chainsaw-test/bad-pod-notall.yaml b/best-practices-cel/require-probes/.chainsaw-test/bad-pod-notall.yaml new file mode 100644 index 000000000..ef8c7b298 --- /dev/null +++ b/best-practices-cel/require-probes/.chainsaw-test/bad-pod-notall.yaml @@ -0,0 +1,38 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod02 + labels: + app: myapp +spec: + containers: + - name: busybox + image: busybox:1.35 + ports: + - containerPort: 8080 + readinessProbe: + tcpSocket: + port: 8080 + periodSeconds: 10 + - name: busybox-again + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod03 + labels: + app: myapp +spec: + containers: + - name: busybox + image: busybox:1.35 + - name: busybox-again + image: busybox:1.35 + ports: + - containerPort: 8080 + readinessProbe: + tcpSocket: + port: 8080 + periodSeconds: 10 + diff --git a/best-practices/require-probes/.chainsaw-test/bad-pod-update.yaml b/best-practices-cel/require-probes/.chainsaw-test/bad-pod-nothing.yaml similarity index 57% rename from best-practices/require-probes/.chainsaw-test/bad-pod-update.yaml rename to best-practices-cel/require-probes/.chainsaw-test/bad-pod-nothing.yaml index 3e46d32cc..6e820cce1 100644 --- a/best-practices/require-probes/.chainsaw-test/bad-pod-update.yaml +++ b/best-practices-cel/require-probes/.chainsaw-test/bad-pod-nothing.yaml @@ -1,10 +1,11 @@ apiVersion: v1 kind: Pod metadata: - name: goodpod01 + name: badpod01 labels: app: myapp spec: containers: - - name: evil-box - image: busybox:1.35 \ No newline at end of file + - name: busybox + image: busybox:1.35 + diff --git a/best-practices-cel/require-probes/.chainsaw-test/bad-podcontrollers.yaml b/best-practices-cel/require-probes/.chainsaw-test/bad-podcontrollers.yaml new file mode 100644 index 000000000..8735991ba --- /dev/null +++ b/best-practices-cel/require-probes/.chainsaw-test/bad-podcontrollers.yaml @@ -0,0 +1,24 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: reqprobes-baddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + foo: bar + template: + metadata: + labels: + foo: bar + spec: + containers: + - name: busybox + image: busybox:1.35 + livenessProbe: + tcpSocket: + port: 7070 + periodSeconds: 20 + - name: busybox-again + image: busybox:1.35 + diff --git a/best-practices-cel/require-probes/.chainsaw-test/chainsaw-test.yaml b/best-practices-cel/require-probes/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..7a5fba016 --- /dev/null +++ b/best-practices-cel/require-probes/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,44 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: require-probes +spec: + steps: + - name: step-01 + try: + - apply: + file: ../require-probes.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: require-pod-probes + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: good-pods.yaml + - apply: + file: good-podcontrollers.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-pod-nothing.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-pod-notall.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-podcontrollers.yaml + diff --git a/best-practices-cel/require-probes/.chainsaw-test/good-podcontrollers.yaml b/best-practices-cel/require-probes/.chainsaw-test/good-podcontrollers.yaml new file mode 100644 index 000000000..dc19a7f29 --- /dev/null +++ b/best-practices-cel/require-probes/.chainsaw-test/good-podcontrollers.yaml @@ -0,0 +1,28 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: reqprobes-gooddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + foo: bar + template: + metadata: + labels: + foo: bar + spec: + containers: + - name: busybox + image: busybox:1.35 + livenessProbe: + tcpSocket: + port: 7070 + periodSeconds: 20 + - name: busybox-again + image: busybox:1.35 + readinessProbe: + tcpSocket: + port: 8080 + periodSeconds: 10 + diff --git a/best-practices-cel/require-probes/.chainsaw-test/good-pods.yaml b/best-practices-cel/require-probes/.chainsaw-test/good-pods.yaml new file mode 100644 index 000000000..128a793af --- /dev/null +++ b/best-practices-cel/require-probes/.chainsaw-test/good-pods.yaml @@ -0,0 +1,50 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 + labels: + app: myapp +spec: + containers: + - name: busybox + image: busybox:1.35 + livenessProbe: + tcpSocket: + port: 7070 + periodSeconds: 20 +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod02 + labels: + app: myapp +spec: + containers: + - name: busybox + image: busybox:1.35 + livenessProbe: + tcpSocket: + port: 7070 + periodSeconds: 20 + - name: busybox-again + image: busybox:1.35 + readinessProbe: + tcpSocket: + port: 8080 + periodSeconds: 10 +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod03 + labels: + app: myapp +spec: + containers: + - name: busybox + image: busybox:1.35 + startupProbe: + grpc: + port: 8888 + diff --git a/best-practices-cel/require-probes/.chainsaw-test/policy-ready.yaml b/best-practices-cel/require-probes/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..7087bf19f --- /dev/null +++ b/best-practices-cel/require-probes/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: require-pod-probes +status: + ready: true + diff --git a/best-practices-cel/require-probes/.kyverno-test/kyverno-test.yaml b/best-practices-cel/require-probes/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..3a8978421 --- /dev/null +++ b/best-practices-cel/require-probes/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,26 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: require-pod-probes +policies: +- ../require-probes.yaml +resources: +- resource.yaml +results: +- kind: Pod + policy: require-pod-probes + resources: + - badpod01 + - badpod02 + result: fail + rule: validate-probes +- kind: Pod + policy: require-pod-probes + resources: + - goodpod01 + - goodpod02 + - goodpod03 + - goodpod04 + result: pass + rule: validate-probes + diff --git a/best-practices-cel/require-probes/.kyverno-test/resource.yaml b/best-practices-cel/require-probes/.kyverno-test/resource.yaml new file mode 100644 index 000000000..0c742c9e4 --- /dev/null +++ b/best-practices-cel/require-probes/.kyverno-test/resource.yaml @@ -0,0 +1,111 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 + labels: + app: myapp +spec: + containers: + - name: goproxy + image: registry.k8s.io/goproxy:0.1 + readinessProbe: + tcpSocket: + port: 8080 + periodSeconds: 10 + livenessProbe: + tcpSocket: + port: 7070 + periodSeconds: 20 +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod02 + labels: + app: myapp +spec: + containers: + - name: goproxy + image: registry.k8s.io/goproxy:0.1 + readinessProbe: + tcpSocket: + port: 8080 + periodSeconds: 10 + livenessProbe: + tcpSocket: + port: 7070 + periodSeconds: 20 + - name: busybox + image: busybox + readinessProbe: + tcpSocket: + port: 8080 + periodSeconds: 10 + livenessProbe: + tcpSocket: + port: 7070 + periodSeconds: 20 +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod03 + labels: + app: myapp +spec: + containers: + - name: goproxy + image: registry.k8s.io/goproxy:0.1 + ports: + - containerPort: 8080 + readinessProbe: + tcpSocket: + port: 8080 + periodSeconds: 10 +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod04 + labels: + app: myapp +spec: + containers: + - name: goproxy + image: asfadsasfasdf:0.1 + startupProbe: + grpc: + port: 8888 +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 + labels: + app: myapp +spec: + containers: + - name: goproxy + image: registry.k8s.io/goproxy:0.1 + ports: + - containerPort: 8080 +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod02 + labels: + app: myapp +spec: + containers: + - name: goproxy + image: registry.k8s.io/goproxy:0.1 + ports: + - containerPort: 8080 + readinessProbe: + tcpSocket: + port: 8080 + periodSeconds: 10 + - name: nginx + image: nginx:latest + diff --git a/best-practices-cel/require-probes/artifacthub-pkg.yml b/best-practices-cel/require-probes/artifacthub-pkg.yml new file mode 100644 index 000000000..a0281a1bb --- /dev/null +++ b/best-practices-cel/require-probes/artifacthub-pkg.yml @@ -0,0 +1,25 @@ +name: require-probes-cel +version: 1.0.0 +displayName: Require Pod Probes in CEL expressions +description: >- + Liveness and readiness probes need to be configured to correctly manage a Pod's lifecycle during deployments, restarts, and upgrades. For each Pod, a periodic `livenessProbe` is performed by the kubelet to determine if the Pod's containers are running or need to be restarted. A `readinessProbe` is used by Services and Deployments to determine if the Pod is ready to receive network traffic. This policy validates that all containers have one of livenessProbe, readinessProbe, or startupProbe defined. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/best-practices-cel/require-probes/require-probes.yaml + ``` +keywords: + - kyverno + - Best Practices + - EKS Best Practices + - CEL Expressions +readme: | + Liveness and readiness probes need to be configured to correctly manage a Pod's lifecycle during deployments, restarts, and upgrades. For each Pod, a periodic `livenessProbe` is performed by the kubelet to determine if the Pod's containers are running or need to be restarted. A `readinessProbe` is used by Services and Deployments to determine if the Pod is ready to receive network traffic. This policy validates that all containers have one of livenessProbe, readinessProbe, or startupProbe defined. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Best Practices, EKS Best Practices in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Pod" +digest: bef0d9498ddf0d62aa5fe8671726b4f79cb6c53c7657e48b6fa5a21ded00fefe +createdAt: "2024-03-10T14:28:37Z" + diff --git a/best-practices-cel/require-probes/require-probes.yaml b/best-practices-cel/require-probes/require-probes.yaml new file mode 100644 index 000000000..b39c9d16d --- /dev/null +++ b/best-practices-cel/require-probes/require-probes.yaml @@ -0,0 +1,40 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: require-pod-probes + annotations: + pod-policies.kyverno.io/autogen-controllers: DaemonSet,Deployment,StatefulSet + policies.kyverno.io/title: Require Pod Probes in CEL expressions + policies.kyverno.io/category: Best Practices, EKS Best Practices in CEL + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + policies.kyverno.io/description: >- + Liveness and readiness probes need to be configured to correctly manage a Pod's + lifecycle during deployments, restarts, and upgrades. For each Pod, a periodic + `livenessProbe` is performed by the kubelet to determine if the Pod's containers + are running or need to be restarted. A `readinessProbe` is used by Services + and Deployments to determine if the Pod is ready to receive network traffic. + This policy validates that all containers have one of livenessProbe, readinessProbe, + or startupProbe defined. +spec: + validationFailureAction: Audit + background: true + rules: + - name: validate-probes + match: + any: + - resources: + kinds: + - Pod + validate: + cel: + expressions: + - expression: >- + object.spec.containers.all(container, + has(container.livenessProbe) || + has(container.startupProbe) || + has(container.readinessProbe)) + message: "Liveness, readiness, or startup probes are required for all containers." + diff --git a/best-practices-cel/require-ro-rootfs/.chainsaw-test/bad-pod-false.yaml b/best-practices-cel/require-ro-rootfs/.chainsaw-test/bad-pod-false.yaml new file mode 100644 index 000000000..2893d42cb --- /dev/null +++ b/best-practices-cel/require-ro-rootfs/.chainsaw-test/bad-pod-false.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 +spec: + containers: + - name: busybox + image: busybox:1.35 + securityContext: + readOnlyRootFilesystem: false + diff --git a/best-practices-cel/require-ro-rootfs/.chainsaw-test/bad-pod-notall.yaml b/best-practices-cel/require-ro-rootfs/.chainsaw-test/bad-pod-notall.yaml new file mode 100644 index 000000000..ae5f1e2b3 --- /dev/null +++ b/best-practices-cel/require-ro-rootfs/.chainsaw-test/bad-pod-notall.yaml @@ -0,0 +1,26 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod-roroot +spec: + containers: + - name: busybox + image: busybox:1.35 + - name: busybox-again + image: busybox:1.35 + securityContext: + readOnlyRootFilesystem: true +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod-roroot +spec: + containers: + - name: busybox + image: busybox:1.35 + securityContext: + readOnlyRootFilesystem: true + - name: busybox-again + image: busybox:1.35 + diff --git a/best-practices-cel/require-ro-rootfs/.chainsaw-test/bad-pod-nothing.yaml b/best-practices-cel/require-ro-rootfs/.chainsaw-test/bad-pod-nothing.yaml new file mode 100644 index 000000000..d37b2c900 --- /dev/null +++ b/best-practices-cel/require-ro-rootfs/.chainsaw-test/bad-pod-nothing.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod02-roroot +spec: + containers: + - name: busybox + image: busybox:1.35 + diff --git a/best-practices-cel/require-ro-rootfs/.chainsaw-test/bad-podcontrollers.yaml b/best-practices-cel/require-ro-rootfs/.chainsaw-test/bad-podcontrollers.yaml new file mode 100644 index 000000000..6fb05b66e --- /dev/null +++ b/best-practices-cel/require-ro-rootfs/.chainsaw-test/bad-podcontrollers.yaml @@ -0,0 +1,41 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: reqro-baddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + containers: + - name: busybox + image: busybox:1.35 + - name: busybox-again + image: busybox:1.35 + securityContext: + readOnlyRootFilesystem: true +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: reqro-badcronjob01 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + containers: + - name: busybox + image: busybox:1.35 + - name: busybox-again + image: busybox:1.35 + securityContext: + readOnlyRootFilesystem: true + diff --git a/best-practices-cel/require-ro-rootfs/.chainsaw-test/chainsaw-test.yaml b/best-practices-cel/require-ro-rootfs/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..9857eaa9b --- /dev/null +++ b/best-practices-cel/require-ro-rootfs/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,49 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: require-ro-rootfs +spec: + steps: + - name: step-01 + try: + - apply: + file: ../require-ro-rootfs.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: require-ro-rootfs + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: good-pods.yaml + - apply: + file: good-podcontrollers.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-pod-nothing.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-pod-notall.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-pod-false.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-podcontrollers.yaml + diff --git a/best-practices-cel/require-ro-rootfs/.chainsaw-test/good-podcontrollers.yaml b/best-practices-cel/require-ro-rootfs/.chainsaw-test/good-podcontrollers.yaml new file mode 100644 index 000000000..4362709c5 --- /dev/null +++ b/best-practices-cel/require-ro-rootfs/.chainsaw-test/good-podcontrollers.yaml @@ -0,0 +1,45 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: reqro-gooddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + foo: bar + template: + metadata: + labels: + foo: bar + spec: + containers: + - name: busybox + image: busybox:1.35 + securityContext: + readOnlyRootFilesystem: true + - name: busybox-again + image: busybox:1.35 + securityContext: + readOnlyRootFilesystem: true +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: reqprobes-goodcronjob01 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + containers: + - name: busybox + image: busybox:1.35 + securityContext: + readOnlyRootFilesystem: true + - name: busybox-again + image: busybox:1.35 + securityContext: + readOnlyRootFilesystem: true + diff --git a/best-practices-cel/require-ro-rootfs/.chainsaw-test/good-pods.yaml b/best-practices-cel/require-ro-rootfs/.chainsaw-test/good-pods.yaml new file mode 100644 index 000000000..f5d4e8831 --- /dev/null +++ b/best-practices-cel/require-ro-rootfs/.chainsaw-test/good-pods.yaml @@ -0,0 +1,26 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01-roroot +spec: + containers: + - name: busybox + image: busybox:1.35 + securityContext: + readOnlyRootFilesystem: true +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod02-roroot +spec: + containers: + - name: busybox + image: busybox:1.35 + securityContext: + readOnlyRootFilesystem: true + - name: busybox-again + image: busybox:1.35 + securityContext: + readOnlyRootFilesystem: true + diff --git a/best-practices-cel/require-ro-rootfs/.chainsaw-test/policy-ready.yaml b/best-practices-cel/require-ro-rootfs/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..c1fea112c --- /dev/null +++ b/best-practices-cel/require-ro-rootfs/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: require-ro-rootfs +status: + ready: true + diff --git a/best-practices-cel/require-ro-rootfs/.kyverno-test/kyverno-test.yaml b/best-practices-cel/require-ro-rootfs/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..0534a97e0 --- /dev/null +++ b/best-practices-cel/require-ro-rootfs/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,25 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: require-ro-rootfs +policies: +- ../require-ro-rootfs.yaml +resources: +- resource.yaml +results: +- kind: Pod + policy: require-ro-rootfs + resources: + - badpod01 + - badpod02 + - badpod03 + result: fail + rule: validate-readOnlyRootFilesystem +- kind: Pod + policy: require-ro-rootfs + resources: + - goodpod01 + - goodpod02 + result: pass + rule: validate-readOnlyRootFilesystem + diff --git a/best-practices-cel/require-ro-rootfs/.kyverno-test/resource.yaml b/best-practices-cel/require-ro-rootfs/.kyverno-test/resource.yaml new file mode 100644 index 000000000..f55bd12bc --- /dev/null +++ b/best-practices-cel/require-ro-rootfs/.kyverno-test/resource.yaml @@ -0,0 +1,59 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 +spec: + containers: + - name: ghost + image: ghost + securityContext: + readOnlyRootFilesystem: false +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod02 +spec: + containers: + - name: ghost + image: ghost +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod03 +spec: + containers: + - name: ghost + image: ghost + - name: busybox + image: busybox + securityContext: + readOnlyRootFilesystem: true +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 +spec: + containers: + - name: ghost + image: ghost + securityContext: + readOnlyRootFilesystem: true +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod02 +spec: + containers: + - name: ghost + image: ghost + securityContext: + readOnlyRootFilesystem: true + - name: nginx + image: nginx + securityContext: + readOnlyRootFilesystem: true + diff --git a/best-practices-cel/require-ro-rootfs/artifacthub-pkg.yml b/best-practices-cel/require-ro-rootfs/artifacthub-pkg.yml new file mode 100644 index 000000000..f99c882ce --- /dev/null +++ b/best-practices-cel/require-ro-rootfs/artifacthub-pkg.yml @@ -0,0 +1,25 @@ +name: require-ro-rootfs-cel +version: 1.0.0 +displayName: Require Read-Only Root Filesystem in CEL expressions +description: >- + A read-only root file system helps to enforce an immutable infrastructure strategy; the container only needs to write on the mounted volume that persists the state. An immutable root filesystem can also prevent malicious binaries from writing to the host system. This policy validates that containers define a securityContext with `readOnlyRootFilesystem: true`. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/best-practices-cel/require-ro-rootfs/require-ro-rootfs.yaml + ``` +keywords: + - kyverno + - Best Practices + - EKS Best Practices + - CEL Expressions +readme: | + A read-only root file system helps to enforce an immutable infrastructure strategy; the container only needs to write on the mounted volume that persists the state. An immutable root filesystem can also prevent malicious binaries from writing to the host system. This policy validates that containers define a securityContext with `readOnlyRootFilesystem: true`. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Best Practices, EKS Best Practices in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Pod" +digest: 3e33d8d031a0cf31168bd04a0b691520ff01b6dc908554bbc1591700c0e69b0e +createdAt: "2024-03-07T12:35:00Z" + diff --git a/best-practices-cel/require-ro-rootfs/require-ro-rootfs.yaml b/best-practices-cel/require-ro-rootfs/require-ro-rootfs.yaml new file mode 100644 index 000000000..bf56915c4 --- /dev/null +++ b/best-practices-cel/require-ro-rootfs/require-ro-rootfs.yaml @@ -0,0 +1,36 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: require-ro-rootfs + annotations: + policies.kyverno.io/title: Require Read-Only Root Filesystem in CEL expressions + policies.kyverno.io/category: Best Practices, EKS Best Practices, PSP Migration in CEL + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/minversion: 1.11.0 + policies.kyverno.io/description: >- + A read-only root file system helps to enforce an immutable infrastructure strategy; + the container only needs to write on the mounted volume that persists the state. + An immutable root filesystem can also prevent malicious binaries from writing to the + host system. This policy validates that containers define a securityContext + with `readOnlyRootFilesystem: true`. +spec: + validationFailureAction: Audit + background: true + rules: + - name: validate-readOnlyRootFilesystem + match: + any: + - resources: + kinds: + - Pod + validate: + cel: + expressions: + - expression: >- + object.spec.containers.all(container, + has(container.securityContext) && + container.securityContext.readOnlyRootFilesystem == true) + message: "Root filesystem must be read-only." + diff --git a/best-practices-cel/restrict-image-registries/.chainsaw-test/bad-pod-false.yaml b/best-practices-cel/restrict-image-registries/.chainsaw-test/bad-pod-false.yaml new file mode 100644 index 000000000..2876a5024 --- /dev/null +++ b/best-practices-cel/restrict-image-registries/.chainsaw-test/bad-pod-false.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod01-registry +spec: + containers: + - name: k8s-nginx + image: registry.k8s.io/nginx:1.7.9 + diff --git a/best-practices-cel/restrict-image-registries/.chainsaw-test/bad-pod-noregistry.yaml b/best-practices-cel/restrict-image-registries/.chainsaw-test/bad-pod-noregistry.yaml new file mode 100644 index 000000000..c46ebaf5e --- /dev/null +++ b/best-practices-cel/restrict-image-registries/.chainsaw-test/bad-pod-noregistry.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod04-registry +spec: + containers: + - name: k8s-nginx + image: nginx + diff --git a/best-practices-cel/restrict-image-registries/.chainsaw-test/bad-pod-notall.yaml b/best-practices-cel/restrict-image-registries/.chainsaw-test/bad-pod-notall.yaml new file mode 100644 index 000000000..591ee4d47 --- /dev/null +++ b/best-practices-cel/restrict-image-registries/.chainsaw-test/bad-pod-notall.yaml @@ -0,0 +1,22 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod02-registry +spec: + containers: + - name: k8s-nginx + image: registry.k8s.io/nginx:1.7.9 + - name: busybox + image: bar.io/busybox +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod03-registry +spec: + containers: + - name: busybox + image: eu.foo.io/busybox + - name: k8s-nginx + image: registry.k8s.io/nginx:1.7.9 + diff --git a/best-practices-cel/restrict-image-registries/.chainsaw-test/bad-podcontrollers.yaml b/best-practices-cel/restrict-image-registries/.chainsaw-test/bad-podcontrollers.yaml new file mode 100644 index 000000000..b4b56ebd3 --- /dev/null +++ b/best-practices-cel/restrict-image-registries/.chainsaw-test/bad-podcontrollers.yaml @@ -0,0 +1,141 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: reqro-baddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + initContainers: + - name: k8s-nginx-init + image: bar.io/nginx + - name: busybox-init + image: busybox + containers: + - name: busybox + image: busybox:1.35 + - name: k8s-nginx + image: bar.io/nginx +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: reqro-baddeployment02 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + initContainers: + - name: k8s-nginx-init + image: bar.io/nginx + - name: nginx-init + image: eu.foo.io/nginx + containers: + - name: k8s-nginx + image: bar.io/nginx + - name: busybox + image: busybox:1.35 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: reqro-baddeployment03 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + initContainers: + - name: k8s-nginx-init + image: bar.io/nginx + - name: busybox-init + image: busybox:1.35 + containers: + - name: k8s-nginx + image: bar.io/nginx + - name: nginx + image: eu.foo.io/nginx +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: reqro-badcronjob01 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + initContainers: + - name: k8s-nginx-init + image: bar.io/nginx + - name: busybox-init + image: busybox + containers: + - name: busybox + image: busybox:1.35 + - name: k8s-nginx + image: bar.io/nginx +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: reqro-badcronjob02 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + initContainers: + - name: k8s-nginx-init + image: bar.io/nginx + - name: nginx-init + image: eu.foo.io/nginx + containers: + - name: k8s-nginx + image: bar.io/nginx + - name: busybox + image: busybox:1.35 +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: reqro-badcronjob03 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + initContainers: + - name: k8s-nginx-init + image: bar.io/nginx + - name: busybox-init + image: busybox:1.35 + containers: + - name: k8s-nginx + image: bar.io/nginx + - name: nginx + image: eu.foo.io/nginx + diff --git a/best-practices-cel/restrict-image-registries/.chainsaw-test/chainsaw-test.yaml b/best-practices-cel/restrict-image-registries/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..9ee72fa4e --- /dev/null +++ b/best-practices-cel/restrict-image-registries/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,64 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: restrict-image-registries +spec: + # disable templating because it can cause issues with CEL expressions + template: false + steps: + - name: step-01 + try: + - apply: + file: ../restrict-image-registries.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: restrict-image-registries + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: good-pods.yaml + - apply: + file: good-podcontrollers.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-pod-noregistry.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-pod-notall.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-pod-false.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-podcontrollers.yaml + - name: step-03 + try: + - script: + content: if kubectl debug -it goodpod02-registry --image=busybox:1.35 --target=k8s-nginx + -n ir-pods-namespace; then exit 1; else exit 0; fi; + - name: step-98 + try: + - script: + content: kubectl delete deployments --all --force --grace-period=0 -n ir-pods-namespace + - script: + content: kubectl delete pods --all --force --grace-period=0 -n ir-pods-namespace + - script: + content: kubectl delete cronjobs --all --force --grace-period=0 -n ir-pods-namespace + diff --git a/best-practices-cel/restrict-image-registries/.chainsaw-test/good-podcontrollers.yaml b/best-practices-cel/restrict-image-registries/.chainsaw-test/good-podcontrollers.yaml new file mode 100644 index 000000000..48f74daff --- /dev/null +++ b/best-practices-cel/restrict-image-registries/.chainsaw-test/good-podcontrollers.yaml @@ -0,0 +1,49 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: reqro-gooddeployment01 + namespace: ir-pods-namespace +spec: + replicas: 1 + selector: + matchLabels: + foo: bar + template: + metadata: + labels: + foo: bar + spec: + initContainers: + - name: k8s-nginx-init + image: bar.io/nginx + - name: busybox-init + image: eu.foo.io/busybox + containers: + - name: busybox + image: eu.foo.io/nginx + - name: k8s-nginx + image: bar.io/nginx +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: reqprobes-goodcronjob01 + namespace: ir-pods-namespace +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + initContainers: + - name: k8s-nginx-init + image: bar.io/nginx + - name: busybox-init + image: eu.foo.io/busybox + containers: + - name: busybox + image: eu.foo.io/nginx + - name: k8s-nginx + image: bar.io/nginx + diff --git a/best-practices-cel/restrict-image-registries/.chainsaw-test/good-pods.yaml b/best-practices-cel/restrict-image-registries/.chainsaw-test/good-pods.yaml new file mode 100644 index 000000000..d092314d7 --- /dev/null +++ b/best-practices-cel/restrict-image-registries/.chainsaw-test/good-pods.yaml @@ -0,0 +1,35 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: ir-pods-namespace +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01-registry + namespace: ir-pods-namespace +spec: + initContainers: + - name: k8s-nginx-init + image: bar.io/nginx + containers: + - name: k8s-nginx + image: eu.foo.io/nginx +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod02-registry + namespace: ir-pods-namespace +spec: + initContainers: + - name: nginx-init + image: bar.io/nginx + - name: busybox-init + image: eu.foo.io/busybox + containers: + - name: k8s-nginx + image: bar.io/nginx + - name: busybox + image: eu.foo.io/busybox + diff --git a/best-practices-cel/restrict-image-registries/.chainsaw-test/policy-ready.yaml b/best-practices-cel/restrict-image-registries/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..5924c7b49 --- /dev/null +++ b/best-practices-cel/restrict-image-registries/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-image-registries +status: + ready: true + diff --git a/best-practices-cel/restrict-image-registries/.kyverno-test/kyverno-test.yaml b/best-practices-cel/restrict-image-registries/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..11a15e2b4 --- /dev/null +++ b/best-practices-cel/restrict-image-registries/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,27 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: restrict-image-registries +policies: +- ../restrict-image-registries.yaml +resources: +- resource.yaml +results: +- kind: Pod + policy: restrict-image-registries + resources: + - badpod01 + - badpod02 + - badpod03 + - badpod04 + result: fail + rule: validate-registries +- kind: Pod + policy: restrict-image-registries + resources: + - goodpod01 + - goodpod02 + - goodpod03 + result: pass + rule: validate-registries + diff --git a/best-practices-cel/restrict-image-registries/.kyverno-test/resource.yaml b/best-practices-cel/restrict-image-registries/.kyverno-test/resource.yaml new file mode 100644 index 000000000..0f7628233 --- /dev/null +++ b/best-practices-cel/restrict-image-registries/.kyverno-test/resource.yaml @@ -0,0 +1,69 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 +spec: + containers: + - name: k8s-nginx + image: registry.k8s.io/nginx:1.7.9 +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod02 +spec: + containers: + - name: k8s-nginx + image: registry.k8s.io/nginx:1.7.9 + - name: busybox + image: bar.io/busybox +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod03 +spec: + containers: + - name: k8s-nginx + image: registry.k8s.io/nginx:1.7.9 + - name: busybox + image: eu.foo.io/busybox +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod04 +spec: + containers: + - name: k8s-nginx + image: nginx +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 +spec: + containers: + - name: k8s-nginx + image: eu.foo.io/nginx +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod02 +spec: + containers: + - name: k8s-nginx + image: bar.io/nginx +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod03 +spec: + containers: + - name: k8s-nginx + image: bar.io/nginx + - name: busybox + image: eu.foo.io/busybox + diff --git a/best-practices-cel/restrict-image-registries/artifacthub-pkg.yml b/best-practices-cel/restrict-image-registries/artifacthub-pkg.yml new file mode 100644 index 000000000..330273cff --- /dev/null +++ b/best-practices-cel/restrict-image-registries/artifacthub-pkg.yml @@ -0,0 +1,25 @@ +name: restrict-image-registries-cel +version: 1.0.0 +displayName: Restrict Image Registries in CEL expressions +description: >- + Images from unknown, public registries can be of dubious quality and may not be scanned and secured, representing a high degree of risk. Requiring use of known, approved registries helps reduce threat exposure by ensuring image pulls only come from them. This 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. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/best-practices-cel/restrict-image-registries/restrict-image-registries.yaml + ``` +keywords: + - kyverno + - Best Practices + - EKS Best Practices + - CEL Expressions +readme: | + Images from unknown, public registries can be of dubious quality and may not be scanned and secured, representing a high degree of risk. Requiring use of known, approved registries helps reduce threat exposure by ensuring image pulls only come from them. This 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. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Best Practices, EKS Best Practices in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Pod" +digest: 9a431345cee629f64c388e843e39a83ce327d049ac03c02ebad4105abe0c9af5 +createdAt: "2024-03-07T13:35:11Z" + diff --git a/best-practices-cel/restrict-image-registries/restrict-image-registries.yaml b/best-practices-cel/restrict-image-registries/restrict-image-registries.yaml new file mode 100644 index 000000000..5c8bfd43b --- /dev/null +++ b/best-practices-cel/restrict-image-registries/restrict-image-registries.yaml @@ -0,0 +1,36 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-image-registries + annotations: + policies.kyverno.io/title: Restrict Image Registries in CEL expressions + policies.kyverno.io/category: Best Practices, EKS Best Practices in CEL + policies.kyverno.io/severity: medium + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/subject: Pod + policies.kyverno.io/description: >- + Images from unknown, public registries can be of dubious quality and may not be + scanned and secured, representing a high degree of risk. Requiring use of known, approved + registries helps reduce threat exposure by ensuring image pulls only come from them. This + 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 + background: true + rules: + - name: validate-registries + match: + any: + - resources: + kinds: + - Pod + 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: "variables.allContainers.all(container, container.image.startsWith('eu.foo.io/') || container.image.startsWith('bar.io/'))" + message: "Unknown image registry." + diff --git a/best-practices-cel/restrict-node-port/.chainsaw-test/bad-service-nodeport.yaml b/best-practices-cel/restrict-node-port/.chainsaw-test/bad-service-nodeport.yaml new file mode 100644 index 000000000..5ff22f5cf --- /dev/null +++ b/best-practices-cel/restrict-node-port/.chainsaw-test/bad-service-nodeport.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: badservice01-np +spec: + ports: + - name: http + nodePort: 31080 + port: 80 + protocol: TCP + targetPort: 8080 + type: NodePort + diff --git a/best-practices-cel/restrict-node-port/.chainsaw-test/chainsaw-test.yaml b/best-practices-cel/restrict-node-port/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..f0487517f --- /dev/null +++ b/best-practices-cel/restrict-node-port/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,32 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: restrict-node-port +spec: + steps: + - name: step-01 + try: + - apply: + file: ../restrict-node-port.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: restrict-nodeport + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: good-services.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-service-nodeport.yaml + diff --git a/best-practices-cel/restrict-node-port/.chainsaw-test/good-services.yaml b/best-practices-cel/restrict-node-port/.chainsaw-test/good-services.yaml new file mode 100644 index 000000000..8e1fa3e98 --- /dev/null +++ b/best-practices-cel/restrict-node-port/.chainsaw-test/good-services.yaml @@ -0,0 +1,25 @@ +apiVersion: v1 +kind: Service +metadata: + name: goodservice01-np +spec: + ports: + - name: http + port: 80 + protocol: TCP + targetPort: 8080 + type: ClusterIP +--- +apiVersion: v1 +kind: Service +metadata: + name: goodservice02-np +spec: + selector: + app: MyApp + ports: + - protocol: TCP + port: 80 + targetPort: 9376 + type: LoadBalancer + diff --git a/best-practices-cel/restrict-node-port/.chainsaw-test/policy-ready.yaml b/best-practices-cel/restrict-node-port/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..71a3f4715 --- /dev/null +++ b/best-practices-cel/restrict-node-port/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-nodeport +status: + ready: true + diff --git a/best-practices-cel/restrict-node-port/.kyverno-test/kyverno-test.yaml b/best-practices-cel/restrict-node-port/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..964ef12f5 --- /dev/null +++ b/best-practices-cel/restrict-node-port/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,23 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: restrict-node-port +policies: +- ../restrict-node-port.yaml +resources: +- resource.yaml +results: +- kind: Service + policy: restrict-nodeport + resources: + - badservice01 + result: fail + rule: validate-nodeport +- kind: Service + policy: restrict-nodeport + resources: + - goodservice01 + - goodservice02 + result: pass + rule: validate-nodeport + diff --git a/best-practices-cel/restrict-node-port/.kyverno-test/resource.yaml b/best-practices-cel/restrict-node-port/.kyverno-test/resource.yaml new file mode 100644 index 000000000..5100a8514 --- /dev/null +++ b/best-practices-cel/restrict-node-port/.kyverno-test/resource.yaml @@ -0,0 +1,39 @@ +apiVersion: v1 +kind: Service +metadata: + name: badservice01 +spec: + ports: + - name: http + nodePort: 31080 + port: 80 + protocol: TCP + targetPort: 8080 + type: NodePort +--- +apiVersion: v1 +kind: Service +metadata: + name: goodservice01 +spec: + ports: + - name: http + nodePort: 31080 + port: 80 + protocol: TCP + targetPort: 8080 + type: ClusterIP +--- +apiVersion: v1 +kind: Service +metadata: + name: goodservice02 +spec: + selector: + app: MyApp + ports: + - protocol: TCP + port: 80 + targetPort: 9376 + type: LoadBalancer + diff --git a/best-practices-cel/restrict-node-port/artifacthub-pkg.yml b/best-practices-cel/restrict-node-port/artifacthub-pkg.yml new file mode 100644 index 000000000..dbe33e351 --- /dev/null +++ b/best-practices-cel/restrict-node-port/artifacthub-pkg.yml @@ -0,0 +1,24 @@ +name: restrict-node-port-cel +version: 1.0.0 +displayName: Disallow NodePort in CEL expressions +description: >- + A Kubernetes Service of type NodePort uses a host port to receive traffic from any source. A NetworkPolicy cannot be used to control traffic to host ports. Although NodePort Services can be useful, their use must be limited to Services with additional upstream security checks. This policy validates that any new Services do not use the `NodePort` type. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/best-practices-cel/restrict-node-port/restrict-node-port.yaml + ``` +keywords: + - kyverno + - Best Practices + - CEL Expressions +readme: | + A Kubernetes Service of type NodePort uses a host port to receive traffic from any source. A NetworkPolicy cannot be used to control traffic to host ports. Although NodePort Services can be useful, their use must be limited to Services with additional upstream security checks. This policy validates that any new Services do not use the `NodePort` type. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Best Practices in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Service" +digest: 5cee0523689e20cc0e5adccc2cf76d725c7f8df2213e7dfdede1fb768fa9a2b9 +createdAt: "2024-03-06T14:04:34Z" + diff --git a/best-practices-cel/restrict-node-port/restrict-node-port.yaml b/best-practices-cel/restrict-node-port/restrict-node-port.yaml new file mode 100644 index 000000000..4a28d2a1b --- /dev/null +++ b/best-practices-cel/restrict-node-port/restrict-node-port.yaml @@ -0,0 +1,33 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-nodeport + annotations: + policies.kyverno.io/title: Disallow NodePort in CEL expressions + policies.kyverno.io/category: Best Practices in CEL + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Service + policies.kyverno.io/description: >- + A Kubernetes Service of type NodePort uses a host port to receive traffic from + any source. A NetworkPolicy cannot be used to control traffic to host ports. + Although NodePort Services can be useful, their use must be limited to Services + with additional upstream security checks. This policy validates that any new Services + do not use the `NodePort` type. +spec: + validationFailureAction: Audit + background: true + rules: + - name: validate-nodeport + match: + any: + - resources: + kinds: + - Service + validate: + cel: + expressions: + - expression: "has(object.spec.type) ? (object.spec.type != 'NodePort') : true" + message: "Services of type NodePort are not allowed." + diff --git a/best-practices-cel/restrict-service-external-ips/.chainsaw-test/bad-service-oneip.yaml b/best-practices-cel/restrict-service-external-ips/.chainsaw-test/bad-service-oneip.yaml new file mode 100644 index 000000000..16dab36c1 --- /dev/null +++ b/best-practices-cel/restrict-service-external-ips/.chainsaw-test/bad-service-oneip.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: badservice01-eip +spec: + selector: + app: MyApp + ports: + - protocol: TCP + port: 80 + targetPort: 9376 + externalIPs: + - 1.2.3.4 + diff --git a/best-practices-cel/restrict-service-external-ips/.chainsaw-test/bad-service-twoeip.yaml b/best-practices-cel/restrict-service-external-ips/.chainsaw-test/bad-service-twoeip.yaml new file mode 100644 index 000000000..c448876c0 --- /dev/null +++ b/best-practices-cel/restrict-service-external-ips/.chainsaw-test/bad-service-twoeip.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: badservice02-eip +spec: + selector: + app: MyApp + ports: + - protocol: TCP + port: 80 + targetPort: 9376 + externalIPs: + - 1.2.3.4 + - 37.10.11.53 + diff --git a/best-practices-cel/restrict-service-external-ips/.chainsaw-test/chainsaw-test.yaml b/best-practices-cel/restrict-service-external-ips/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..add3f7d80 --- /dev/null +++ b/best-practices-cel/restrict-service-external-ips/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,37 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: restrict-service-external-ips +spec: + steps: + - name: step-01 + try: + - apply: + file: ../restrict-service-external-ips.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: restrict-external-ips + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: good-services.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-service-oneip.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-service-twoeip.yaml + diff --git a/best-practices-cel/restrict-service-external-ips/.chainsaw-test/good-services.yaml b/best-practices-cel/restrict-service-external-ips/.chainsaw-test/good-services.yaml new file mode 100644 index 000000000..cdaa47e6e --- /dev/null +++ b/best-practices-cel/restrict-service-external-ips/.chainsaw-test/good-services.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Service +metadata: + name: goodservice01-eip +spec: + selector: + app: MyApp + ports: + - protocol: TCP + port: 80 + targetPort: 9376 + diff --git a/best-practices-cel/restrict-service-external-ips/.chainsaw-test/policy-ready.yaml b/best-practices-cel/restrict-service-external-ips/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..24f285eed --- /dev/null +++ b/best-practices-cel/restrict-service-external-ips/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-external-ips +status: + ready: true + diff --git a/best-practices-cel/restrict-service-external-ips/.kyverno-test/kyverno-test.yaml b/best-practices-cel/restrict-service-external-ips/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..9fa1e0430 --- /dev/null +++ b/best-practices-cel/restrict-service-external-ips/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,23 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: restrict-external-ips +policies: +- ../restrict-service-external-ips.yaml +resources: +- resource.yaml +results: +- kind: Service + policy: restrict-external-ips + resources: + - badservice01 + - badservice02 + result: fail + rule: check-ips +- kind: Service + policy: restrict-external-ips + resources: + - goodservice01 + result: pass + rule: check-ips + diff --git a/best-practices-cel/restrict-service-external-ips/.kyverno-test/resource.yaml b/best-practices-cel/restrict-service-external-ips/.kyverno-test/resource.yaml new file mode 100644 index 000000000..ad3d09a12 --- /dev/null +++ b/best-practices-cel/restrict-service-external-ips/.kyverno-test/resource.yaml @@ -0,0 +1,41 @@ +apiVersion: v1 +kind: Service +metadata: + name: goodservice01 +spec: + selector: + app: MyApp + ports: + - protocol: TCP + port: 80 + targetPort: 9376 +--- +apiVersion: v1 +kind: Service +metadata: + name: badservice01 +spec: + selector: + app: MyApp + ports: + - protocol: TCP + port: 80 + targetPort: 9376 + externalIPs: + - 1.2.3.4 +--- +apiVersion: v1 +kind: Service +metadata: + name: badservice02 +spec: + selector: + app: MyApp + ports: + - protocol: TCP + port: 80 + targetPort: 9376 + externalIPs: + - 1.2.3.4 + - 37.10.11.53 + diff --git a/best-practices-cel/restrict-service-external-ips/artifacthub-pkg.yml b/best-practices-cel/restrict-service-external-ips/artifacthub-pkg.yml new file mode 100644 index 000000000..2aad9d303 --- /dev/null +++ b/best-practices-cel/restrict-service-external-ips/artifacthub-pkg.yml @@ -0,0 +1,24 @@ +name: restrict-service-external-ips-cel +version: 1.0.0 +displayName: Restrict External IPs in CEL expressions +description: >- + Service externalIPs can be used for a MITM attack (CVE-2020-8554). Restrict externalIPs or limit to a known set of addresses. See: https://github.com/kyverno/kyverno/issues/1367. This policy validates that the `externalIPs` field is not set on a Service. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/best-practices-cel/restrict-service-external-ips/restrict-service-external-ips.yaml + ``` +keywords: + - kyverno + - Best Practices + - CEL Expressions +readme: | + Service externalIPs can be used for a MITM attack (CVE-2020-8554). Restrict externalIPs or limit to a known set of addresses. See: https://github.com/kyverno/kyverno/issues/1367. This policy validates that the `externalIPs` field is not set on a Service. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Best Practices in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Service" +digest: d03ee8911a09239eb433b737858c9e7eb99da256ab9114a2268537e235817b3c +createdAt: "2024-03-07T05:48:27Z" + diff --git a/best-practices-cel/restrict-service-external-ips/restrict-service-external-ips.yaml b/best-practices-cel/restrict-service-external-ips/restrict-service-external-ips.yaml new file mode 100644 index 000000000..636ddc996 --- /dev/null +++ b/best-practices-cel/restrict-service-external-ips/restrict-service-external-ips.yaml @@ -0,0 +1,36 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-external-ips + annotations: + policies.kyverno.io/title: Restrict External IPs in CEL expressions + policies.kyverno.io/category: Best Practices in CEL + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Service + policies.kyverno.io/description: >- + Service externalIPs can be used for a MITM attack (CVE-2020-8554). + Restrict externalIPs or limit to a known set of addresses. + See: https://github.com/kyverno/kyverno/issues/1367. This policy validates + that the `externalIPs` field is not set on a Service. +spec: + validationFailureAction: Audit + background: true + rules: + - name: check-ips + match: + any: + - resources: + kinds: + - Service + validate: + cel: + expressions: + - expression: "!has(object.spec.externalIPs)" + # restrict external IP addresses + # you can alternatively restrict to a known set of addresses using: + # !has(object.spec.externalIPs) || + # object.spec.externalIPs.all(ip, ip in ["37.10.11.53", "153.10.20.1"]) + message: "externalIPs are not allowed." + diff --git a/best-practices/disallow-cri-sock-mount/.chainsaw-test/chainsaw-test.yaml b/best-practices/disallow-cri-sock-mount/.chainsaw-test/chainsaw-test.yaml index f15214a40..849553fc4 100755 --- a/best-practices/disallow-cri-sock-mount/.chainsaw-test/chainsaw-test.yaml +++ b/best-practices/disallow-cri-sock-mount/.chainsaw-test/chainsaw-test.yaml @@ -19,7 +19,7 @@ spec: spec: validationFailureAction: Enforce - assert: - file: chainsaw-step-01-assert-1.yaml + file: policy-ready.yaml - name: step-02 try: - apply: diff --git a/best-practices/disallow-cri-sock-mount/.chainsaw-test/chainsaw-step-01-assert-1.yaml b/best-practices/disallow-cri-sock-mount/.chainsaw-test/policy-ready.yaml similarity index 100% rename from best-practices/disallow-cri-sock-mount/.chainsaw-test/chainsaw-step-01-assert-1.yaml rename to best-practices/disallow-cri-sock-mount/.chainsaw-test/policy-ready.yaml diff --git a/best-practices/disallow-default-namespace/.chainsaw-test/chainsaw-test.yaml b/best-practices/disallow-default-namespace/.chainsaw-test/chainsaw-test.yaml index c574dad57..0df2e4cbb 100755 --- a/best-practices/disallow-default-namespace/.chainsaw-test/chainsaw-test.yaml +++ b/best-practices/disallow-default-namespace/.chainsaw-test/chainsaw-test.yaml @@ -19,11 +19,11 @@ spec: spec: validationFailureAction: Enforce - assert: - file: chainsaw-step-01-assert-1.yaml + file: policy-ready.yaml - name: step-02 try: - apply: - file: chainsaw-step-02-apply-1.yaml + file: ns.yaml - name: step-03 try: - apply: diff --git a/best-practices/disallow-default-namespace/.chainsaw-test/chainsaw-step-02-apply-1.yaml b/best-practices/disallow-default-namespace/.chainsaw-test/ns.yaml similarity index 100% rename from best-practices/disallow-default-namespace/.chainsaw-test/chainsaw-step-02-apply-1.yaml rename to best-practices/disallow-default-namespace/.chainsaw-test/ns.yaml diff --git a/best-practices/disallow-default-namespace/.chainsaw-test/chainsaw-step-01-assert-1.yaml b/best-practices/disallow-default-namespace/.chainsaw-test/policy-ready.yaml similarity index 100% rename from best-practices/disallow-default-namespace/.chainsaw-test/chainsaw-step-01-assert-1.yaml rename to best-practices/disallow-default-namespace/.chainsaw-test/policy-ready.yaml diff --git a/best-practices/disallow-empty-ingress-host/.chainsaw-test/chainsaw-test.yaml b/best-practices/disallow-empty-ingress-host/.chainsaw-test/chainsaw-test.yaml index ea88b458f..e2f1b81f1 100755 --- a/best-practices/disallow-empty-ingress-host/.chainsaw-test/chainsaw-test.yaml +++ b/best-practices/disallow-empty-ingress-host/.chainsaw-test/chainsaw-test.yaml @@ -10,6 +10,14 @@ spec: try: - apply: file: ../disallow-empty-ingress-host.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: disallow-empty-ingress-host + spec: + validationFailureAction: Enforce - assert: file: policy-ready.yaml - name: step-02 diff --git a/best-practices/disallow-empty-ingress-host/artifacthub-pkg.yml b/best-practices/disallow-empty-ingress-host/artifacthub-pkg.yml index 35a403ede..5baa5dbb3 100644 --- a/best-practices/disallow-empty-ingress-host/artifacthub-pkg.yml +++ b/best-practices/disallow-empty-ingress-host/artifacthub-pkg.yml @@ -18,4 +18,4 @@ readme: | annotations: kyverno/category: "Best Practices" kyverno/subject: "Ingress" -digest: f9e70cf095e2d69a9586d7b8071975006e76aa715e5c978d37761c03ac6fc7fd +digest: dc6573e0a73eeb6e698fff33c86c2ec05af93d470f13a92e9af6a1cac6538721 diff --git a/best-practices/disallow-empty-ingress-host/disallow-empty-ingress-host.yaml b/best-practices/disallow-empty-ingress-host/disallow-empty-ingress-host.yaml index 142f6323d..daf459b8c 100644 --- a/best-practices/disallow-empty-ingress-host/disallow-empty-ingress-host.yaml +++ b/best-practices/disallow-empty-ingress-host/disallow-empty-ingress-host.yaml @@ -13,7 +13,7 @@ metadata: in order to be valid. This policy ensures that there is a hostname for each rule defined. spec: - validationFailureAction: enforce + validationFailureAction: Audit background: false rules: - name: disallow-empty-ingress-host diff --git a/best-practices/disallow-helm-tiller/.chainsaw-test/bad-deploy.yaml b/best-practices/disallow-helm-tiller/.chainsaw-test/bad-deploy.yaml index 5fbfecc4b..e2b85aea5 100644 --- a/best-practices/disallow-helm-tiller/.chainsaw-test/bad-deploy.yaml +++ b/best-practices/disallow-helm-tiller/.chainsaw-test/bad-deploy.yaml @@ -16,6 +16,6 @@ spec: spec: containers: - image: busybox - name: busybox:1.35 + name: busybox - image: docker.io/tiller:latest name: helm-tiller diff --git a/best-practices/disallow-helm-tiller/.chainsaw-test/chainsaw-test.yaml b/best-practices/disallow-helm-tiller/.chainsaw-test/chainsaw-test.yaml index 86f7dac53..982fedabe 100755 --- a/best-practices/disallow-helm-tiller/.chainsaw-test/chainsaw-test.yaml +++ b/best-practices/disallow-helm-tiller/.chainsaw-test/chainsaw-test.yaml @@ -19,7 +19,7 @@ spec: spec: validationFailureAction: Enforce - assert: - file: chainsaw-step-01-assert-1.yaml + file: policy-ready.yaml - name: step-02 try: - apply: diff --git a/best-practices/disallow-helm-tiller/.chainsaw-test/chainsaw-step-01-assert-1.yaml b/best-practices/disallow-helm-tiller/.chainsaw-test/policy-ready.yaml similarity index 100% rename from best-practices/disallow-helm-tiller/.chainsaw-test/chainsaw-step-01-assert-1.yaml rename to best-practices/disallow-helm-tiller/.chainsaw-test/policy-ready.yaml diff --git a/best-practices/disallow-latest-tag/.chainsaw-test/chainsaw-test.yaml b/best-practices/disallow-latest-tag/.chainsaw-test/chainsaw-test.yaml index 3703335f2..d5e9fb6f8 100755 --- a/best-practices/disallow-latest-tag/.chainsaw-test/chainsaw-test.yaml +++ b/best-practices/disallow-latest-tag/.chainsaw-test/chainsaw-test.yaml @@ -19,7 +19,7 @@ spec: spec: validationFailureAction: Enforce - assert: - file: chainsaw-step-01-assert-1.yaml + file: policy-ready.yaml - name: step-02 try: - apply: diff --git a/best-practices/disallow-latest-tag/.chainsaw-test/chainsaw-step-01-assert-1.yaml b/best-practices/disallow-latest-tag/.chainsaw-test/policy-ready.yaml similarity index 100% rename from best-practices/disallow-latest-tag/.chainsaw-test/chainsaw-step-01-assert-1.yaml rename to best-practices/disallow-latest-tag/.chainsaw-test/policy-ready.yaml diff --git a/best-practices/require-drop-all/.chainsaw-test/bad-pod-corner.yaml b/best-practices/require-drop-all/.chainsaw-test/bad-pod-corner.yaml index e29726b9a..94bf1acf0 100644 --- a/best-practices/require-drop-all/.chainsaw-test/bad-pod-corner.yaml +++ b/best-practices/require-drop-all/.chainsaw-test/bad-pod-corner.yaml @@ -11,13 +11,13 @@ spec: add: ["SYS_TIME"] drop: - ALL - - name: add-capabilities + - name: add-capabilities-again image: busybox:1.35 securityContext: capabilities: add: ["SYS_TIME"] drop: - - ["CAP_NET_RAW"] + - CAP_NET_RAW --- apiVersion: v1 kind: Pod @@ -30,7 +30,7 @@ spec: securityContext: capabilities: add: ["SYS_TIME"] - - name: add-capabilities + - name: add-capabilities-again image: busybox:1.35 securityContext: capabilities: @@ -41,7 +41,7 @@ spec: apiVersion: v1 kind: Pod metadata: - name: add-capabilities-good + name: add-capabilities-bad spec: containers: - name: init diff --git a/best-practices/require-drop-all/.chainsaw-test/chainsaw-test.yaml b/best-practices/require-drop-all/.chainsaw-test/chainsaw-test.yaml index 02dce4a76..8324d8345 100755 --- a/best-practices/require-drop-all/.chainsaw-test/chainsaw-test.yaml +++ b/best-practices/require-drop-all/.chainsaw-test/chainsaw-test.yaml @@ -19,7 +19,7 @@ spec: spec: validationFailureAction: Enforce - assert: - file: chainsaw-step-01-assert-1.yaml + file: policy-ready.yaml - name: step-02 try: - apply: diff --git a/best-practices/require-drop-all/.chainsaw-test/chainsaw-step-01-assert-1.yaml b/best-practices/require-drop-all/.chainsaw-test/policy-ready.yaml similarity index 100% rename from best-practices/require-drop-all/.chainsaw-test/chainsaw-step-01-assert-1.yaml rename to best-practices/require-drop-all/.chainsaw-test/policy-ready.yaml diff --git a/best-practices/require-drop-cap-net-raw/.chainsaw-test/bad-pod-corner.yaml b/best-practices/require-drop-cap-net-raw/.chainsaw-test/bad-pod-corner.yaml index 0ea6ffb92..a4702dbce 100644 --- a/best-practices/require-drop-cap-net-raw/.chainsaw-test/bad-pod-corner.yaml +++ b/best-practices/require-drop-cap-net-raw/.chainsaw-test/bad-pod-corner.yaml @@ -1,7 +1,7 @@ apiVersion: v1 kind: Pod metadata: - name: add-capabilities-bad + name: add-capabilities-bad-001 spec: containers: - name: add-capabilities @@ -10,7 +10,7 @@ spec: capabilities: drop: - CAP_NET_RAW - - name: add-capabilities + - name: add-capabilities-again image: busybox:1.35 securityContext: capabilities: @@ -20,7 +20,7 @@ spec: apiVersion: v1 kind: Pod metadata: - name: add-capabilities-bad + name: add-capabilities-bad-002 spec: containers: - name: add-capabilities @@ -28,7 +28,7 @@ spec: securityContext: capabilities: add: ["SYS_TIME"] - - name: add-capabilities + - name: add-capabilities-again image: busybox:1.35 securityContext: capabilities: diff --git a/best-practices/require-drop-cap-net-raw/.chainsaw-test/bad-pod-initcontainers.yaml b/best-practices/require-drop-cap-net-raw/.chainsaw-test/bad-pod-initcontainers.yaml index dba8a40bf..961ae740e 100644 --- a/best-practices/require-drop-cap-net-raw/.chainsaw-test/bad-pod-initcontainers.yaml +++ b/best-practices/require-drop-cap-net-raw/.chainsaw-test/bad-pod-initcontainers.yaml @@ -1,7 +1,7 @@ apiVersion: v1 kind: Pod metadata: - name: add-capabilities-bad + name: add-capabilities-bad-1 spec: initContainers: - name: init @@ -25,7 +25,7 @@ spec: apiVersion: v1 kind: Pod metadata: - name: add-capabilities-bad + name: add-capabilities-bad-2 spec: initContainers: - name: init diff --git a/best-practices/require-drop-cap-net-raw/.chainsaw-test/chainsaw-test.yaml b/best-practices/require-drop-cap-net-raw/.chainsaw-test/chainsaw-test.yaml index ea755bb20..b205c83c2 100755 --- a/best-practices/require-drop-cap-net-raw/.chainsaw-test/chainsaw-test.yaml +++ b/best-practices/require-drop-cap-net-raw/.chainsaw-test/chainsaw-test.yaml @@ -19,7 +19,7 @@ spec: spec: validationFailureAction: Enforce - assert: - file: chainsaw-step-01-assert-1.yaml + file: policy-ready.yaml - name: step-02 try: - apply: diff --git a/best-practices/require-drop-cap-net-raw/.chainsaw-test/chainsaw-step-01-assert-1.yaml b/best-practices/require-drop-cap-net-raw/.chainsaw-test/policy-ready.yaml similarity index 100% rename from best-practices/require-drop-cap-net-raw/.chainsaw-test/chainsaw-step-01-assert-1.yaml rename to best-practices/require-drop-cap-net-raw/.chainsaw-test/policy-ready.yaml diff --git a/best-practices/require-labels/.chainsaw-test/bad-podcontrollers.yaml b/best-practices/require-labels/.chainsaw-test/bad-podcontrollers.yaml index a34a7a944..71a7e6e1b 100644 --- a/best-practices/require-labels/.chainsaw-test/bad-podcontrollers.yaml +++ b/best-practices/require-labels/.chainsaw-test/bad-podcontrollers.yaml @@ -10,7 +10,7 @@ spec: template: metadata: labels: - foo: bar + app: app spec: containers: - name: busybox diff --git a/best-practices/require-labels/.chainsaw-test/chainsaw-test.yaml b/best-practices/require-labels/.chainsaw-test/chainsaw-test.yaml index 6d8a1442d..77d167c73 100755 --- a/best-practices/require-labels/.chainsaw-test/chainsaw-test.yaml +++ b/best-practices/require-labels/.chainsaw-test/chainsaw-test.yaml @@ -19,7 +19,7 @@ spec: spec: validationFailureAction: Enforce - assert: - file: chainsaw-step-01-assert-1.yaml + file: policy-ready.yaml - name: step-02 try: - apply: diff --git a/best-practices/require-labels/.chainsaw-test/chainsaw-step-01-assert-1.yaml b/best-practices/require-labels/.chainsaw-test/policy-ready.yaml similarity index 100% rename from best-practices/require-labels/.chainsaw-test/chainsaw-step-01-assert-1.yaml rename to best-practices/require-labels/.chainsaw-test/policy-ready.yaml diff --git a/best-practices/require-pod-requests-limits/.chainsaw-test/chainsaw-test.yaml b/best-practices/require-pod-requests-limits/.chainsaw-test/chainsaw-test.yaml index 8b0b6581c..f274df775 100755 --- a/best-practices/require-pod-requests-limits/.chainsaw-test/chainsaw-test.yaml +++ b/best-practices/require-pod-requests-limits/.chainsaw-test/chainsaw-test.yaml @@ -19,7 +19,7 @@ spec: spec: validationFailureAction: Enforce - assert: - file: chainsaw-step-01-assert-1.yaml + file: policy-ready.yaml - name: step-02 try: - apply: diff --git a/best-practices/require-pod-requests-limits/.chainsaw-test/chainsaw-step-01-assert-1.yaml b/best-practices/require-pod-requests-limits/.chainsaw-test/policy-ready.yaml similarity index 100% rename from best-practices/require-pod-requests-limits/.chainsaw-test/chainsaw-step-01-assert-1.yaml rename to best-practices/require-pod-requests-limits/.chainsaw-test/policy-ready.yaml diff --git a/best-practices/require-probes/.chainsaw-test/bad-pod-notall.yaml b/best-practices/require-probes/.chainsaw-test/bad-pod-notall.yaml index 469ce4446..e13d87ed4 100644 --- a/best-practices/require-probes/.chainsaw-test/bad-pod-notall.yaml +++ b/best-practices/require-probes/.chainsaw-test/bad-pod-notall.yaml @@ -14,7 +14,7 @@ spec: tcpSocket: port: 8080 periodSeconds: 10 - - name: busybox + - name: busybox-again image: busybox:1.35 --- apiVersion: v1 @@ -27,7 +27,7 @@ spec: containers: - name: busybox image: busybox:1.35 - - name: busybox + - name: busybox-again image: busybox:1.35 ports: - containerPort: 8080 diff --git a/best-practices/require-probes/.chainsaw-test/chainsaw-test.yaml b/best-practices/require-probes/.chainsaw-test/chainsaw-test.yaml index 5c1b1fafb..7a5fba016 100755 --- a/best-practices/require-probes/.chainsaw-test/chainsaw-test.yaml +++ b/best-practices/require-probes/.chainsaw-test/chainsaw-test.yaml @@ -19,7 +19,7 @@ spec: spec: validationFailureAction: Enforce - assert: - file: chainsaw-step-01-assert-1.yaml + file: policy-ready.yaml - name: step-02 try: - apply: @@ -41,10 +41,4 @@ spec: - check: ($error != null): true file: bad-podcontrollers.yaml - - name: step-03 - try: - - apply: - expect: - - check: - ($error != null): true - file: bad-pod-update.yaml + diff --git a/best-practices/require-probes/.chainsaw-test/chainsaw-step-01-assert-1.yaml b/best-practices/require-probes/.chainsaw-test/policy-ready.yaml similarity index 100% rename from best-practices/require-probes/.chainsaw-test/chainsaw-step-01-assert-1.yaml rename to best-practices/require-probes/.chainsaw-test/policy-ready.yaml diff --git a/best-practices/require-ro-rootfs/.chainsaw-test/bad-pod-notall.yaml b/best-practices/require-ro-rootfs/.chainsaw-test/bad-pod-notall.yaml index f04c93285..df4910577 100644 --- a/best-practices/require-ro-rootfs/.chainsaw-test/bad-pod-notall.yaml +++ b/best-practices/require-ro-rootfs/.chainsaw-test/bad-pod-notall.yaml @@ -6,7 +6,7 @@ spec: containers: - name: busybox image: busybox:1.35 - - name: busybox + - name: busybox-again image: busybox:1.35 securityContext: readOnlyRootFilesystem: true @@ -21,5 +21,5 @@ spec: image: busybox:1.35 securityContext: readOnlyRootFilesystem: true - - name: busybox + - name: busybox-again image: busybox:1.35 \ No newline at end of file diff --git a/best-practices/require-ro-rootfs/.chainsaw-test/bad-podcontrollers.yaml b/best-practices/require-ro-rootfs/.chainsaw-test/bad-podcontrollers.yaml index b2f168d04..29a800931 100644 --- a/best-practices/require-ro-rootfs/.chainsaw-test/bad-podcontrollers.yaml +++ b/best-practices/require-ro-rootfs/.chainsaw-test/bad-podcontrollers.yaml @@ -10,7 +10,7 @@ spec: template: metadata: labels: - foo: bar + app: app spec: containers: - name: busybox diff --git a/best-practices/require-ro-rootfs/.chainsaw-test/chainsaw-test.yaml b/best-practices/require-ro-rootfs/.chainsaw-test/chainsaw-test.yaml index d7e2936cc..2ffe3e63d 100755 --- a/best-practices/require-ro-rootfs/.chainsaw-test/chainsaw-test.yaml +++ b/best-practices/require-ro-rootfs/.chainsaw-test/chainsaw-test.yaml @@ -19,7 +19,7 @@ spec: spec: validationFailureAction: Enforce - assert: - file: chainsaw-step-01-assert-1.yaml + file: policy-ready.yaml - name: step-02 try: - apply: diff --git a/best-practices/require-ro-rootfs/.chainsaw-test/chainsaw-step-01-assert-1.yaml b/best-practices/require-ro-rootfs/.chainsaw-test/policy-ready.yaml similarity index 100% rename from best-practices/require-ro-rootfs/.chainsaw-test/chainsaw-step-01-assert-1.yaml rename to best-practices/require-ro-rootfs/.chainsaw-test/policy-ready.yaml diff --git a/best-practices/restrict-image-registries/.chainsaw-test/bad-podcontrollers.yaml b/best-practices/restrict-image-registries/.chainsaw-test/bad-podcontrollers.yaml index c85b49f08..1a0180e09 100644 --- a/best-practices/restrict-image-registries/.chainsaw-test/bad-podcontrollers.yaml +++ b/best-practices/restrict-image-registries/.chainsaw-test/bad-podcontrollers.yaml @@ -10,7 +10,7 @@ spec: template: metadata: labels: - foo: bar + app: app spec: initContainers: - name: k8s-nginx-init @@ -35,7 +35,7 @@ spec: template: metadata: labels: - foo: bar + app: app spec: initContainers: - name: k8s-nginx-init @@ -60,7 +60,7 @@ spec: template: metadata: labels: - foo: bar + app: app spec: initContainers: - name: k8s-nginx-init diff --git a/best-practices/restrict-image-registries/.chainsaw-test/chainsaw-test.yaml b/best-practices/restrict-image-registries/.chainsaw-test/chainsaw-test.yaml index 296a9a062..ca38e8f03 100755 --- a/best-practices/restrict-image-registries/.chainsaw-test/chainsaw-test.yaml +++ b/best-practices/restrict-image-registries/.chainsaw-test/chainsaw-test.yaml @@ -19,7 +19,7 @@ spec: spec: validationFailureAction: Enforce - assert: - file: chainsaw-step-01-assert-1.yaml + file: policy-ready.yaml - name: step-02 try: - apply: diff --git a/best-practices/restrict-image-registries/.chainsaw-test/chainsaw-step-01-assert-1.yaml b/best-practices/restrict-image-registries/.chainsaw-test/policy-ready.yaml similarity index 100% rename from best-practices/restrict-image-registries/.chainsaw-test/chainsaw-step-01-assert-1.yaml rename to best-practices/restrict-image-registries/.chainsaw-test/policy-ready.yaml diff --git a/best-practices/restrict-node-port/.chainsaw-test/chainsaw-test.yaml b/best-practices/restrict-node-port/.chainsaw-test/chainsaw-test.yaml index d4072dd6e..fdc4b09c3 100755 --- a/best-practices/restrict-node-port/.chainsaw-test/chainsaw-test.yaml +++ b/best-practices/restrict-node-port/.chainsaw-test/chainsaw-test.yaml @@ -19,7 +19,7 @@ spec: spec: validationFailureAction: Enforce - assert: - file: chainsaw-step-01-assert-1.yaml + file: policy-ready.yaml - name: step-02 try: - apply: diff --git a/best-practices/restrict-node-port/.chainsaw-test/chainsaw-step-01-assert-1.yaml b/best-practices/restrict-node-port/.chainsaw-test/policy-ready.yaml similarity index 100% rename from best-practices/restrict-node-port/.chainsaw-test/chainsaw-step-01-assert-1.yaml rename to best-practices/restrict-node-port/.chainsaw-test/policy-ready.yaml diff --git a/best-practices/restrict-service-external-ips/.chainsaw-test/chainsaw-test.yaml b/best-practices/restrict-service-external-ips/.chainsaw-test/chainsaw-test.yaml index d7fee19b0..3520df0b2 100755 --- a/best-practices/restrict-service-external-ips/.chainsaw-test/chainsaw-test.yaml +++ b/best-practices/restrict-service-external-ips/.chainsaw-test/chainsaw-test.yaml @@ -19,7 +19,7 @@ spec: spec: validationFailureAction: Enforce - assert: - file: chainsaw-step-01-assert-1.yaml + file: policy-ready.yaml - name: step-02 try: - apply: diff --git a/best-practices/restrict-service-external-ips/.chainsaw-test/chainsaw-step-01-assert-1.yaml b/best-practices/restrict-service-external-ips/.chainsaw-test/policy-ready.yaml similarity index 100% rename from best-practices/restrict-service-external-ips/.chainsaw-test/chainsaw-step-01-assert-1.yaml rename to best-practices/restrict-service-external-ips/.chainsaw-test/policy-ready.yaml