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/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. 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 + 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. + 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"