From bc1a92befd30a061dcfdf517bde94ad33bd5a3a3 Mon Sep 17 00:00:00 2001 From: Anudeep Nalla <121174814+anuddeeph1@users.noreply.github.com> Date: Fri, 2 Aug 2024 19:30:02 +0530 Subject: [PATCH 1/4] Added policy for require-run-as-containeruser for windows pods (#1024) * Added policy for require-run-as-containeruser Signed-off-by: Anudeep Nalla * modified digest Signed-off-by: Anudeep Nalla * added windows-pod-security directory to test.yaml in workflows Signed-off-by: Anudeep Nalla * modified require-run-as-containeruser Signed-off-by: root * modified require-run-as-containeruser Signed-off-by: root * modified require-run-as-containeruser.yaml Signed-off-by: Anudeep Nalla * added windows-security in workflows test.yml Signed-off-by: anuddeeph1 * added windows-security in test.yml Signed-off-by: anuddeeph1 * resolving conflict in test.yml Signed-off-by: anuddeeph1 * added windows-security in test.yml Signed-off-by: anuddeeph1 * added proper digest in artifacthub-pkg.yml Signed-off-by: anuddeeph1 * resolving conflict in test.yaml Signed-off-by: anuddeeph1 * resolving conflict in test.yaml Signed-off-by: anuddeeph1 * resolving conflict in test.yaml Signed-off-by: anuddeeph1 * Update .github/workflows/test.yml Signed-off-by: Chip Zoller * Update windows-security/require-run-as-containeruser/artifacthub-pkg.yml Signed-off-by: Chip Zoller --------- Signed-off-by: Anudeep Nalla Signed-off-by: root Signed-off-by: anuddeeph1 Signed-off-by: Anudeep Nalla <121174814+anuddeeph1@users.noreply.github.com> Signed-off-by: Chip Zoller Co-authored-by: Anudeep Nalla Co-authored-by: Chip Zoller --- .../chainsaw-step-01-assert-1.yaml | 6 +++ .../.chainsaw-test/chainsaw-test.yaml | 37 ++++++++++++++++ .../.chainsaw-test/pod-bad.yaml | 17 ++++++++ .../.chainsaw-test/pod-good.yaml | 18 ++++++++ .../.chainsaw-test/podcontroller-bad.yaml | 26 +++++++++++ .../.chainsaw-test/podcontroller-good.yaml | 27 ++++++++++++ .../artifacthub-pkg.yml | 23 ++++++++++ .../require-run-as-containeruser.yaml | 43 +++++++++++++++++++ 8 files changed, 197 insertions(+) create mode 100755 windows-security/require-run-as-containeruser/.chainsaw-test/chainsaw-step-01-assert-1.yaml create mode 100755 windows-security/require-run-as-containeruser/.chainsaw-test/chainsaw-test.yaml create mode 100644 windows-security/require-run-as-containeruser/.chainsaw-test/pod-bad.yaml create mode 100644 windows-security/require-run-as-containeruser/.chainsaw-test/pod-good.yaml create mode 100644 windows-security/require-run-as-containeruser/.chainsaw-test/podcontroller-bad.yaml create mode 100644 windows-security/require-run-as-containeruser/.chainsaw-test/podcontroller-good.yaml create mode 100644 windows-security/require-run-as-containeruser/artifacthub-pkg.yml create mode 100644 windows-security/require-run-as-containeruser/require-run-as-containeruser.yaml diff --git a/windows-security/require-run-as-containeruser/.chainsaw-test/chainsaw-step-01-assert-1.yaml b/windows-security/require-run-as-containeruser/.chainsaw-test/chainsaw-step-01-assert-1.yaml new file mode 100755 index 000000000..9fb95c569 --- /dev/null +++ b/windows-security/require-run-as-containeruser/.chainsaw-test/chainsaw-step-01-assert-1.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: require-run-as-containeruser +status: + ready: true diff --git a/windows-security/require-run-as-containeruser/.chainsaw-test/chainsaw-test.yaml b/windows-security/require-run-as-containeruser/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..93d87ea58 --- /dev/null +++ b/windows-security/require-run-as-containeruser/.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: + name: require-run-as-containeruser +spec: + steps: + - name: step-01 + try: + - apply: + file: ../require-run-as-containeruser.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: require-run-as-containeruser + spec: + validationFailureAction: Enforce + - assert: + file: chainsaw-step-01-assert-1.yaml + - name: step-02 + try: + - apply: + file: pod-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: pod-bad.yaml + - apply: + file: podcontroller-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: podcontroller-bad.yaml diff --git a/windows-security/require-run-as-containeruser/.chainsaw-test/pod-bad.yaml b/windows-security/require-run-as-containeruser/.chainsaw-test/pod-bad.yaml new file mode 100644 index 000000000..bbade42c8 --- /dev/null +++ b/windows-security/require-run-as-containeruser/.chainsaw-test/pod-bad.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Pod +metadata: + name: bad-windows-pod +spec: + nodeSelector: + kubernetes.io/arch: amd64 + kubernetes.io/os: windows + securityContext: + windowsOptions: + hostProcess: true + runAsUserName: "NT AUTHORITY\\Local service" + hostNetwork: true + containers: + - name: windows-container + image: mcr.microsoft.com/windows/servercore:ltsc2019 + command: ["cmd", "/c", "echo", "Hello from Windows Container && timeout", "/t", "300"] diff --git a/windows-security/require-run-as-containeruser/.chainsaw-test/pod-good.yaml b/windows-security/require-run-as-containeruser/.chainsaw-test/pod-good.yaml new file mode 100644 index 000000000..75c040c16 --- /dev/null +++ b/windows-security/require-run-as-containeruser/.chainsaw-test/pod-good.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Pod +metadata: + name: good-windows-pod +spec: + nodeSelector: + kubernetes.io/arch: amd64 + kubernetes.io/os: windows + securityContext: + runAsNonRoot: true + windowsOptions: + hostProcess: false + runAsUserName: "ContainerUser" + hostNetwork: false + containers: + - name: windows-container + image: mcr.microsoft.com/windows/servercore:ltsc2019 + command: ["cmd", "/c", "echo", "Hello from Windows Container && timeout", "/t", "300"] diff --git a/windows-security/require-run-as-containeruser/.chainsaw-test/podcontroller-bad.yaml b/windows-security/require-run-as-containeruser/.chainsaw-test/podcontroller-bad.yaml new file mode 100644 index 000000000..97b454eaa --- /dev/null +++ b/windows-security/require-run-as-containeruser/.chainsaw-test/podcontroller-bad.yaml @@ -0,0 +1,26 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: bad-windows-deployment +spec: + replicas: 1 + selector: + matchLabels: + app: windows-app + template: + metadata: + labels: + app: windows-app + spec: + nodeSelector: + kubernetes.io/arch: amd64 + kubernetes.io/os: windows + securityContext: + windowsOptions: + hostProcess: true + runAsUserName: "NT AUTHORITY\\Local service" + hostNetwork: true + containers: + - name: windows-container + image: mcr.microsoft.com/windows/servercore:ltsc2019 + command: ["cmd", "/c", "echo", "Hello from Windows Container && timeout", "/t", "300"] diff --git a/windows-security/require-run-as-containeruser/.chainsaw-test/podcontroller-good.yaml b/windows-security/require-run-as-containeruser/.chainsaw-test/podcontroller-good.yaml new file mode 100644 index 000000000..5d8bbf602 --- /dev/null +++ b/windows-security/require-run-as-containeruser/.chainsaw-test/podcontroller-good.yaml @@ -0,0 +1,27 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: good-windows-deployment +spec: + replicas: 1 + selector: + matchLabels: + app: windows-app + template: + metadata: + labels: + app: windows-app + spec: + nodeSelector: + kubernetes.io/arch: amd64 + kubernetes.io/os: windows + securityContext: + runAsNonRoot: true + windowsOptions: + hostProcess: false + runAsUserName: "ContainerUser" + hostNetwork: false + containers: + - name: windows-container + image: mcr.microsoft.com/windows/servercore:ltsc2019 + command: ["cmd", "/c", "echo", "Hello from Windows Container && timeout", "/t", "300"] diff --git a/windows-security/require-run-as-containeruser/artifacthub-pkg.yml b/windows-security/require-run-as-containeruser/artifacthub-pkg.yml new file mode 100644 index 000000000..d11205de7 --- /dev/null +++ b/windows-security/require-run-as-containeruser/artifacthub-pkg.yml @@ -0,0 +1,23 @@ +name: require-run-as-containeruser +version: 1.0.0 +displayName: Require runAsContainerUser (Windows) +createdAt: "2024-05-21T09:05:16.000Z" +description: >- + Containers must be required to run as ContainerUser. This policy ensures that the fields spec.securityContext.windowsOptions.runAsUserName, spec.containers[*].securityContext.windowsOptions.runAsUserName, spec.initContainers[*].securityContext.windowsOptions.runAsUserName is either unset or set to ContainerUser. + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/windows-security/require-run-as-containeruser/require-run-as-containeruser.yaml + ``` +keywords: + - kyverno + - Windows Security +readme: | + Containers must be required to run as ContainerUser. This policy ensures that the fields spec.securityContext.windowsOptions.runAsUserName, spec.containers[*].securityContext.windowsOptions.runAsUserName, spec.initContainers[*].securityContext.windowsOptions.runAsUserName is either unset or set to ContainerUser. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Windows Security" + kyverno/kubernetesVersion: "1.22-1.28" + kyverno/subject: "Pod" +digest: e51c72783f9c92d0ba3337d8e41bb5383b7ce15f583d7e1732ef75d7c1acd811 diff --git a/windows-security/require-run-as-containeruser/require-run-as-containeruser.yaml b/windows-security/require-run-as-containeruser/require-run-as-containeruser.yaml new file mode 100644 index 000000000..547bb2a34 --- /dev/null +++ b/windows-security/require-run-as-containeruser/require-run-as-containeruser.yaml @@ -0,0 +1,43 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: require-run-as-containeruser + annotations: + policies.kyverno.io/title: Require Run As ContainerUser (Windows) + policies.kyverno.io/category: Windows Security + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + kyverno.io/kyverno-version: 1.6.0 + kyverno.io/kubernetes-version: "1.22-1.28" + policies.kyverno.io/description: >- + Containers must be required to run as ContainerUser. This policy ensures that the fields + spec.securityContext.windowsOptions.runAsUserName, + spec.containers[*].securityContext.windowsOptions.runAsUserName, + spec.initContainers[*].securityContext.windowsOptions.runAsUserName, + and is either unset or set to ContainerUser. +spec: + validationFailureAction: audit + background: true + rules: + - name: require-run-as-containeruser + match: + any: + - resources: + kinds: + - Pod + validate: + message: >- + Running the container as ContainerAdministrator,NT AUTHORITY\NETWORK SERVICE, NT AUTHORITY\LOCAL SERVICE is not allowed. + pattern: + spec: + =(securityContext): + =(windowsOptions): + =(runAsUserName): "ContainerUser" + =(initContainers): + - =(securityContext): + =(windowsOptions): + =(runAsUserName): "ContainerUser" + containers: + - =(securityContext): + =(windowsOptions): + =(runAsUserName): "ContainerUser" From 52533f68df5ee4ec02b9a29b2c00b83e11945034 Mon Sep 17 00:00:00 2001 From: nsagark <90008930+nsagark@users.noreply.github.com> Date: Fri, 2 Aug 2024 10:09:46 -0400 Subject: [PATCH 2/4] Add policy Restrict Clusterrole for Mutating and Validating Admission Webhooks (#1068) * Adding files for restrict-clusterrole-mutating-validating-admission-webhooks policy Signed-off-by: nsagark * Updated the policy and the artifacthub-pkg.yml Signed-off-by: nsagark * added the missing annotations and updated the artifacthub-pkg.yml Signed-off-by: nsagark * Updated the digest in the artifacthub-pkg.yml Signed-off-by: nsagark * Updated the digest in the artifacthub-pkg.yml Signed-off-by: nsagark --------- Signed-off-by: nsagark Co-authored-by: Chip Zoller --- .../chainsaw-step-01-assert-1.yaml | 6 +++ .../.chainsaw-test/chainsaw-test.yaml | 31 ++++++++++++ .../non-violating-clusterrole.yaml | 11 ++++ .../.chainsaw-test/violating-clusterrole.yaml | 11 ++++ .../.kyverno-test/kyverno-test.yaml | 21 ++++++++ .../.kyverno-test/resource.yaml | 25 ++++++++++ .../artifacthub-pkg.yml | 21 ++++++++ ...utating-validating-admission-webhooks.yaml | 50 +++++++++++++++++++ 8 files changed, 176 insertions(+) create mode 100644 other/restrict-clusterrole-mutating-validating-admission-webhooks/.chainsaw-test/chainsaw-step-01-assert-1.yaml create mode 100644 other/restrict-clusterrole-mutating-validating-admission-webhooks/.chainsaw-test/chainsaw-test.yaml create mode 100644 other/restrict-clusterrole-mutating-validating-admission-webhooks/.chainsaw-test/non-violating-clusterrole.yaml create mode 100644 other/restrict-clusterrole-mutating-validating-admission-webhooks/.chainsaw-test/violating-clusterrole.yaml create mode 100644 other/restrict-clusterrole-mutating-validating-admission-webhooks/.kyverno-test/kyverno-test.yaml create mode 100644 other/restrict-clusterrole-mutating-validating-admission-webhooks/.kyverno-test/resource.yaml create mode 100644 other/restrict-clusterrole-mutating-validating-admission-webhooks/artifacthub-pkg.yml create mode 100644 other/restrict-clusterrole-mutating-validating-admission-webhooks/restrict-clusterrole-mutating-validating-admission-webhooks.yaml diff --git a/other/restrict-clusterrole-mutating-validating-admission-webhooks/.chainsaw-test/chainsaw-step-01-assert-1.yaml b/other/restrict-clusterrole-mutating-validating-admission-webhooks/.chainsaw-test/chainsaw-step-01-assert-1.yaml new file mode 100644 index 000000000..5f5432cb0 --- /dev/null +++ b/other/restrict-clusterrole-mutating-validating-admission-webhooks/.chainsaw-test/chainsaw-step-01-assert-1.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-clusterrole-mutating-validating-admission-webhooks +status: + ready: true diff --git a/other/restrict-clusterrole-mutating-validating-admission-webhooks/.chainsaw-test/chainsaw-test.yaml b/other/restrict-clusterrole-mutating-validating-admission-webhooks/.chainsaw-test/chainsaw-test.yaml new file mode 100644 index 000000000..c834989ea --- /dev/null +++ b/other/restrict-clusterrole-mutating-validating-admission-webhooks/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,31 @@ +# 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-clusterrole-mutating-validating-admission-webhooks +spec: + steps: + - name: step-01 + try: + - apply: + file: ../restrict-clusterrole-mutating-validating-admission-webhooks.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: restrict-clusterrole-mutating-validating-admission-webhooks + spec: + validationFailureAction: Enforce + - assert: + file: chainsaw-step-01-assert-1.yaml + - name: step-02 + try: + - apply: + file: non-violating-clusterrole.yaml + - apply: + expect: + - check: + ($error != null): true + file: violating-clusterrole.yaml diff --git a/other/restrict-clusterrole-mutating-validating-admission-webhooks/.chainsaw-test/non-violating-clusterrole.yaml b/other/restrict-clusterrole-mutating-validating-admission-webhooks/.chainsaw-test/non-violating-clusterrole.yaml new file mode 100644 index 000000000..442ff536e --- /dev/null +++ b/other/restrict-clusterrole-mutating-validating-admission-webhooks/.chainsaw-test/non-violating-clusterrole.yaml @@ -0,0 +1,11 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: non-violating-clusterrole +rules: +- apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch"] +- apiGroups: ["admissionregistration.k8s.io"] + resources: ["mutatingwebhookconfigurations", "validatingwebhookconfigurations"] + verbs: ["get", "list", "watch"] diff --git a/other/restrict-clusterrole-mutating-validating-admission-webhooks/.chainsaw-test/violating-clusterrole.yaml b/other/restrict-clusterrole-mutating-validating-admission-webhooks/.chainsaw-test/violating-clusterrole.yaml new file mode 100644 index 000000000..42991b97a --- /dev/null +++ b/other/restrict-clusterrole-mutating-validating-admission-webhooks/.chainsaw-test/violating-clusterrole.yaml @@ -0,0 +1,11 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: violating-clusterrole +rules: +- apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch"] +- apiGroups: ["admissionregistration.k8s.io"] + resources: ["mutatingwebhookconfigurations", "validatingwebhookconfigurations"] + verbs: ["create", "update", "patch"] diff --git a/other/restrict-clusterrole-mutating-validating-admission-webhooks/.kyverno-test/kyverno-test.yaml b/other/restrict-clusterrole-mutating-validating-admission-webhooks/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..9049cfb16 --- /dev/null +++ b/other/restrict-clusterrole-mutating-validating-admission-webhooks/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,21 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: restrict-clusterrole-mutating-validating-admission-webhooks +policies: +- ../restrict-clusterrole-mutating-validating-admission-webhooks.yaml +resources: +- resource.yaml +results: +- kind: ClusterRole + policy: restrict-clusterrole-mutating-validating-admission-webhooks + resources: + - non-violating-clusterrole + result: pass + rule: restrict-clusterrole +- kind: ClusterRole + policy: restrict-clusterrole-mutating-validating-admission-webhooks + resources: + - violating-clusterrole + result: fail + rule: restrict-clusterrole diff --git a/other/restrict-clusterrole-mutating-validating-admission-webhooks/.kyverno-test/resource.yaml b/other/restrict-clusterrole-mutating-validating-admission-webhooks/.kyverno-test/resource.yaml new file mode 100644 index 000000000..07fc9bfd9 --- /dev/null +++ b/other/restrict-clusterrole-mutating-validating-admission-webhooks/.kyverno-test/resource.yaml @@ -0,0 +1,25 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: non-violating-clusterrole +rules: +- apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch"] +- apiGroups: ["admissionregistration.k8s.io"] + resources: ["mutatingwebhookconfigurations", "validatingwebhookconfigurations"] + verbs: ["get", "list", "watch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: violating-clusterrole +rules: +- apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch"] +- apiGroups: ["admissionregistration.k8s.io"] + resources: ["mutatingwebhookconfigurations", "validatingwebhookconfigurations"] + verbs: ["create", "update", "patch"] + diff --git a/other/restrict-clusterrole-mutating-validating-admission-webhooks/artifacthub-pkg.yml b/other/restrict-clusterrole-mutating-validating-admission-webhooks/artifacthub-pkg.yml new file mode 100644 index 000000000..0f21b043c --- /dev/null +++ b/other/restrict-clusterrole-mutating-validating-admission-webhooks/artifacthub-pkg.yml @@ -0,0 +1,21 @@ +name: restrict-clusterrole-mutating-validating-admission-webhooks +version: 1.0.0 +displayName: Restrict Clusterrole for Mutating and Validating Admission Webhooks +createdAt: "2024-05-19T20:30:05.000Z" +description: >- + ClusterRoles that grant write permissions over admission webhook should be minimized to reduce powerful identities in the cluster. This policy checks to ensure write permissions are not provided to admission webhooks. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/other/restrict-clusterrole-mutating-validating-admission-webhooks/restrict-clusterrole-mutating-validating-admission-webhooks.yaml + ``` +keywords: +- kyverno +- Other +readme: | + ClusterRoles that grant write permissions over admission webhook should be minimized to reduce powerful identities in the cluster. This policy checks to ensure write permissions are not provided to admission webhooks. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Other" + kyverno/subject: "ClusterRole" +digest: 3ebafd2ea6b0db34271461525d00cb97805c3ba8a97e928db056bb6e65dbf01b diff --git a/other/restrict-clusterrole-mutating-validating-admission-webhooks/restrict-clusterrole-mutating-validating-admission-webhooks.yaml b/other/restrict-clusterrole-mutating-validating-admission-webhooks/restrict-clusterrole-mutating-validating-admission-webhooks.yaml new file mode 100644 index 000000000..f30b96e79 --- /dev/null +++ b/other/restrict-clusterrole-mutating-validating-admission-webhooks/restrict-clusterrole-mutating-validating-admission-webhooks.yaml @@ -0,0 +1,50 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-clusterrole-mutating-validating-admission-webhooks + annotations: + policies.kyverno.io/title: Restrict Clusterrole for Mutating and Validating Admission Webhooks + policies.kyverno.io/category: Other + policies.kyverno.io/severity: medium + kyverno.io/kyverno-version: 1.10.7 + kyverno.io/kubernetes-version: "1.27" + policies.kyverno.io/subject: ClusterRole + policies.kyverno.io/description: >- + ClusterRoles that grant write permissions over admission webhook should be minimized to reduce powerful identities in the cluster. This policy checks to ensure write permissions are not provided to admission webhooks. +spec: + validationFailureAction: Audit + background: true + rules: + - name: restrict-clusterrole + match: + any: + - resources: + kinds: + - ClusterRole + validate: + message: "Use of verbs `create`, `update`, and `patch` are forbidden for mutating and validating admission webhooks" + foreach: + - list: "request.object.rules[]" + deny: + conditions: + all: + - key: "{{ element.apiGroups || '' }}" + operator: AnyIn + value: + - admissionregistration.k8s.io + - key: "{{ element.resources || '' }}" + operator: AnyIn + value: + - mutatingwebhookconfigurations + - validatingwebhookconfigurations + any: + - key: "{{ element.verbs }}" + operator: AnyIn + value: + - create + - update + - patch + - key: "{{ contains(element.verbs[], '*') }}" + operator: Equals + value: true + From b1251132c2911e51bf32bfc63a30fe70d2662d38 Mon Sep 17 00:00:00 2001 From: Chandan-DK Date: Fri, 2 Aug 2024 20:14:48 +0530 Subject: [PATCH 3/4] feat: add miscellaneous policies in CEL expressions - Part 4 (#1033) * copy check-supplemental-groups Signed-off-by: Chandan-DK * convert check-supplemental-groups Signed-off-by: Chandan-DK * copy restrict-adding-capabilities Signed-off-by: Chandan-DK * convert restrict-adding-capabilities Signed-off-by: Chandan-DK * copy restrict-runtimeClassName Signed-off-by: Chandan-DK * convert restrict-runtimeClassName Signed-off-by: Chandan-DK * copy block-velero-restore Signed-off-by: Chandan-DK * convert block-velero-restore Signed-off-by: Chandan-DK * convert block-velero-restore Signed-off-by: Chandan-DK * copy validate-cron-schedule Signed-off-by: Chandan-DK * convert validate-cron-schedule Signed-off-by: Chandan-DK * copy block-tekton-task-runs Signed-off-by: Chandan-DK * add kyverno tests for block-tekton-task-runs Signed-off-by: Chandan-DK * remove unused resources Signed-off-by: Chandan-DK * convert block-tekton-task-runs Signed-off-by: Chandan-DK * copy require-tekton-bundle Signed-off-by: Chandan-DK * add kyverno tests for require-tekton-bundle Signed-off-by: Chandan-DK * convert require-tekton-bundle Signed-off-by: Chandan-DK * copy require-tekton-namespace-pipelinerun Signed-off-by: Chandan-DK * add kyverno tests for require-tekton-namespace-pipelinerun Signed-off-by: Chandan-DK * convert require-tekton-namespace-pipelinerun Signed-off-by: Chandan-DK * rename files for clarity Signed-off-by: Chandan-DK * add CI tests for cel folders Signed-off-by: Chandan-DK * remove require-tekton-namespace-pipelinerun Removing this cel policy because issue https://github.com/kyverno/kyverno/issues/10313 causes CI failure Signed-off-by: Chandan-DK * explicitly specify CREATE and UPDATE operations Signed-off-by: Chandan-DK --------- Signed-off-by: Chandan-DK Signed-off-by: Chandan-DK Co-authored-by: Chip Zoller --- .github/workflows/test.yml | 5 +- .../.chainsaw-test/chainsaw-test.yaml | 38 ++ .../.chainsaw-test/pod-bad.yaml | 55 +++ .../.chainsaw-test/pod-good.yaml | 60 ++++ .../.chainsaw-test/podcontroller-bad.yaml | 42 +++ .../.chainsaw-test/podcontroller-good.yaml | 42 +++ .../.chainsaw-test/policy-ready.yaml | 6 + .../.kyverno-test/kyverno-test.yaml | 21 ++ .../.kyverno-test/resource.yaml | 24 ++ .../artifacthub-pkg.yml | 23 ++ .../check-supplemental-groups.yaml | 39 +++ .../.chainsaw-test/chainsaw-test.yaml | 40 +++ .../.chainsaw-test/pod-bad.yaml | 177 ++++++++++ .../.chainsaw-test/pod-good.yaml | 148 ++++++++ .../.chainsaw-test/podcontroller-bad.yaml | 308 ++++++++++++++++ .../.chainsaw-test/podcontroller-good.yaml | 267 ++++++++++++++ .../.chainsaw-test/policy-ready.yaml | 6 + .../.kyverno-test/kyverno-test.yaml | 39 +++ .../.kyverno-test/resource.yaml | 328 ++++++++++++++++++ .../artifacthub-pkg.yml | 23 ++ .../restrict-adding-capabilities.yaml | 49 +++ .../.chainsaw-test/bad-pods.yaml | 10 + .../.chainsaw-test/chainsaw-test.yaml | 43 +++ .../.chainsaw-test/good-pods.yaml | 31 ++ .../.chainsaw-test/ns.yaml | 4 + .../.chainsaw-test/policy-ready.yaml | 9 + .../.chainsaw-test/runtimeclass-exp.yaml | 5 + .../.chainsaw-test/runtimeclass-foo.yaml | 5 + .../.chainsaw-test/runtimeclass-prod.yaml | 5 + .../.kyverno-test/kyverno-test.yaml | 23 ++ .../.kyverno-test/resource.yaml | 42 +++ .../artifacthub-pkg.yml | 23 ++ .../restrict-runtimeClassName.yaml | 36 ++ .../.chainsaw-test/chainsaw-test.yaml | 33 ++ .../.chainsaw-test/crd-assert.yaml | 12 + .../.chainsaw-test/policy-ready.yaml | 6 + .../.chainsaw-test/taskrun.yaml | 7 + .../.kyverno-test/kyverno-test.yaml | 15 + .../artifacthub-pkg.yml | 23 ++ .../block-tekton-task-runs.yaml | 38 ++ .../.chainsaw-test/bad-pipelinerun.yaml | 18 + .../.chainsaw-test/bad-taskrun.yaml | 7 + .../.chainsaw-test/chainsaw-test.yaml | 44 +++ .../crd-pipelinerun-assert.yaml | 12 + .../.chainsaw-test/crd-taskrun-assert.yaml | 12 + .../.chainsaw-test/good-pipelinerun.yaml | 8 + .../.chainsaw-test/good-taskrun.yaml | 8 + .../.chainsaw-test/policy-ready.yaml | 6 + .../.kyverno-test/kyverno-test.yaml | 37 ++ .../require-tekton-bundle/artifacthub-pkg.yml | 23 ++ .../require-tekton-bundle.yaml | 44 +++ .../.kyverno-test/kyverno-test.yaml | 37 ++ .../.kyverno-test/kyverno-test.yaml | 22 ++ .../.chainsaw-test/bad-restore.yaml | 21 ++ .../.chainsaw-test/chainsaw-test.yaml | 35 ++ .../.chainsaw-test/crd-restore-assert.yaml | 13 + .../.chainsaw-test/good-restore.yaml | 28 ++ .../.chainsaw-test/policy-ready.yaml | 6 + .../.kyverno-test/kyverno-test.yaml | 22 ++ .../.kyverno-test/resource.yaml | 52 +++ .../block-velero-restore/artifacthub-pkg.yml | 31 ++ .../block-velero-restore.yaml | 38 ++ .../.chainsaw-test/bad-schedule.yaml | 19 + .../.chainsaw-test/chainsaw-test.yaml | 35 ++ .../.chainsaw-test/crd-schedule-assert.yaml | 13 + .../.chainsaw-test/good-schedule.yaml | 11 + .../.chainsaw-test/policy-ready.yaml | 6 + .../.kyverno-test/kyverno-test.yaml | 21 ++ .../.kyverno-test/resources.yaml | 20 ++ .../artifacthub-pkg.yml | 25 ++ .../validate-cron-schedule.yaml | 33 ++ 71 files changed, 2816 insertions(+), 1 deletion(-) create mode 100755 psp-migration-cel/check-supplemental-groups/.chainsaw-test/chainsaw-test.yaml create mode 100644 psp-migration-cel/check-supplemental-groups/.chainsaw-test/pod-bad.yaml create mode 100644 psp-migration-cel/check-supplemental-groups/.chainsaw-test/pod-good.yaml create mode 100644 psp-migration-cel/check-supplemental-groups/.chainsaw-test/podcontroller-bad.yaml create mode 100644 psp-migration-cel/check-supplemental-groups/.chainsaw-test/podcontroller-good.yaml create mode 100755 psp-migration-cel/check-supplemental-groups/.chainsaw-test/policy-ready.yaml create mode 100644 psp-migration-cel/check-supplemental-groups/.kyverno-test/kyverno-test.yaml create mode 100644 psp-migration-cel/check-supplemental-groups/.kyverno-test/resource.yaml create mode 100644 psp-migration-cel/check-supplemental-groups/artifacthub-pkg.yml create mode 100644 psp-migration-cel/check-supplemental-groups/check-supplemental-groups.yaml create mode 100755 psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/chainsaw-test.yaml create mode 100644 psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/pod-bad.yaml create mode 100644 psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/pod-good.yaml create mode 100644 psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/podcontroller-bad.yaml create mode 100644 psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/podcontroller-good.yaml create mode 100755 psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/policy-ready.yaml create mode 100644 psp-migration-cel/restrict-adding-capabilities/.kyverno-test/kyverno-test.yaml create mode 100644 psp-migration-cel/restrict-adding-capabilities/.kyverno-test/resource.yaml create mode 100644 psp-migration-cel/restrict-adding-capabilities/artifacthub-pkg.yml create mode 100644 psp-migration-cel/restrict-adding-capabilities/restrict-adding-capabilities.yaml create mode 100644 psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/bad-pods.yaml create mode 100755 psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/chainsaw-test.yaml create mode 100644 psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/good-pods.yaml create mode 100755 psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/ns.yaml create mode 100644 psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/policy-ready.yaml create mode 100755 psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/runtimeclass-exp.yaml create mode 100755 psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/runtimeclass-foo.yaml create mode 100755 psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/runtimeclass-prod.yaml create mode 100644 psp-migration-cel/restrict-runtimeClassName/.kyverno-test/kyverno-test.yaml create mode 100644 psp-migration-cel/restrict-runtimeClassName/.kyverno-test/resource.yaml create mode 100644 psp-migration-cel/restrict-runtimeClassName/artifacthub-pkg.yml create mode 100644 psp-migration-cel/restrict-runtimeClassName/restrict-runtimeClassName.yaml create mode 100755 tekton-cel/block-tekton-task-runs/.chainsaw-test/chainsaw-test.yaml create mode 100755 tekton-cel/block-tekton-task-runs/.chainsaw-test/crd-assert.yaml create mode 100755 tekton-cel/block-tekton-task-runs/.chainsaw-test/policy-ready.yaml create mode 100644 tekton-cel/block-tekton-task-runs/.chainsaw-test/taskrun.yaml create mode 100644 tekton-cel/block-tekton-task-runs/.kyverno-test/kyverno-test.yaml create mode 100644 tekton-cel/block-tekton-task-runs/artifacthub-pkg.yml create mode 100644 tekton-cel/block-tekton-task-runs/block-tekton-task-runs.yaml create mode 100644 tekton-cel/require-tekton-bundle/.chainsaw-test/bad-pipelinerun.yaml create mode 100644 tekton-cel/require-tekton-bundle/.chainsaw-test/bad-taskrun.yaml create mode 100755 tekton-cel/require-tekton-bundle/.chainsaw-test/chainsaw-test.yaml create mode 100755 tekton-cel/require-tekton-bundle/.chainsaw-test/crd-pipelinerun-assert.yaml create mode 100755 tekton-cel/require-tekton-bundle/.chainsaw-test/crd-taskrun-assert.yaml create mode 100644 tekton-cel/require-tekton-bundle/.chainsaw-test/good-pipelinerun.yaml create mode 100644 tekton-cel/require-tekton-bundle/.chainsaw-test/good-taskrun.yaml create mode 100755 tekton-cel/require-tekton-bundle/.chainsaw-test/policy-ready.yaml create mode 100644 tekton-cel/require-tekton-bundle/.kyverno-test/kyverno-test.yaml create mode 100644 tekton-cel/require-tekton-bundle/artifacthub-pkg.yml create mode 100644 tekton-cel/require-tekton-bundle/require-tekton-bundle.yaml create mode 100644 tekton/require-tekton-bundle/.kyverno-test/kyverno-test.yaml create mode 100644 tekton/require-tekton-namespace-pipelinerun/.kyverno-test/kyverno-test.yaml create mode 100644 velero-cel/block-velero-restore/.chainsaw-test/bad-restore.yaml create mode 100755 velero-cel/block-velero-restore/.chainsaw-test/chainsaw-test.yaml create mode 100755 velero-cel/block-velero-restore/.chainsaw-test/crd-restore-assert.yaml create mode 100644 velero-cel/block-velero-restore/.chainsaw-test/good-restore.yaml create mode 100755 velero-cel/block-velero-restore/.chainsaw-test/policy-ready.yaml create mode 100644 velero-cel/block-velero-restore/.kyverno-test/kyverno-test.yaml create mode 100644 velero-cel/block-velero-restore/.kyverno-test/resource.yaml create mode 100644 velero-cel/block-velero-restore/artifacthub-pkg.yml create mode 100644 velero-cel/block-velero-restore/block-velero-restore.yaml create mode 100644 velero-cel/validate-cron-schedule/.chainsaw-test/bad-schedule.yaml create mode 100755 velero-cel/validate-cron-schedule/.chainsaw-test/chainsaw-test.yaml create mode 100755 velero-cel/validate-cron-schedule/.chainsaw-test/crd-schedule-assert.yaml create mode 100644 velero-cel/validate-cron-schedule/.chainsaw-test/good-schedule.yaml create mode 100755 velero-cel/validate-cron-schedule/.chainsaw-test/policy-ready.yaml create mode 100644 velero-cel/validate-cron-schedule/.kyverno-test/kyverno-test.yaml create mode 100644 velero-cel/validate-cron-schedule/.kyverno-test/resources.yaml create mode 100644 velero-cel/validate-cron-schedule/artifacthub-pkg.yml create mode 100644 velero-cel/validate-cron-schedule/validate-cron-schedule.yaml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8c78461b7..be3ccbb61 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -57,9 +57,12 @@ jobs: - ^pod-security$ - ^psa$ - ^psp-migration$ + - ^psp-migration-cel$ - ^tekton$ + - ^tekton-cel$ - ^traefik$ - ^velero$ + - ^velero-cel$ runs-on: ubuntu-latest name: ${{ matrix.k8s-version.name }} - ${{ matrix.tests }} steps: @@ -72,4 +75,4 @@ jobs: - name: Run Tests uses: ./.github/actions/run-tests with: - tests: ${{ matrix.tests }} \ No newline at end of file + tests: ${{ matrix.tests }} diff --git a/psp-migration-cel/check-supplemental-groups/.chainsaw-test/chainsaw-test.yaml b/psp-migration-cel/check-supplemental-groups/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..2d0f56c6b --- /dev/null +++ b/psp-migration-cel/check-supplemental-groups/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,38 @@ +# 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: check-supplemental-groups +spec: + steps: + - name: step-01 + try: + - apply: + file: ../check-supplemental-groups.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: psp-check-supplemental-groups + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: pod-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: pod-bad.yaml + - apply: + file: podcontroller-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: podcontroller-bad.yaml diff --git a/psp-migration-cel/check-supplemental-groups/.chainsaw-test/pod-bad.yaml b/psp-migration-cel/check-supplemental-groups/.chainsaw-test/pod-bad.yaml new file mode 100644 index 000000000..295f13ed2 --- /dev/null +++ b/psp-migration-cel/check-supplemental-groups/.chainsaw-test/pod-bad.yaml @@ -0,0 +1,55 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 +spec: + securityContext: + supplementalGroups: + - 120 + - 230 + - 550 + containers: + - name: busybox01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod02 +spec: + securityContext: + supplementalGroups: + - 1000 + - 120 + containers: + - name: busybox01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod03 +spec: + securityContext: + runAsGroup: 0 + supplementalGroups: + - 580 + - 0 + containers: + - name: busybox01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod04 +spec: + securityContext: + supplementalGroups: + - 100 + - 601 + - 600 + runAsGroup: 0 + containers: + - name: busybox01 + image: busybox:1.35 \ No newline at end of file diff --git a/psp-migration-cel/check-supplemental-groups/.chainsaw-test/pod-good.yaml b/psp-migration-cel/check-supplemental-groups/.chainsaw-test/pod-good.yaml new file mode 100644 index 000000000..ccdb66190 --- /dev/null +++ b/psp-migration-cel/check-supplemental-groups/.chainsaw-test/pod-good.yaml @@ -0,0 +1,60 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 +spec: + containers: + - name: busybox01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod02 +spec: + securityContext: + supplementalGroups: + - 150 + - 100 + - 500 + containers: + - name: busybox01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod03 +spec: + securityContext: + supplementalGroups: + - 550 + - 600 + - 120 + containers: + - name: busybox01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod04 +spec: + securityContext: + runAsGroup: 0 + containers: + - name: busybox01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod05 +spec: + securityContext: + supplementalGroups: + - 600 + runAsGroup: 0 + containers: + - name: busybox01 + image: busybox:1.35 \ No newline at end of file diff --git a/psp-migration-cel/check-supplemental-groups/.chainsaw-test/podcontroller-bad.yaml b/psp-migration-cel/check-supplemental-groups/.chainsaw-test/podcontroller-bad.yaml new file mode 100644 index 000000000..da4768b78 --- /dev/null +++ b/psp-migration-cel/check-supplemental-groups/.chainsaw-test/podcontroller-bad.yaml @@ -0,0 +1,42 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: baddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + securityContext: + supplementalGroups: + - 100 + - 601 + - 600 + runAsGroup: 0 + containers: + - name: busybox01 + image: busybox:1.35 +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob01 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + securityContext: + supplementalGroups: + - 1000 + - 120 + containers: + - name: busybox01 + image: busybox:1.35 \ No newline at end of file diff --git a/psp-migration-cel/check-supplemental-groups/.chainsaw-test/podcontroller-good.yaml b/psp-migration-cel/check-supplemental-groups/.chainsaw-test/podcontroller-good.yaml new file mode 100644 index 000000000..cbb26cae5 --- /dev/null +++ b/psp-migration-cel/check-supplemental-groups/.chainsaw-test/podcontroller-good.yaml @@ -0,0 +1,42 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gooddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + securityContext: + supplementalGroups: + - 150 + - 100 + - 500 + containers: + - name: busybox01 + image: busybox:1.35 +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob01 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + securityContext: + supplementalGroups: + - 550 + - 600 + - 120 + containers: + - name: busybox01 + image: busybox:1.35 \ No newline at end of file diff --git a/psp-migration-cel/check-supplemental-groups/.chainsaw-test/policy-ready.yaml b/psp-migration-cel/check-supplemental-groups/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..d68e9bb1c --- /dev/null +++ b/psp-migration-cel/check-supplemental-groups/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: psp-check-supplemental-groups +status: + ready: true diff --git a/psp-migration-cel/check-supplemental-groups/.kyverno-test/kyverno-test.yaml b/psp-migration-cel/check-supplemental-groups/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..35f4b1eb9 --- /dev/null +++ b/psp-migration-cel/check-supplemental-groups/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,21 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: psp-check-supplemental-groups +policies: +- ../check-supplemental-groups.yaml +resources: +- resource.yaml +results: +- kind: Pod + policy: psp-check-supplemental-groups + resources: + - badpod01 + result: fail + rule: supplementalgroup-ranges +- kind: Pod + policy: psp-check-supplemental-groups + resources: + - goodpod01 + result: pass + rule: supplementalgroup-ranges diff --git a/psp-migration-cel/check-supplemental-groups/.kyverno-test/resource.yaml b/psp-migration-cel/check-supplemental-groups/.kyverno-test/resource.yaml new file mode 100644 index 000000000..d7c4dc51f --- /dev/null +++ b/psp-migration-cel/check-supplemental-groups/.kyverno-test/resource.yaml @@ -0,0 +1,24 @@ +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 +spec: + containers: + - name: container01 + image: dummyimagename + securityContext: + supplementalGroups: + - 0 +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 +spec: + containers: + - name: container01 + image: dummyimagename + securityContext: + supplementalGroups: + - 100 diff --git a/psp-migration-cel/check-supplemental-groups/artifacthub-pkg.yml b/psp-migration-cel/check-supplemental-groups/artifacthub-pkg.yml new file mode 100644 index 000000000..7717aebbe --- /dev/null +++ b/psp-migration-cel/check-supplemental-groups/artifacthub-pkg.yml @@ -0,0 +1,23 @@ +name: check-supplemental-groups-cel +version: 1.0.0 +displayName: Check supplementalGroups in CEL expressions +description: >- + Supplemental groups control which group IDs containers add and can coincide with restricted groups on the host. Pod Security Policies (PSP) allowed a range of these group IDs to be specified which were allowed. This policy ensures any Pod may only specify supplementalGroup IDs between 100-200 or 500-600. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/psp-migration-cel/check-supplemental-groups/check-supplemental-groups.yaml + ``` +keywords: + - kyverno + - PSP Migration + - CEL Expressions +readme: | + Supplemental groups control which group IDs containers add and can coincide with restricted groups on the host. Pod Security Policies (PSP) allowed a range of these group IDs to be specified which were allowed. This policy ensures any Pod may only specify supplementalGroup IDs between 100-200 or 500-600. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "PSP Migration in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Pod" +digest: 05135ed92926031b15d782552af3f8dbf8776014401328e186987344079fcc66 +createdAt: "2024-05-23T13:57:56Z" diff --git a/psp-migration-cel/check-supplemental-groups/check-supplemental-groups.yaml b/psp-migration-cel/check-supplemental-groups/check-supplemental-groups.yaml new file mode 100644 index 000000000..461920574 --- /dev/null +++ b/psp-migration-cel/check-supplemental-groups/check-supplemental-groups.yaml @@ -0,0 +1,39 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: psp-check-supplemental-groups + annotations: + policies.kyverno.io/title: Check supplementalGroups in CEL expressions + policies.kyverno.io/category: PSP Migration in CEL + policies.kyverno.io/severity: medium + kyverno.io/kyverno-version: 1.11.0 + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/subject: Pod + policies.kyverno.io/description: >- + Supplemental groups control which group IDs containers add and can coincide with + restricted groups on the host. Pod Security Policies (PSP) allowed a range of + these group IDs to be specified which were allowed. This policy ensures any Pod + may only specify supplementalGroup IDs between 100-200 or 500-600. +spec: + background: false + validationFailureAction: Audit + rules: + - name: supplementalgroup-ranges + match: + any: + - resources: + kinds: + - Pod + operations: + - CREATE + - UPDATE + validate: + cel: + expressions: + - expression: >- + !has(object.spec.securityContext) || + !has(object.spec.securityContext.supplementalGroups) || + object.spec.securityContext.supplementalGroups.all(supplementalGroup, (supplementalGroup >= 100 && supplementalGroup <= 200) || (supplementalGroup >= 500 && supplementalGroup <= 600)) + message: Any supplementalGroup ID must be within the range 100-200 or 500-600. + diff --git a/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/chainsaw-test.yaml b/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..537dcecd5 --- /dev/null +++ b/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,40 @@ +# 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-adding-capabilities +spec: + # disable templating because it can cause issues with CEL expressions + template: false + steps: + - name: step-01 + try: + - apply: + file: ../restrict-adding-capabilities.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: psp-restrict-adding-capabilities + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: pod-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: pod-bad.yaml + - apply: + file: podcontroller-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: podcontroller-bad.yaml diff --git a/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/pod-bad.yaml b/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/pod-bad.yaml new file mode 100644 index 000000000..9d97c06bf --- /dev/null +++ b/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/pod-bad.yaml @@ -0,0 +1,177 @@ +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod01 +spec: + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CHOWN +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod02 +spec: + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CHOWN + - NET_BIND_SERVICE +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod03 +spec: + containers: + - name: container01 + image: busybox:1.35 + - name: container02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CHOWN +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod04 +spec: + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + - name: container02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CHOWN +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod05 +spec: + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + - name: container02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CHOWN + - NET_BIND_SERVICE +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod06 +spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CHOWN + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod07 +spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CHOWN + - NET_BIND_SERVICE + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod08 +spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + - name: initcontainer02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CHOWN + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod09 +spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + - name: initcontainer02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CHOWN + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod10 +spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + - name: initcontainer02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CHOWN + - NET_BIND_SERVICE + containers: + - name: container01 + image: busybox:1.35 +--- \ No newline at end of file diff --git a/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/pod-good.yaml b/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/pod-good.yaml new file mode 100644 index 000000000..8b77e2a79 --- /dev/null +++ b/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/pod-good.yaml @@ -0,0 +1,148 @@ +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod01 +spec: + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod02 +spec: + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod03 +spec: + containers: + - name: container01 + image: busybox:1.35 + - name: container02 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod04 +spec: + containers: + - name: container01 + image: busybox:1.35 + - name: container02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod05 +spec: + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + - name: container02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod06 +spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod07 +spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod08 +spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + - name: initcontainer02 + image: busybox:1.35 + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod09 +spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + - name: initcontainer02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod10 +spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + - name: initcontainer02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + containers: + - name: container01 + image: busybox:1.35 diff --git a/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/podcontroller-bad.yaml b/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/podcontroller-bad.yaml new file mode 100644 index 000000000..4037cb574 --- /dev/null +++ b/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/podcontroller-bad.yaml @@ -0,0 +1,308 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: baddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_RAW +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: baddeployment02 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_RAW + - CAP_CHOWN +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: baddeployment03 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_RAW + - name: container02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CAP_CHOWN +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: baddeployment04 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_RAW + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CAP_CHOWN +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: baddeployment05 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + - name: initcontainer02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_RAW + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CAP_CHOWN +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: baddeployment06 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_RAW + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - SYS_ADMIN +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob01 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_RAW +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob02 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_RAW + - NET_BIND_SERVICE +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob03 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_RAW + - name: container02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob04 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + initContainers: + - name: initcontainer01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_RAW + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + - CAP_CHOWN +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob05 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + initContainers: + - name: initcontainer01 + image: busybox:1.35 + - name: initcontainer02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_RAW + - CAP_CHOWN + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - SETGID +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob06 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + initContainers: + - name: initcontainer01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_RAW + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - SYS_ADMIN +--- \ No newline at end of file diff --git a/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/podcontroller-good.yaml b/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/podcontroller-good.yaml new file mode 100644 index 000000000..8daee6250 --- /dev/null +++ b/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/podcontroller-good.yaml @@ -0,0 +1,267 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gooddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gooddeployment02 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gooddeployment03 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CAP_CHOWN + - name: container02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gooddeployment04 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gooddeployment05 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CAP_CHOWN + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gooddeployment06 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CAP_CHOWN +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob01 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob02 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CAP_CHOWN +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob03 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + - name: container02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CAP_CHOWN +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob04 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + initContainers: + - name: initcontainer01 + image: busybox:1.35 + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob05 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + initContainers: + - name: initcontainer01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob06 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + initContainers: + - name: initcontainer01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CAP_CHOWN diff --git a/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/policy-ready.yaml b/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..e870f077e --- /dev/null +++ b/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: psp-restrict-adding-capabilities +status: + ready: true diff --git a/psp-migration-cel/restrict-adding-capabilities/.kyverno-test/kyverno-test.yaml b/psp-migration-cel/restrict-adding-capabilities/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..4c94d8b92 --- /dev/null +++ b/psp-migration-cel/restrict-adding-capabilities/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,39 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: psp-restrict-adding-capabilities +policies: +- ../restrict-adding-capabilities.yaml +resources: +- resource.yaml +results: +- kind: Pod + policy: psp-restrict-adding-capabilities + resources: + - addcap-badpod01 + - addcap-badpod02 + - addcap-badpod03 + - addcap-badpod04 + - addcap-badpod05 + - addcap-badpod06 + - addcap-badpod07 + - addcap-badpod08 + - addcap-badpod09 + - addcap-badpod10 + result: fail + rule: allowed-capabilities +- kind: Pod + policy: psp-restrict-adding-capabilities + resources: + - addcap-goodpod01 + - addcap-goodpod02 + - addcap-goodpod03 + - addcap-goodpod04 + - addcap-goodpod05 + - addcap-goodpod06 + - addcap-goodpod07 + - addcap-goodpod08 + - addcap-goodpod09 + - addcap-goodpod10 + result: pass + rule: allowed-capabilities diff --git a/psp-migration-cel/restrict-adding-capabilities/.kyverno-test/resource.yaml b/psp-migration-cel/restrict-adding-capabilities/.kyverno-test/resource.yaml new file mode 100644 index 000000000..af86fceb7 --- /dev/null +++ b/psp-migration-cel/restrict-adding-capabilities/.kyverno-test/resource.yaml @@ -0,0 +1,328 @@ +###### Pods - Bad +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod01 +spec: + containers: + - name: container01 + image: dummyimagename + securityContext: + capabilities: + add: + - CHOWN +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod02 +spec: + containers: + - name: container01 + image: dummyimagename + securityContext: + capabilities: + add: + - CHOWN + - NET_BIND_SERVICE +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod03 +spec: + containers: + - name: container01 + image: dummyimagename + - name: container02 + image: dummyimagename + securityContext: + capabilities: + add: + - CHOWN +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod04 +spec: + containers: + - name: container01 + image: dummyimagename + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + - name: container02 + image: dummyimagename + securityContext: + capabilities: + add: + - CHOWN +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod05 +spec: + containers: + - name: container01 + image: dummyimagename + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + - name: container02 + image: dummyimagename + securityContext: + capabilities: + add: + - CHOWN + - NET_BIND_SERVICE +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod06 +spec: + initContainers: + - name: initcontainer01 + image: dummyimagename + securityContext: + capabilities: + add: + - CHOWN + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod07 +spec: + initContainers: + - name: initcontainer01 + image: dummyimagename + securityContext: + capabilities: + add: + - CHOWN + - NET_BIND_SERVICE + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod08 +spec: + initContainers: + - name: initcontainer01 + image: dummyimagename + - name: initcontainer02 + image: dummyimagename + securityContext: + capabilities: + add: + - CHOWN + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod09 +spec: + initContainers: + - name: initcontainer01 + image: dummyimagename + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + - name: initcontainer02 + image: dummyimagename + securityContext: + capabilities: + add: + - CHOWN + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod10 +spec: + initContainers: + - name: initcontainer01 + image: dummyimagename + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + - name: initcontainer02 + image: dummyimagename + securityContext: + capabilities: + add: + - CHOWN + - NET_BIND_SERVICE + containers: + - name: container01 + image: dummyimagename +--- +###### Pods - Good +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod01 +spec: + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod02 +spec: + containers: + - name: container01 + image: dummyimagename + securityContext: + capabilities: + add: + - NET_BIND_SERVICE +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod03 +spec: + containers: + - name: container01 + image: dummyimagename + - name: container02 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod04 +spec: + containers: + - name: container01 + image: dummyimagename + - name: container02 + image: dummyimagename + securityContext: + capabilities: + add: + - NET_BIND_SERVICE +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod05 +spec: + containers: + - name: container01 + image: dummyimagename + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + - name: container02 + image: dummyimagename + securityContext: + capabilities: + add: + - NET_BIND_SERVICE +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod06 +spec: + initContainers: + - name: initcontainer01 + image: dummyimagename + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod07 +spec: + initContainers: + - name: initcontainer01 + image: dummyimagename + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod08 +spec: + initContainers: + - name: initcontainer01 + image: dummyimagename + - name: initcontainer02 + image: dummyimagename + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod09 +spec: + initContainers: + - name: initcontainer01 + image: dummyimagename + - name: initcontainer02 + image: dummyimagename + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod10 +spec: + initContainers: + - name: initcontainer01 + image: dummyimagename + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + - name: initcontainer02 + image: dummyimagename + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + containers: + - name: container01 + image: dummyimagename diff --git a/psp-migration-cel/restrict-adding-capabilities/artifacthub-pkg.yml b/psp-migration-cel/restrict-adding-capabilities/artifacthub-pkg.yml new file mode 100644 index 000000000..19ded7cb5 --- /dev/null +++ b/psp-migration-cel/restrict-adding-capabilities/artifacthub-pkg.yml @@ -0,0 +1,23 @@ +name: restrict-adding-capabilities-cel +version: 1.0.0 +displayName: Restrict Adding Capabilities in CEL expressions +description: >- + Adding capabilities is a way for containers in a Pod to request higher levels of ability than those with which they may be provisioned. Many capabilities allow system-level control and should be prevented. Pod Security Policies (PSP) allowed a list of "good" capabilities to be added. This policy checks ephemeralContainers, initContainers, and containers to ensure the only capabilities that can be added are either NET_BIND_SERVICE or CAP_CHOWN. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/psp-migration-cel/restrict-adding-capabilities/restrict-adding-capabilities.yaml + ``` +keywords: + - kyverno + - PSP Migration + - CEL Expressions +readme: | + Adding capabilities is a way for containers in a Pod to request higher levels of ability than those with which they may be provisioned. Many capabilities allow system-level control and should be prevented. Pod Security Policies (PSP) allowed a list of "good" capabilities to be added. This policy checks ephemeralContainers, initContainers, and containers to ensure the only capabilities that can be added are either NET_BIND_SERVICE or CAP_CHOWN. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "PSP Migration in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Pod" +digest: a577515c97fa6c2990de6bc88df222e1555bf11bfacdf00e31b26c5c5fb086ac +createdAt: "2024-05-23T14:18:49Z" diff --git a/psp-migration-cel/restrict-adding-capabilities/restrict-adding-capabilities.yaml b/psp-migration-cel/restrict-adding-capabilities/restrict-adding-capabilities.yaml new file mode 100644 index 000000000..1d9f54494 --- /dev/null +++ b/psp-migration-cel/restrict-adding-capabilities/restrict-adding-capabilities.yaml @@ -0,0 +1,49 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: psp-restrict-adding-capabilities + annotations: + policies.kyverno.io/title: Restrict Adding Capabilities in CEL expressions + policies.kyverno.io/category: PSP Migration in CEL + policies.kyverno.io/severity: medium + kyverno.io/kyverno-version: 1.11.0 + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/subject: Pod + policies.kyverno.io/description: >- + Adding capabilities is a way for containers in a Pod to request higher levels + of ability than those with which they may be provisioned. Many capabilities + allow system-level control and should be prevented. Pod Security Policies (PSP) + allowed a list of "good" capabilities to be added. This policy checks + ephemeralContainers, initContainers, and containers to ensure the only + capabilities that can be added are either NET_BIND_SERVICE or CAP_CHOWN. +spec: + validationFailureAction: Audit + background: true + rules: + - name: allowed-capabilities + match: + any: + - resources: + kinds: + - Pod + operations: + - CREATE + - UPDATE + validate: + cel: + variables: + - name: allContainers + expression: "(object.spec.containers + (has(object.spec.initContainers) ? object.spec.initContainers : []) + (has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []))" + - name: allowedCapabilities + expression: "['NET_BIND_SERVICE', 'CAP_CHOWN']" + expressions: + - expression: >- + variables.allContainers.all(container, + !has(container.securityContext) || + !has(container.securityContext.capabilities) || + !has(container.securityContext.capabilities.add) || + container.securityContext.capabilities.add.all(capability, capability in variables.allowedCapabilities)) + message: >- + Any capabilities added other than NET_BIND_SERVICE or CAP_CHOWN are disallowed. + diff --git a/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/bad-pods.yaml b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/bad-pods.yaml new file mode 100644 index 000000000..6dee8ab8a --- /dev/null +++ b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/bad-pods.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 + namespace: restrict-runtimeclassname +spec: + runtimeClassName: fooclass + containers: + - name: container01 + image: dummyimagename \ No newline at end of file diff --git a/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/chainsaw-test.yaml b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..e42476abe --- /dev/null +++ b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,43 @@ +# 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-runtimeclassname +spec: + steps: + - name: step-00 + try: + - apply: + file: ../restrict-runtimeClassName.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: restrict-runtimeclass + spec: + validationFailureAction: Enforce + - name: step-01 + try: + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: ns.yaml + - apply: + file: runtimeclass-prod.yaml + - apply: + file: runtimeclass-exp.yaml + - apply: + file: runtimeclass-foo.yaml + - name: step-03 + try: + - apply: + file: good-pods.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-pods.yaml diff --git a/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/good-pods.yaml b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/good-pods.yaml new file mode 100644 index 000000000..475c030e4 --- /dev/null +++ b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/good-pods.yaml @@ -0,0 +1,31 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 + namespace: restrict-runtimeclassname +spec: + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod02 + namespace: restrict-runtimeclassname +spec: + runtimeClassName: expclass + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod03 + namespace: restrict-runtimeclassname +spec: + runtimeClassName: prodclass + containers: + - name: container01 + image: dummyimagename diff --git a/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/ns.yaml b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/ns.yaml new file mode 100755 index 000000000..121c85370 --- /dev/null +++ b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/ns.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: restrict-runtimeclassname diff --git a/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/policy-ready.yaml b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/policy-ready.yaml new file mode 100644 index 000000000..126968a0f --- /dev/null +++ b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-runtimeclass +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready \ No newline at end of file diff --git a/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/runtimeclass-exp.yaml b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/runtimeclass-exp.yaml new file mode 100755 index 000000000..0318454a0 --- /dev/null +++ b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/runtimeclass-exp.yaml @@ -0,0 +1,5 @@ +apiVersion: node.k8s.io/v1 +handler: expconfig +kind: RuntimeClass +metadata: + name: expclass diff --git a/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/runtimeclass-foo.yaml b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/runtimeclass-foo.yaml new file mode 100755 index 000000000..6d03f568e --- /dev/null +++ b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/runtimeclass-foo.yaml @@ -0,0 +1,5 @@ +apiVersion: node.k8s.io/v1 +handler: fooconfig +kind: RuntimeClass +metadata: + name: fooclass diff --git a/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/runtimeclass-prod.yaml b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/runtimeclass-prod.yaml new file mode 100755 index 000000000..5616c1916 --- /dev/null +++ b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/runtimeclass-prod.yaml @@ -0,0 +1,5 @@ +apiVersion: node.k8s.io/v1 +handler: prodconfig +kind: RuntimeClass +metadata: + name: prodclass diff --git a/psp-migration-cel/restrict-runtimeClassName/.kyverno-test/kyverno-test.yaml b/psp-migration-cel/restrict-runtimeClassName/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..faa23c777 --- /dev/null +++ b/psp-migration-cel/restrict-runtimeClassName/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,23 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: restrict-runtimeclass +policies: +- ../restrict-runtimeClassName.yaml +resources: +- resource.yaml +results: +- kind: Pod + policy: restrict-runtimeclass + resources: + - badpod01 + result: fail + rule: prodclass-or-expclass +- kind: Pod + policy: restrict-runtimeclass + resources: + - goodpod01 + - goodpod02 + - goodpod03 + result: pass + rule: prodclass-or-expclass diff --git a/psp-migration-cel/restrict-runtimeClassName/.kyverno-test/resource.yaml b/psp-migration-cel/restrict-runtimeClassName/.kyverno-test/resource.yaml new file mode 100644 index 000000000..2820962a2 --- /dev/null +++ b/psp-migration-cel/restrict-runtimeClassName/.kyverno-test/resource.yaml @@ -0,0 +1,42 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 + namespace: restrict-runtimeclassname +spec: + runtimeClassName: fooclass + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 + namespace: restrict-runtimeclassname +spec: + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod02 + namespace: restrict-runtimeclassname +spec: + runtimeClassName: expclass + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod03 + namespace: restrict-runtimeclassname +spec: + runtimeClassName: prodclass + containers: + - name: container01 + image: dummyimagename diff --git a/psp-migration-cel/restrict-runtimeClassName/artifacthub-pkg.yml b/psp-migration-cel/restrict-runtimeClassName/artifacthub-pkg.yml new file mode 100644 index 000000000..08f856608 --- /dev/null +++ b/psp-migration-cel/restrict-runtimeClassName/artifacthub-pkg.yml @@ -0,0 +1,23 @@ +name: restrict-runtimeclass-cel +version: 1.0.0 +displayName: Restrict runtimeClass in CEL expressions +description: >- + The runtimeClass field of a Pod spec defines which container engine runtime should be used. In the previous Pod Security Policy controller, defining restrictions on which classes were allowed was permitted. Limiting runtime classes to only those which have been defined can prevent unintended running states or Pods which may not come online. This policy restricts the runtimeClass field to the values `prodclass` or `expclass`. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/psp-migration-cel/restrict-runtimeClassName/restrict-runtimeClassName.yaml + ``` +keywords: + - kyverno + - PSP Migration + - CEL Expressions +readme: | + The runtimeClass field of a Pod spec defines which container engine runtime should be used. In the previous Pod Security Policy controller, defining restrictions on which classes were allowed was permitted. Limiting runtime classes to only those which have been defined can prevent unintended running states or Pods which may not come online. This policy restricts the runtimeClass field to the values `prodclass` or `expclass`. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "PSP Migration in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Pod" +digest: 7bbfbc460b7977c74d198e76f96419f6415141ad08f53819f6c3643b9e1e7ab0 +createdAt: "2024-05-23T14:25:37Z" diff --git a/psp-migration-cel/restrict-runtimeClassName/restrict-runtimeClassName.yaml b/psp-migration-cel/restrict-runtimeClassName/restrict-runtimeClassName.yaml new file mode 100644 index 000000000..1dd8abbc8 --- /dev/null +++ b/psp-migration-cel/restrict-runtimeClassName/restrict-runtimeClassName.yaml @@ -0,0 +1,36 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-runtimeclass + annotations: + policies.kyverno.io/title: Restrict runtimeClass in CEL expressions + policies.kyverno.io/category: PSP Migration in CEL + policies.kyverno.io/subject: Pod + kyverno.io/kyverno-version: 1.12.1 + kyverno.io/kubernetes-version: "1.26-1.27" + pod-policies.kyverno.io/autogen-controllers: none + policies.kyverno.io/description: >- + The runtimeClass field of a Pod spec defines which container engine runtime should be used. + In the previous Pod Security Policy controller, defining restrictions on which classes were allowed + was permitted. Limiting runtime classes to only those which have been defined can prevent + unintended running states or Pods which may not come online. This policy restricts the runtimeClass + field to the values `prodclass` or `expclass`. +spec: + validationFailureAction: Enforce + background: false + rules: + - name: prodclass-or-expclass + match: + any: + - resources: + kinds: + - Pod + celPreconditions: + - name: "operation-should-be-create" + expression: "request.operation == 'CREATE'" + validate: + cel: + expressions: + - expression: "!has(object.spec.runtimeClassName) || object.spec.runtimeClassName in ['prodclass', 'expclass']" + message: Only the runtime classes prodclass or expclass may be used. + diff --git a/tekton-cel/block-tekton-task-runs/.chainsaw-test/chainsaw-test.yaml b/tekton-cel/block-tekton-task-runs/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..c89a2230e --- /dev/null +++ b/tekton-cel/block-tekton-task-runs/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,33 @@ +# 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: block-tekton-task-runs +spec: + steps: + - name: step-00 + try: + - assert: + file: crd-assert.yaml + - name: step-01 + try: + - apply: + file: ../block-tekton-task-runs.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: block-tekton-task-runs + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + expect: + - check: + ($error != null): true + file: taskrun.yaml diff --git a/tekton-cel/block-tekton-task-runs/.chainsaw-test/crd-assert.yaml b/tekton-cel/block-tekton-task-runs/.chainsaw-test/crd-assert.yaml new file mode 100755 index 000000000..2934ff501 --- /dev/null +++ b/tekton-cel/block-tekton-task-runs/.chainsaw-test/crd-assert.yaml @@ -0,0 +1,12 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: taskruns.tekton.dev +spec: {} +status: + acceptedNames: + kind: TaskRun + plural: taskruns + singular: taskrun + storedVersions: + - v1 diff --git a/tekton-cel/block-tekton-task-runs/.chainsaw-test/policy-ready.yaml b/tekton-cel/block-tekton-task-runs/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..ca24ce66c --- /dev/null +++ b/tekton-cel/block-tekton-task-runs/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: block-tekton-task-runs +status: + ready: true diff --git a/tekton-cel/block-tekton-task-runs/.chainsaw-test/taskrun.yaml b/tekton-cel/block-tekton-task-runs/.chainsaw-test/taskrun.yaml new file mode 100644 index 000000000..d25f69cb0 --- /dev/null +++ b/tekton-cel/block-tekton-task-runs/.chainsaw-test/taskrun.yaml @@ -0,0 +1,7 @@ +apiVersion: tekton.dev/v1 +kind: TaskRun +metadata: + name: taskrun01 +spec: + taskRef: + name: read-task \ No newline at end of file diff --git a/tekton-cel/block-tekton-task-runs/.kyverno-test/kyverno-test.yaml b/tekton-cel/block-tekton-task-runs/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..f98351850 --- /dev/null +++ b/tekton-cel/block-tekton-task-runs/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,15 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: block-tekton-task-runs +policies: +- ../block-tekton-task-runs.yaml +resources: +- ../.chainsaw-test/taskrun.yaml +results: +- policy: block-tekton-task-runs + rule: check-taskrun-user + kind: TaskRun + resources: + - taskrun01 + result: fail diff --git a/tekton-cel/block-tekton-task-runs/artifacthub-pkg.yml b/tekton-cel/block-tekton-task-runs/artifacthub-pkg.yml new file mode 100644 index 000000000..20a5fe972 --- /dev/null +++ b/tekton-cel/block-tekton-task-runs/artifacthub-pkg.yml @@ -0,0 +1,23 @@ +name: block-tekton-task-runs-cel +version: 1.0.0 +displayName: Block Tekton TaskRun in CEL expressions +description: >- + Restrict creation of TaskRun resources to the Tekton pipelines controller. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/tekton-cel/block-tekton-task-runs/block-tekton-task-runs.yaml + ``` +keywords: + - kyverno + - Tekton + - CEL Expressions +readme: | + Restrict creation of TaskRun resources to the Tekton pipelines controller. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Tekton in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "TaskRun" +digest: 865b8ae10fc53e1bb258db975e122e386610b84cba4bbf7fa4549d93f3affca4 +createdAt: "2024-05-23T18:08:47Z" diff --git a/tekton-cel/block-tekton-task-runs/block-tekton-task-runs.yaml b/tekton-cel/block-tekton-task-runs/block-tekton-task-runs.yaml new file mode 100644 index 000000000..f1f786b34 --- /dev/null +++ b/tekton-cel/block-tekton-task-runs/block-tekton-task-runs.yaml @@ -0,0 +1,38 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: block-tekton-task-runs + annotations: + policies.kyverno.io/title: Block Tekton TaskRun in CEL expressions + policies.kyverno.io/category: Tekton in CEL + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: TaskRun + kyverno.io/kyverno-version: 1.11.0 + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/description: >- + Restrict creation of TaskRun resources to the Tekton pipelines controller. +spec: + validationFailureAction: Audit + background: false + rules: + - name: check-taskrun-user + match: + any: + - resources: + kinds: + - TaskRun + operations: + - CREATE + - UPDATE + exclude: + any: + - subjects: + - kind: User + name: "system:serviceaccount:tekton-pipelines:tekton-pipelines-controller" + validate: + cel: + expressions: + - expression: "false" + message: Creating a TaskRun is not allowed. + diff --git a/tekton-cel/require-tekton-bundle/.chainsaw-test/bad-pipelinerun.yaml b/tekton-cel/require-tekton-bundle/.chainsaw-test/bad-pipelinerun.yaml new file mode 100644 index 000000000..cad412909 --- /dev/null +++ b/tekton-cel/require-tekton-bundle/.chainsaw-test/bad-pipelinerun.yaml @@ -0,0 +1,18 @@ +apiVersion: tekton.dev/v1 +kind: PipelineRun +metadata: + name: badpipelinerun01 +spec: + pipelineRef: + name: mypipeline +--- +apiVersion: tekton.dev/v1 +kind: PipelineRun +metadata: + name: badpipelinerun02 +spec: + pipelineSpec: + tasks: + - name: task1 + taskRef: + name: mytask \ No newline at end of file diff --git a/tekton-cel/require-tekton-bundle/.chainsaw-test/bad-taskrun.yaml b/tekton-cel/require-tekton-bundle/.chainsaw-test/bad-taskrun.yaml new file mode 100644 index 000000000..22ac6a221 --- /dev/null +++ b/tekton-cel/require-tekton-bundle/.chainsaw-test/bad-taskrun.yaml @@ -0,0 +1,7 @@ +apiVersion: tekton.dev/v1 +kind: TaskRun +metadata: + name: badtaskrun01 +spec: + taskRef: + name: read-task \ No newline at end of file diff --git a/tekton-cel/require-tekton-bundle/.chainsaw-test/chainsaw-test.yaml b/tekton-cel/require-tekton-bundle/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..1ee775051 --- /dev/null +++ b/tekton-cel/require-tekton-bundle/.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-tekton-bundle +spec: + steps: + - name: step-00 + try: + - assert: + file: crd-taskrun-assert.yaml + - assert: + file: crd-pipelinerun-assert.yaml + - name: step-01 + try: + - apply: + file: ../require-tekton-bundle.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: require-tekton-bundle + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: good-taskrun.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-taskrun.yaml + - apply: + file: good-pipelinerun.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-pipelinerun.yaml diff --git a/tekton-cel/require-tekton-bundle/.chainsaw-test/crd-pipelinerun-assert.yaml b/tekton-cel/require-tekton-bundle/.chainsaw-test/crd-pipelinerun-assert.yaml new file mode 100755 index 000000000..81ab957e7 --- /dev/null +++ b/tekton-cel/require-tekton-bundle/.chainsaw-test/crd-pipelinerun-assert.yaml @@ -0,0 +1,12 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: pipelineruns.tekton.dev +spec: {} +status: + acceptedNames: + kind: PipelineRun + plural: pipelineruns + singular: pipelinerun + storedVersions: + - v1 diff --git a/tekton-cel/require-tekton-bundle/.chainsaw-test/crd-taskrun-assert.yaml b/tekton-cel/require-tekton-bundle/.chainsaw-test/crd-taskrun-assert.yaml new file mode 100755 index 000000000..2934ff501 --- /dev/null +++ b/tekton-cel/require-tekton-bundle/.chainsaw-test/crd-taskrun-assert.yaml @@ -0,0 +1,12 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: taskruns.tekton.dev +spec: {} +status: + acceptedNames: + kind: TaskRun + plural: taskruns + singular: taskrun + storedVersions: + - v1 diff --git a/tekton-cel/require-tekton-bundle/.chainsaw-test/good-pipelinerun.yaml b/tekton-cel/require-tekton-bundle/.chainsaw-test/good-pipelinerun.yaml new file mode 100644 index 000000000..21403752f --- /dev/null +++ b/tekton-cel/require-tekton-bundle/.chainsaw-test/good-pipelinerun.yaml @@ -0,0 +1,8 @@ +apiVersion: tekton.dev/v1 +kind: PipelineRun +metadata: + name: goodpipelinerun01 +spec: + pipelineRef: + name: mypipeline + bundle: docker.io/foo/bar \ No newline at end of file diff --git a/tekton-cel/require-tekton-bundle/.chainsaw-test/good-taskrun.yaml b/tekton-cel/require-tekton-bundle/.chainsaw-test/good-taskrun.yaml new file mode 100644 index 000000000..51cc014b7 --- /dev/null +++ b/tekton-cel/require-tekton-bundle/.chainsaw-test/good-taskrun.yaml @@ -0,0 +1,8 @@ +apiVersion: tekton.dev/v1 +kind: TaskRun +metadata: + name: goodtaskrun01 +spec: + taskRef: + name: echo-task + bundle: docker.io/foo/bar \ No newline at end of file diff --git a/tekton-cel/require-tekton-bundle/.chainsaw-test/policy-ready.yaml b/tekton-cel/require-tekton-bundle/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..fe3d051fb --- /dev/null +++ b/tekton-cel/require-tekton-bundle/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: require-tekton-bundle +status: + ready: true diff --git a/tekton-cel/require-tekton-bundle/.kyverno-test/kyverno-test.yaml b/tekton-cel/require-tekton-bundle/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..5c6b040b6 --- /dev/null +++ b/tekton-cel/require-tekton-bundle/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,37 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: require-tekton-bundle +policies: +- ../require-tekton-bundle.yaml +resources: +- ../.chainsaw-test/bad-pipelinerun.yaml +- ../.chainsaw-test/bad-taskrun.yaml +- ../.chainsaw-test/good-pipelinerun.yaml +- ../.chainsaw-test/good-taskrun.yaml +results: +- policy: require-tekton-bundle + rule: check-bundle-pipelinerun + kind: PipelineRun + resources: + - badpipelinerun01 + - badpipelinerun02 + result: fail +- policy: require-tekton-bundle + rule: check-bundle-pipelinerun + kind: PipelineRun + resources: + - goodpipelinerun01 + result: pass +- policy: require-tekton-bundle + rule: check-bundle-taskrun + kind: TaskRun + resources: + - badtaskrun01 + result: fail +- policy: require-tekton-bundle + rule: check-bundle-taskrun + kind: TaskRun + resources: + - goodtaskrun01 + result: pass diff --git a/tekton-cel/require-tekton-bundle/artifacthub-pkg.yml b/tekton-cel/require-tekton-bundle/artifacthub-pkg.yml new file mode 100644 index 000000000..67bdf90ef --- /dev/null +++ b/tekton-cel/require-tekton-bundle/artifacthub-pkg.yml @@ -0,0 +1,23 @@ +name: require-tekton-bundle-cel +version: 1.0.0 +displayName: Require Tekton Bundle in CEL expressions +description: >- + PipelineRun and TaskRun resources must be executed from a bundle +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/tekton-cel/require-tekton-bundle/require-tekton-bundle.yaml + ``` +keywords: + - kyverno + - Tekton + - CEL Expressions +readme: | + PipelineRun and TaskRun resources must be executed from a bundle + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Tekton in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "TaskRun, PipelineRun" +digest: 396315ccb0132309267847614372230dbab14ab9935a1aac800d96981da37d10 +createdAt: "2024-05-24T04:26:34Z" diff --git a/tekton-cel/require-tekton-bundle/require-tekton-bundle.yaml b/tekton-cel/require-tekton-bundle/require-tekton-bundle.yaml new file mode 100644 index 000000000..359ae7f1e --- /dev/null +++ b/tekton-cel/require-tekton-bundle/require-tekton-bundle.yaml @@ -0,0 +1,44 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: require-tekton-bundle + annotations: + policies.kyverno.io/title: Require Tekton Bundle in CEL expressions + policies.kyverno.io/category: Tekton in CEL + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: TaskRun, PipelineRun + kyverno.io/kyverno-version: 1.11.0 + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/description: >- + PipelineRun and TaskRun resources must be executed from a bundle +spec: + validationFailureAction: Audit + background: true + rules: + - name: check-bundle-pipelinerun + match: + any: + - resources: + kinds: + - PipelineRun + operations: + - CREATE + - UPDATE + validate: + cel: + expressions: + - expression: "has(object.spec.pipelineRef) && has(object.spec.pipelineRef.bundle) && object.spec.pipelineRef.bundle != ''" + message: "A bundle is required." + - name: check-bundle-taskrun + match: + any: + - resources: + kinds: + - TaskRun + validate: + cel: + expressions: + - expression: "has(object.spec.taskRef) && has(object.spec.taskRef.bundle) && object.spec.taskRef.bundle != ''" + message: "A bundle is required." + diff --git a/tekton/require-tekton-bundle/.kyverno-test/kyverno-test.yaml b/tekton/require-tekton-bundle/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..5c6b040b6 --- /dev/null +++ b/tekton/require-tekton-bundle/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,37 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: require-tekton-bundle +policies: +- ../require-tekton-bundle.yaml +resources: +- ../.chainsaw-test/bad-pipelinerun.yaml +- ../.chainsaw-test/bad-taskrun.yaml +- ../.chainsaw-test/good-pipelinerun.yaml +- ../.chainsaw-test/good-taskrun.yaml +results: +- policy: require-tekton-bundle + rule: check-bundle-pipelinerun + kind: PipelineRun + resources: + - badpipelinerun01 + - badpipelinerun02 + result: fail +- policy: require-tekton-bundle + rule: check-bundle-pipelinerun + kind: PipelineRun + resources: + - goodpipelinerun01 + result: pass +- policy: require-tekton-bundle + rule: check-bundle-taskrun + kind: TaskRun + resources: + - badtaskrun01 + result: fail +- policy: require-tekton-bundle + rule: check-bundle-taskrun + kind: TaskRun + resources: + - goodtaskrun01 + result: pass diff --git a/tekton/require-tekton-namespace-pipelinerun/.kyverno-test/kyverno-test.yaml b/tekton/require-tekton-namespace-pipelinerun/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..141034c08 --- /dev/null +++ b/tekton/require-tekton-namespace-pipelinerun/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,22 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: require-tekton-namespace-pipelinerun +policies: +- ../require-tekton-namespace-pipelinerun.yaml +resources: +- ../.chainsaw-test/bad-pipelinerun.yaml +- ../.chainsaw-test/good-pipelinerun.yaml +results: +- policy: require-tekton-namespace-pipelinerun + rule: check-pipelinerun-namespace + kind: PipelineRun + resources: + - badpipelinerun01 + result: fail +- policy: require-tekton-namespace-pipelinerun + rule: check-pipelinerun-namespace + kind: PipelineRun + resources: + - goodpipelinerun01 + result: pass diff --git a/velero-cel/block-velero-restore/.chainsaw-test/bad-restore.yaml b/velero-cel/block-velero-restore/.chainsaw-test/bad-restore.yaml new file mode 100644 index 000000000..84e3ec4e6 --- /dev/null +++ b/velero-cel/block-velero-restore/.chainsaw-test/bad-restore.yaml @@ -0,0 +1,21 @@ +apiVersion: velero.io/v1 +kind: Restore +metadata: + name: badrestore01 +spec: + backupName: a-very-special-backup + namespaceMapping: + foo: kube-system +--- +apiVersion: velero.io/v1 +kind: Restore +metadata: + name: badrestore02 +spec: + backupName: a-very-special-backup + includedNamespaces: + - '*' + excludedNamespaces: + - some-namespace + namespaceMapping: + foo: kube-node-lease \ No newline at end of file diff --git a/velero-cel/block-velero-restore/.chainsaw-test/chainsaw-test.yaml b/velero-cel/block-velero-restore/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..d63f10b09 --- /dev/null +++ b/velero-cel/block-velero-restore/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,35 @@ +# 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: block-velero-restore +spec: + steps: + - name: step-00 + try: + - assert: + file: crd-restore-assert.yaml + - name: step-01 + try: + - apply: + file: ../block-velero-restore.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: block-velero-restore + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: good-restore.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-restore.yaml diff --git a/velero-cel/block-velero-restore/.chainsaw-test/crd-restore-assert.yaml b/velero-cel/block-velero-restore/.chainsaw-test/crd-restore-assert.yaml new file mode 100755 index 000000000..37aa83b76 --- /dev/null +++ b/velero-cel/block-velero-restore/.chainsaw-test/crd-restore-assert.yaml @@ -0,0 +1,13 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: restores.velero.io +spec: {} +status: + acceptedNames: + kind: Restore + listKind: RestoreList + plural: restores + singular: restore + storedVersions: + - v1 diff --git a/velero-cel/block-velero-restore/.chainsaw-test/good-restore.yaml b/velero-cel/block-velero-restore/.chainsaw-test/good-restore.yaml new file mode 100644 index 000000000..43052e805 --- /dev/null +++ b/velero-cel/block-velero-restore/.chainsaw-test/good-restore.yaml @@ -0,0 +1,28 @@ +apiVersion: velero.io/v1 +kind: Restore +metadata: + name: goodrestore01 +spec: + backupName: a-very-special-backup + namespaceMapping: + foo: bar +--- +apiVersion: velero.io/v1 +kind: Restore +metadata: + name: goodrestore02 +spec: + backupName: a-very-special-backup + includedNamespaces: + - '*' + excludedNamespaces: + - some-namespace +--- +apiVersion: velero.io/v1 +kind: Restore +metadata: + name: goodrestore03 +spec: + backupName: a-very-special-backup + namespaceMapping: + kube-system: bar \ No newline at end of file diff --git a/velero-cel/block-velero-restore/.chainsaw-test/policy-ready.yaml b/velero-cel/block-velero-restore/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..df978e12d --- /dev/null +++ b/velero-cel/block-velero-restore/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: block-velero-restore +status: + ready: true diff --git a/velero-cel/block-velero-restore/.kyverno-test/kyverno-test.yaml b/velero-cel/block-velero-restore/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..64ab3c92a --- /dev/null +++ b/velero-cel/block-velero-restore/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,22 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: block-velero-restore +policies: +- ../block-velero-restore.yaml +resources: +- resource.yaml +results: +- kind: Restore + policy: block-velero-restore + resources: + - badrestore01 + result: fail + rule: block-velero-restore-to-protected-namespace +- kind: Restore + policy: block-velero-restore + resources: + - restore-without-namespace-mapping + - goodrestore01 + result: pass + rule: block-velero-restore-to-protected-namespace diff --git a/velero-cel/block-velero-restore/.kyverno-test/resource.yaml b/velero-cel/block-velero-restore/.kyverno-test/resource.yaml new file mode 100644 index 000000000..9a7a09120 --- /dev/null +++ b/velero-cel/block-velero-restore/.kyverno-test/resource.yaml @@ -0,0 +1,52 @@ +####################################################### +## Rule: block-velero-restore-to-protected-namespace ## +####################################################### +###### Restore - Bad +--- +apiVersion: velero.io/v1 +kind: Restore +metadata: + name: badrestore01 + namespace: velero +spec: + backupName: my-backup + includedResources: + - '*' + namespaceMapping: + default: kube-system +restorePVs: true +--- +###### Restore - Good +apiVersion: velero.io/v1 +kind: Restore +metadata: + name: restore-without-namespace-mapping + namespace: velero +spec: + backupName: my-backup + excludedResources: + - nodes + - events + - events.events.k8s.io + - backups.velero.io + - restores.velero.io + - resticrepositories.velero.io + - csinodes.storage.k8s.io + - volumeattachments.storage.k8s.io + - backuprepositories.velero.io + includedNamespaces: + - '*' +--- +apiVersion: velero.io/v1 +kind: Restore +metadata: + name: goodrestore01 + namespace: velero +spec: + backupName: my-backup + includedResources: + - '*' + namespaceMapping: + default: ingress-nginx +restorePVs: true +--- diff --git a/velero-cel/block-velero-restore/artifacthub-pkg.yml b/velero-cel/block-velero-restore/artifacthub-pkg.yml new file mode 100644 index 000000000..31d9b5ce7 --- /dev/null +++ b/velero-cel/block-velero-restore/artifacthub-pkg.yml @@ -0,0 +1,31 @@ +name: block-velero-restore-cel +version: 1.0.0 +displayName: Block Velero Restore in CEL expressions +description: >- + Velero allows on backup and restore operations and is designed to be run with full cluster admin permissions. + It allows on cross namespace restore operations, which means you can restore backup of namespace A to namespace B. + This policy protect restore operation into system or any protected namespaces, listed in deny condition section. + It checks the Restore CRD object and its namespaceMapping field. If destination match protected namespace + then operation fails and warning message is throw. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/velero-cel/block-velero-restore/block-velero-restore.yaml + ``` +keywords: + - velero + - kyverno + - CEL Expressions +readme: | + Velero allows on backup and restore operations and is designed to be run with full cluster admin permissions. + It allows on cross namespace restore operations, which means you can restore backup of namespace A to namespace B. + This policy protect restore operation into system or any protected namespaces, listed in deny condition section. + It checks the Restore CRD object and its namespaceMapping field. If destination match protected namespace + then operation fails and warning message is throw. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Velero in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Restore" +digest: 375151c611cea4a9da84b11a69c580498e0688db59bddf056770ba416df8982e +createdAt: "2024-05-23T17:20:18Z" diff --git a/velero-cel/block-velero-restore/block-velero-restore.yaml b/velero-cel/block-velero-restore/block-velero-restore.yaml new file mode 100644 index 000000000..e1dd8aeb9 --- /dev/null +++ b/velero-cel/block-velero-restore/block-velero-restore.yaml @@ -0,0 +1,38 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: block-velero-restore + annotations: + policies.kyverno.io/title: Block Velero Restore to Protected Namespace in CEL expressions + policies.kyverno.io/category: Velero in CEL + policies.kyverno.io/subject: Restore + kyverno.io/kyverno-version: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/description: >- + Velero allows on backup and restore operations and is designed to be run with full cluster admin permissions. + It allows on cross namespace restore operations, which means you can restore backup of namespace A to namespace B. + This policy protect restore operation into system or any protected namespaces, listed in deny condition section. + It checks the Restore CRD object and its namespaceMapping field. If destination match protected namespace + then operation fails and warning message is throw. +spec: + validationFailureAction: Audit + background: false + rules: + - name: block-velero-restore-to-protected-namespace + match: + any: + - resources: + kinds: + - velero.io/v1/Restore + operations: + - CREATE + - UPDATE + validate: + cel: + variables: + - name: namespaceMappingValues + expression: "has(object.spec.namespaceMapping) ? object.spec.namespaceMapping.map(nsmap, object.spec.namespaceMapping[nsmap]) : []" + expressions: + - expression: "!variables.namespaceMappingValues.exists(val, val in ['kube-system', 'kube-node-lease'])" + messageExpression: "'Warning! Restore to protected namespace: ' + variables.namespaceMappingValues.join(', ') + ' is not allowed!'" + diff --git a/velero-cel/validate-cron-schedule/.chainsaw-test/bad-schedule.yaml b/velero-cel/validate-cron-schedule/.chainsaw-test/bad-schedule.yaml new file mode 100644 index 000000000..e08e5d4d9 --- /dev/null +++ b/velero-cel/validate-cron-schedule/.chainsaw-test/bad-schedule.yaml @@ -0,0 +1,19 @@ +apiVersion: velero.io/v1 +kind: Schedule +metadata: + name: badschedule01 +spec: + schedule: 0 7 * * * * + template: + includedNamespaces: + - 'default' +--- +apiVersion: velero.io/v1 +kind: Schedule +metadata: + name: badschedule02 +spec: + schedule: 0 7 * */ * + template: + includedNamespaces: + - 'default' diff --git a/velero-cel/validate-cron-schedule/.chainsaw-test/chainsaw-test.yaml b/velero-cel/validate-cron-schedule/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..a4df56dcc --- /dev/null +++ b/velero-cel/validate-cron-schedule/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,35 @@ +# 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: validate-cron-schedule +spec: + steps: + - name: step-00 + try: + - assert: + file: crd-schedule-assert.yaml + - name: step-01 + try: + - apply: + file: ../validate-cron-schedule.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: validate-cron-schedule + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: good-schedule.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-schedule.yaml diff --git a/velero-cel/validate-cron-schedule/.chainsaw-test/crd-schedule-assert.yaml b/velero-cel/validate-cron-schedule/.chainsaw-test/crd-schedule-assert.yaml new file mode 100755 index 000000000..9b0937ad9 --- /dev/null +++ b/velero-cel/validate-cron-schedule/.chainsaw-test/crd-schedule-assert.yaml @@ -0,0 +1,13 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: schedules.velero.io +spec: {} +status: + acceptedNames: + kind: Schedule + listKind: ScheduleList + plural: schedules + singular: schedule + storedVersions: + - v1 diff --git a/velero-cel/validate-cron-schedule/.chainsaw-test/good-schedule.yaml b/velero-cel/validate-cron-schedule/.chainsaw-test/good-schedule.yaml new file mode 100644 index 000000000..41e2f4914 --- /dev/null +++ b/velero-cel/validate-cron-schedule/.chainsaw-test/good-schedule.yaml @@ -0,0 +1,11 @@ +apiVersion: velero.io/v1 +kind: Schedule +metadata: + name: goodsched01 +spec: + schedule: 0 7 * * * + template: + includedNamespaces: + - '*' + excludedNamespaces: + - some-namespace \ No newline at end of file diff --git a/velero-cel/validate-cron-schedule/.chainsaw-test/policy-ready.yaml b/velero-cel/validate-cron-schedule/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..11afe59c1 --- /dev/null +++ b/velero-cel/validate-cron-schedule/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: validate-cron-schedule +status: + ready: true diff --git a/velero-cel/validate-cron-schedule/.kyverno-test/kyverno-test.yaml b/velero-cel/validate-cron-schedule/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..942f49cd4 --- /dev/null +++ b/velero-cel/validate-cron-schedule/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,21 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: validate-cron-schedule +policies: +- ../validate-cron-schedule.yaml +resources: +- resources.yaml +results: +- kind: Schedule + policy: validate-cron-schedule + resources: + - badschedule01 + result: fail + rule: validate-cron +- kind: Schedule + policy: validate-cron-schedule + resources: + - goodschedule01 + result: pass + rule: validate-cron diff --git a/velero-cel/validate-cron-schedule/.kyverno-test/resources.yaml b/velero-cel/validate-cron-schedule/.kyverno-test/resources.yaml new file mode 100644 index 000000000..dd6a0bee1 --- /dev/null +++ b/velero-cel/validate-cron-schedule/.kyverno-test/resources.yaml @@ -0,0 +1,20 @@ +--- +apiVersion: velero.io/v1 +kind: Schedule +metadata: + name: goodschedule01 +spec: + schedule: 0 7 * * * + template: + includedNamespaces: + - 'default' +--- +apiVersion: velero.io/v1 +kind: Schedule +metadata: + name: badschedule01 +spec: + schedule: 0 7 * * * * + template: + includedNamespaces: + - 'default' diff --git a/velero-cel/validate-cron-schedule/artifacthub-pkg.yml b/velero-cel/validate-cron-schedule/artifacthub-pkg.yml new file mode 100644 index 000000000..0a495f085 --- /dev/null +++ b/velero-cel/validate-cron-schedule/artifacthub-pkg.yml @@ -0,0 +1,25 @@ +name: validate-cron-schedule-cel +version: 1.0.0 +displayName: Validate Cron Schedule in CEL expressions +description: >- + A Velero Schedule is given in Cron format and must be accurate to ensure + operation. This policy validates that the schedule is a valid Cron format. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/velero-cel/validate-cron-schedule/validate-cron-schedule.yaml + ``` +keywords: + - velero + - kyverno + - CEL Expressions +readme: | + A Velero Schedule is given in Cron format and must be accurate to ensure + operation. This policy validates that the schedule is a valid Cron format. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Velero in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Schedule" +digest: a42222eee403614bcd88071eb5a6cdf15630cb27e0e03ea318511f359b63d899 +createdAt: "2024-05-23T17:34:19Z" diff --git a/velero-cel/validate-cron-schedule/validate-cron-schedule.yaml b/velero-cel/validate-cron-schedule/validate-cron-schedule.yaml new file mode 100644 index 000000000..86f135f8b --- /dev/null +++ b/velero-cel/validate-cron-schedule/validate-cron-schedule.yaml @@ -0,0 +1,33 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: validate-cron-schedule + annotations: + policies.kyverno.io/title: Validate Schedule in CEL expressions + policies.kyverno.io/category: Velero in CEL + policies.kyverno.io/subject: Schedule + kyverno.io/kyverno-version: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/description: >- + A Velero Schedule is given in Cron format and must be accurate to ensure + operation. This policy validates that the schedule is a valid Cron format. +spec: + background: true + validationFailureAction: Audit + rules: + - name: validate-cron + match: + any: + - resources: + kinds: + - velero.io/v1/Schedule + operations: + - CREATE + - UPDATE + validate: + cel: + expressions: + - expression: >- + object.spec.schedule.matches('^((?:\\*|[0-5]?[0-9](?:(?:-[0-5]?[0-9])|(?:,[0-5]?[0-9])+)?)(?:\\/[0-9]+)?)\\s+((?:\\*|(?:1?[0-9]|2[0-3])(?:(?:-(?:1?[0-9]|2[0-3]))|(?:,(?:1?[0-9]|2[0-3]))+)?)(?:\\/[0-9]+)?)\\s+((?:\\*|(?:[1-9]|[1-2][0-9]|3[0-1])(?:(?:-(?:[1-9]|[1-2][0-9]|3[0-1]))|(?:,(?:[1-9]|[1-2][0-9]|3[0-1]))+)?)(?:\\/[0-9]+)?)\\s+((?:\\*|(?:[1-9]|1[0-2])(?:(?:-(?:[1-9]|1[0-2]))|(?:,(?:[1-9]|1[0-2]))+)?)(?:\\/[0-9]+)?)\\s+((?:\\*|[0-7](?:-[0-7]|(?:,[0-7])+)?)(?:\\/[0-9]+)?)$') + message: The backup schedule must be in a valid cron format. + From af676a5ad62e02688fd2af0dc5b0d673bc9f2f6b Mon Sep 17 00:00:00 2001 From: chipzoller Date: Fri, 2 Aug 2024 10:50:03 -0400 Subject: [PATCH 4/4] add note about digest generation Signed-off-by: chipzoller --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7d1ab5edc..7e5ab011f 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ Anyone and everyone is welcome to write and contribute Kyverno policies! We have * Use dashes for folder name and policy name instead of underscores. -* When updating a policy already in the library, calculate the new sha256 sum of the changed policy and update the `artifacthub-pkg.yml` file's `digest` field with this value. This is to ensure Artifact Hub picks up the changes once merged. +* When updating a policy already in the library, calculate the new sha256 sum of the changed policy and update the `artifacthub-pkg.yml` file's `digest` field with this value. This is to ensure Artifact Hub picks up the changes once merged. Note that because of validation checks in Kyverno's CI processes, it expects the digest to have been generated on a Linux system. Due to the differences of control characters, a digest generated from a Windows system may be different from that generated in Linux. Once your policy is written within these guidelines and tested, please open a standard PR against the `main` branch of kyverno/policies. In order for a policy to make it to the website's [policies page](https://kyverno.io/policies/), it must first be committed to the `main` branch in this repo. Following that, an administrator will render these policies to produce Markdown files in a second PR. You do not need to worry about this process, however.