diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8c78461b7..be3ccbb61 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -57,9 +57,12 @@ jobs: - ^pod-security$ - ^psa$ - ^psp-migration$ + - ^psp-migration-cel$ - ^tekton$ + - ^tekton-cel$ - ^traefik$ - ^velero$ + - ^velero-cel$ runs-on: ubuntu-latest name: ${{ matrix.k8s-version.name }} - ${{ matrix.tests }} steps: @@ -72,4 +75,4 @@ jobs: - name: Run Tests uses: ./.github/actions/run-tests with: - tests: ${{ matrix.tests }} \ No newline at end of file + tests: ${{ matrix.tests }} diff --git a/psp-migration-cel/check-supplemental-groups/.chainsaw-test/chainsaw-test.yaml b/psp-migration-cel/check-supplemental-groups/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..2d0f56c6b --- /dev/null +++ b/psp-migration-cel/check-supplemental-groups/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,38 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: check-supplemental-groups +spec: + steps: + - name: step-01 + try: + - apply: + file: ../check-supplemental-groups.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: psp-check-supplemental-groups + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: pod-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: pod-bad.yaml + - apply: + file: podcontroller-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: podcontroller-bad.yaml diff --git a/psp-migration-cel/check-supplemental-groups/.chainsaw-test/pod-bad.yaml b/psp-migration-cel/check-supplemental-groups/.chainsaw-test/pod-bad.yaml new file mode 100644 index 000000000..295f13ed2 --- /dev/null +++ b/psp-migration-cel/check-supplemental-groups/.chainsaw-test/pod-bad.yaml @@ -0,0 +1,55 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 +spec: + securityContext: + supplementalGroups: + - 120 + - 230 + - 550 + containers: + - name: busybox01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod02 +spec: + securityContext: + supplementalGroups: + - 1000 + - 120 + containers: + - name: busybox01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod03 +spec: + securityContext: + runAsGroup: 0 + supplementalGroups: + - 580 + - 0 + containers: + - name: busybox01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod04 +spec: + securityContext: + supplementalGroups: + - 100 + - 601 + - 600 + runAsGroup: 0 + containers: + - name: busybox01 + image: busybox:1.35 \ No newline at end of file diff --git a/psp-migration-cel/check-supplemental-groups/.chainsaw-test/pod-good.yaml b/psp-migration-cel/check-supplemental-groups/.chainsaw-test/pod-good.yaml new file mode 100644 index 000000000..ccdb66190 --- /dev/null +++ b/psp-migration-cel/check-supplemental-groups/.chainsaw-test/pod-good.yaml @@ -0,0 +1,60 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 +spec: + containers: + - name: busybox01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod02 +spec: + securityContext: + supplementalGroups: + - 150 + - 100 + - 500 + containers: + - name: busybox01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod03 +spec: + securityContext: + supplementalGroups: + - 550 + - 600 + - 120 + containers: + - name: busybox01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod04 +spec: + securityContext: + runAsGroup: 0 + containers: + - name: busybox01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod05 +spec: + securityContext: + supplementalGroups: + - 600 + runAsGroup: 0 + containers: + - name: busybox01 + image: busybox:1.35 \ No newline at end of file diff --git a/psp-migration-cel/check-supplemental-groups/.chainsaw-test/podcontroller-bad.yaml b/psp-migration-cel/check-supplemental-groups/.chainsaw-test/podcontroller-bad.yaml new file mode 100644 index 000000000..da4768b78 --- /dev/null +++ b/psp-migration-cel/check-supplemental-groups/.chainsaw-test/podcontroller-bad.yaml @@ -0,0 +1,42 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: baddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + securityContext: + supplementalGroups: + - 100 + - 601 + - 600 + runAsGroup: 0 + containers: + - name: busybox01 + image: busybox:1.35 +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob01 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + securityContext: + supplementalGroups: + - 1000 + - 120 + containers: + - name: busybox01 + image: busybox:1.35 \ No newline at end of file diff --git a/psp-migration-cel/check-supplemental-groups/.chainsaw-test/podcontroller-good.yaml b/psp-migration-cel/check-supplemental-groups/.chainsaw-test/podcontroller-good.yaml new file mode 100644 index 000000000..cbb26cae5 --- /dev/null +++ b/psp-migration-cel/check-supplemental-groups/.chainsaw-test/podcontroller-good.yaml @@ -0,0 +1,42 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gooddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + securityContext: + supplementalGroups: + - 150 + - 100 + - 500 + containers: + - name: busybox01 + image: busybox:1.35 +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob01 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + securityContext: + supplementalGroups: + - 550 + - 600 + - 120 + containers: + - name: busybox01 + image: busybox:1.35 \ No newline at end of file diff --git a/psp-migration-cel/check-supplemental-groups/.chainsaw-test/policy-ready.yaml b/psp-migration-cel/check-supplemental-groups/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..d68e9bb1c --- /dev/null +++ b/psp-migration-cel/check-supplemental-groups/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: psp-check-supplemental-groups +status: + ready: true diff --git a/psp-migration-cel/check-supplemental-groups/.kyverno-test/kyverno-test.yaml b/psp-migration-cel/check-supplemental-groups/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..35f4b1eb9 --- /dev/null +++ b/psp-migration-cel/check-supplemental-groups/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,21 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: psp-check-supplemental-groups +policies: +- ../check-supplemental-groups.yaml +resources: +- resource.yaml +results: +- kind: Pod + policy: psp-check-supplemental-groups + resources: + - badpod01 + result: fail + rule: supplementalgroup-ranges +- kind: Pod + policy: psp-check-supplemental-groups + resources: + - goodpod01 + result: pass + rule: supplementalgroup-ranges diff --git a/psp-migration-cel/check-supplemental-groups/.kyverno-test/resource.yaml b/psp-migration-cel/check-supplemental-groups/.kyverno-test/resource.yaml new file mode 100644 index 000000000..d7c4dc51f --- /dev/null +++ b/psp-migration-cel/check-supplemental-groups/.kyverno-test/resource.yaml @@ -0,0 +1,24 @@ +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 +spec: + containers: + - name: container01 + image: dummyimagename + securityContext: + supplementalGroups: + - 0 +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 +spec: + containers: + - name: container01 + image: dummyimagename + securityContext: + supplementalGroups: + - 100 diff --git a/psp-migration-cel/check-supplemental-groups/artifacthub-pkg.yml b/psp-migration-cel/check-supplemental-groups/artifacthub-pkg.yml new file mode 100644 index 000000000..7717aebbe --- /dev/null +++ b/psp-migration-cel/check-supplemental-groups/artifacthub-pkg.yml @@ -0,0 +1,23 @@ +name: check-supplemental-groups-cel +version: 1.0.0 +displayName: Check supplementalGroups in CEL expressions +description: >- + Supplemental groups control which group IDs containers add and can coincide with restricted groups on the host. Pod Security Policies (PSP) allowed a range of these group IDs to be specified which were allowed. This policy ensures any Pod may only specify supplementalGroup IDs between 100-200 or 500-600. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/psp-migration-cel/check-supplemental-groups/check-supplemental-groups.yaml + ``` +keywords: + - kyverno + - PSP Migration + - CEL Expressions +readme: | + Supplemental groups control which group IDs containers add and can coincide with restricted groups on the host. Pod Security Policies (PSP) allowed a range of these group IDs to be specified which were allowed. This policy ensures any Pod may only specify supplementalGroup IDs between 100-200 or 500-600. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "PSP Migration in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Pod" +digest: 05135ed92926031b15d782552af3f8dbf8776014401328e186987344079fcc66 +createdAt: "2024-05-23T13:57:56Z" diff --git a/psp-migration-cel/check-supplemental-groups/check-supplemental-groups.yaml b/psp-migration-cel/check-supplemental-groups/check-supplemental-groups.yaml new file mode 100644 index 000000000..461920574 --- /dev/null +++ b/psp-migration-cel/check-supplemental-groups/check-supplemental-groups.yaml @@ -0,0 +1,39 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: psp-check-supplemental-groups + annotations: + policies.kyverno.io/title: Check supplementalGroups in CEL expressions + policies.kyverno.io/category: PSP Migration in CEL + policies.kyverno.io/severity: medium + kyverno.io/kyverno-version: 1.11.0 + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/subject: Pod + policies.kyverno.io/description: >- + Supplemental groups control which group IDs containers add and can coincide with + restricted groups on the host. Pod Security Policies (PSP) allowed a range of + these group IDs to be specified which were allowed. This policy ensures any Pod + may only specify supplementalGroup IDs between 100-200 or 500-600. +spec: + background: false + validationFailureAction: Audit + rules: + - name: supplementalgroup-ranges + match: + any: + - resources: + kinds: + - Pod + operations: + - CREATE + - UPDATE + validate: + cel: + expressions: + - expression: >- + !has(object.spec.securityContext) || + !has(object.spec.securityContext.supplementalGroups) || + object.spec.securityContext.supplementalGroups.all(supplementalGroup, (supplementalGroup >= 100 && supplementalGroup <= 200) || (supplementalGroup >= 500 && supplementalGroup <= 600)) + message: Any supplementalGroup ID must be within the range 100-200 or 500-600. + diff --git a/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/chainsaw-test.yaml b/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..537dcecd5 --- /dev/null +++ b/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,40 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: restrict-adding-capabilities +spec: + # disable templating because it can cause issues with CEL expressions + template: false + steps: + - name: step-01 + try: + - apply: + file: ../restrict-adding-capabilities.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: psp-restrict-adding-capabilities + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: pod-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: pod-bad.yaml + - apply: + file: podcontroller-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: podcontroller-bad.yaml diff --git a/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/pod-bad.yaml b/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/pod-bad.yaml new file mode 100644 index 000000000..9d97c06bf --- /dev/null +++ b/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/pod-bad.yaml @@ -0,0 +1,177 @@ +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod01 +spec: + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CHOWN +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod02 +spec: + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CHOWN + - NET_BIND_SERVICE +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod03 +spec: + containers: + - name: container01 + image: busybox:1.35 + - name: container02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CHOWN +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod04 +spec: + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + - name: container02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CHOWN +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod05 +spec: + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + - name: container02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CHOWN + - NET_BIND_SERVICE +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod06 +spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CHOWN + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod07 +spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CHOWN + - NET_BIND_SERVICE + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod08 +spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + - name: initcontainer02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CHOWN + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod09 +spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + - name: initcontainer02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CHOWN + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod10 +spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + - name: initcontainer02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CHOWN + - NET_BIND_SERVICE + containers: + - name: container01 + image: busybox:1.35 +--- \ No newline at end of file diff --git a/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/pod-good.yaml b/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/pod-good.yaml new file mode 100644 index 000000000..8b77e2a79 --- /dev/null +++ b/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/pod-good.yaml @@ -0,0 +1,148 @@ +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod01 +spec: + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod02 +spec: + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod03 +spec: + containers: + - name: container01 + image: busybox:1.35 + - name: container02 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod04 +spec: + containers: + - name: container01 + image: busybox:1.35 + - name: container02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod05 +spec: + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + - name: container02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod06 +spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod07 +spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod08 +spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + - name: initcontainer02 + image: busybox:1.35 + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod09 +spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + - name: initcontainer02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod10 +spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + - name: initcontainer02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + containers: + - name: container01 + image: busybox:1.35 diff --git a/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/podcontroller-bad.yaml b/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/podcontroller-bad.yaml new file mode 100644 index 000000000..4037cb574 --- /dev/null +++ b/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/podcontroller-bad.yaml @@ -0,0 +1,308 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: baddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_RAW +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: baddeployment02 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_RAW + - CAP_CHOWN +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: baddeployment03 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_RAW + - name: container02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CAP_CHOWN +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: baddeployment04 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_RAW + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CAP_CHOWN +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: baddeployment05 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + - name: initcontainer02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_RAW + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CAP_CHOWN +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: baddeployment06 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_RAW + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - SYS_ADMIN +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob01 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_RAW +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob02 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_RAW + - NET_BIND_SERVICE +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob03 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_RAW + - name: container02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob04 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + initContainers: + - name: initcontainer01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_RAW + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + - CAP_CHOWN +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob05 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + initContainers: + - name: initcontainer01 + image: busybox:1.35 + - name: initcontainer02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_RAW + - CAP_CHOWN + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - SETGID +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob06 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + initContainers: + - name: initcontainer01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_RAW + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - SYS_ADMIN +--- \ No newline at end of file diff --git a/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/podcontroller-good.yaml b/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/podcontroller-good.yaml new file mode 100644 index 000000000..8daee6250 --- /dev/null +++ b/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/podcontroller-good.yaml @@ -0,0 +1,267 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gooddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gooddeployment02 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gooddeployment03 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CAP_CHOWN + - name: container02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gooddeployment04 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gooddeployment05 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CAP_CHOWN + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gooddeployment06 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + initContainers: + - name: initcontainer01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CAP_CHOWN +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob01 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob02 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CAP_CHOWN +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob03 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + - name: container02 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CAP_CHOWN +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob04 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + initContainers: + - name: initcontainer01 + image: busybox:1.35 + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob05 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + initContainers: + - name: initcontainer01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + containers: + - name: container01 + image: busybox:1.35 +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob06 +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + initContainers: + - name: initcontainer01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + containers: + - name: container01 + image: busybox:1.35 + securityContext: + capabilities: + add: + - CAP_CHOWN diff --git a/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/policy-ready.yaml b/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..e870f077e --- /dev/null +++ b/psp-migration-cel/restrict-adding-capabilities/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: psp-restrict-adding-capabilities +status: + ready: true diff --git a/psp-migration-cel/restrict-adding-capabilities/.kyverno-test/kyverno-test.yaml b/psp-migration-cel/restrict-adding-capabilities/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..4c94d8b92 --- /dev/null +++ b/psp-migration-cel/restrict-adding-capabilities/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,39 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: psp-restrict-adding-capabilities +policies: +- ../restrict-adding-capabilities.yaml +resources: +- resource.yaml +results: +- kind: Pod + policy: psp-restrict-adding-capabilities + resources: + - addcap-badpod01 + - addcap-badpod02 + - addcap-badpod03 + - addcap-badpod04 + - addcap-badpod05 + - addcap-badpod06 + - addcap-badpod07 + - addcap-badpod08 + - addcap-badpod09 + - addcap-badpod10 + result: fail + rule: allowed-capabilities +- kind: Pod + policy: psp-restrict-adding-capabilities + resources: + - addcap-goodpod01 + - addcap-goodpod02 + - addcap-goodpod03 + - addcap-goodpod04 + - addcap-goodpod05 + - addcap-goodpod06 + - addcap-goodpod07 + - addcap-goodpod08 + - addcap-goodpod09 + - addcap-goodpod10 + result: pass + rule: allowed-capabilities diff --git a/psp-migration-cel/restrict-adding-capabilities/.kyverno-test/resource.yaml b/psp-migration-cel/restrict-adding-capabilities/.kyverno-test/resource.yaml new file mode 100644 index 000000000..af86fceb7 --- /dev/null +++ b/psp-migration-cel/restrict-adding-capabilities/.kyverno-test/resource.yaml @@ -0,0 +1,328 @@ +###### Pods - Bad +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod01 +spec: + containers: + - name: container01 + image: dummyimagename + securityContext: + capabilities: + add: + - CHOWN +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod02 +spec: + containers: + - name: container01 + image: dummyimagename + securityContext: + capabilities: + add: + - CHOWN + - NET_BIND_SERVICE +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod03 +spec: + containers: + - name: container01 + image: dummyimagename + - name: container02 + image: dummyimagename + securityContext: + capabilities: + add: + - CHOWN +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod04 +spec: + containers: + - name: container01 + image: dummyimagename + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + - name: container02 + image: dummyimagename + securityContext: + capabilities: + add: + - CHOWN +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod05 +spec: + containers: + - name: container01 + image: dummyimagename + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + - name: container02 + image: dummyimagename + securityContext: + capabilities: + add: + - CHOWN + - NET_BIND_SERVICE +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod06 +spec: + initContainers: + - name: initcontainer01 + image: dummyimagename + securityContext: + capabilities: + add: + - CHOWN + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod07 +spec: + initContainers: + - name: initcontainer01 + image: dummyimagename + securityContext: + capabilities: + add: + - CHOWN + - NET_BIND_SERVICE + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod08 +spec: + initContainers: + - name: initcontainer01 + image: dummyimagename + - name: initcontainer02 + image: dummyimagename + securityContext: + capabilities: + add: + - CHOWN + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod09 +spec: + initContainers: + - name: initcontainer01 + image: dummyimagename + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + - name: initcontainer02 + image: dummyimagename + securityContext: + capabilities: + add: + - CHOWN + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-badpod10 +spec: + initContainers: + - name: initcontainer01 + image: dummyimagename + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + - name: initcontainer02 + image: dummyimagename + securityContext: + capabilities: + add: + - CHOWN + - NET_BIND_SERVICE + containers: + - name: container01 + image: dummyimagename +--- +###### Pods - Good +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod01 +spec: + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod02 +spec: + containers: + - name: container01 + image: dummyimagename + securityContext: + capabilities: + add: + - NET_BIND_SERVICE +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod03 +spec: + containers: + - name: container01 + image: dummyimagename + - name: container02 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod04 +spec: + containers: + - name: container01 + image: dummyimagename + - name: container02 + image: dummyimagename + securityContext: + capabilities: + add: + - NET_BIND_SERVICE +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod05 +spec: + containers: + - name: container01 + image: dummyimagename + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + - name: container02 + image: dummyimagename + securityContext: + capabilities: + add: + - NET_BIND_SERVICE +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod06 +spec: + initContainers: + - name: initcontainer01 + image: dummyimagename + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod07 +spec: + initContainers: + - name: initcontainer01 + image: dummyimagename + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod08 +spec: + initContainers: + - name: initcontainer01 + image: dummyimagename + - name: initcontainer02 + image: dummyimagename + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod09 +spec: + initContainers: + - name: initcontainer01 + image: dummyimagename + - name: initcontainer02 + image: dummyimagename + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: addcap-goodpod10 +spec: + initContainers: + - name: initcontainer01 + image: dummyimagename + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + - name: initcontainer02 + image: dummyimagename + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + containers: + - name: container01 + image: dummyimagename diff --git a/psp-migration-cel/restrict-adding-capabilities/artifacthub-pkg.yml b/psp-migration-cel/restrict-adding-capabilities/artifacthub-pkg.yml new file mode 100644 index 000000000..19ded7cb5 --- /dev/null +++ b/psp-migration-cel/restrict-adding-capabilities/artifacthub-pkg.yml @@ -0,0 +1,23 @@ +name: restrict-adding-capabilities-cel +version: 1.0.0 +displayName: Restrict Adding Capabilities in CEL expressions +description: >- + Adding capabilities is a way for containers in a Pod to request higher levels of ability than those with which they may be provisioned. Many capabilities allow system-level control and should be prevented. Pod Security Policies (PSP) allowed a list of "good" capabilities to be added. This policy checks ephemeralContainers, initContainers, and containers to ensure the only capabilities that can be added are either NET_BIND_SERVICE or CAP_CHOWN. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/psp-migration-cel/restrict-adding-capabilities/restrict-adding-capabilities.yaml + ``` +keywords: + - kyverno + - PSP Migration + - CEL Expressions +readme: | + Adding capabilities is a way for containers in a Pod to request higher levels of ability than those with which they may be provisioned. Many capabilities allow system-level control and should be prevented. Pod Security Policies (PSP) allowed a list of "good" capabilities to be added. This policy checks ephemeralContainers, initContainers, and containers to ensure the only capabilities that can be added are either NET_BIND_SERVICE or CAP_CHOWN. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "PSP Migration in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Pod" +digest: a577515c97fa6c2990de6bc88df222e1555bf11bfacdf00e31b26c5c5fb086ac +createdAt: "2024-05-23T14:18:49Z" diff --git a/psp-migration-cel/restrict-adding-capabilities/restrict-adding-capabilities.yaml b/psp-migration-cel/restrict-adding-capabilities/restrict-adding-capabilities.yaml new file mode 100644 index 000000000..1d9f54494 --- /dev/null +++ b/psp-migration-cel/restrict-adding-capabilities/restrict-adding-capabilities.yaml @@ -0,0 +1,49 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: psp-restrict-adding-capabilities + annotations: + policies.kyverno.io/title: Restrict Adding Capabilities in CEL expressions + policies.kyverno.io/category: PSP Migration in CEL + policies.kyverno.io/severity: medium + kyverno.io/kyverno-version: 1.11.0 + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/subject: Pod + policies.kyverno.io/description: >- + Adding capabilities is a way for containers in a Pod to request higher levels + of ability than those with which they may be provisioned. Many capabilities + allow system-level control and should be prevented. Pod Security Policies (PSP) + allowed a list of "good" capabilities to be added. This policy checks + ephemeralContainers, initContainers, and containers to ensure the only + capabilities that can be added are either NET_BIND_SERVICE or CAP_CHOWN. +spec: + validationFailureAction: Audit + background: true + rules: + - name: allowed-capabilities + match: + any: + - resources: + kinds: + - Pod + operations: + - CREATE + - UPDATE + validate: + cel: + variables: + - name: allContainers + expression: "(object.spec.containers + (has(object.spec.initContainers) ? object.spec.initContainers : []) + (has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []))" + - name: allowedCapabilities + expression: "['NET_BIND_SERVICE', 'CAP_CHOWN']" + expressions: + - expression: >- + variables.allContainers.all(container, + !has(container.securityContext) || + !has(container.securityContext.capabilities) || + !has(container.securityContext.capabilities.add) || + container.securityContext.capabilities.add.all(capability, capability in variables.allowedCapabilities)) + message: >- + Any capabilities added other than NET_BIND_SERVICE or CAP_CHOWN are disallowed. + diff --git a/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/bad-pods.yaml b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/bad-pods.yaml new file mode 100644 index 000000000..6dee8ab8a --- /dev/null +++ b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/bad-pods.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 + namespace: restrict-runtimeclassname +spec: + runtimeClassName: fooclass + containers: + - name: container01 + image: dummyimagename \ No newline at end of file diff --git a/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/chainsaw-test.yaml b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..e42476abe --- /dev/null +++ b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,43 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: restrict-runtimeclassname +spec: + steps: + - name: step-00 + try: + - apply: + file: ../restrict-runtimeClassName.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: restrict-runtimeclass + spec: + validationFailureAction: Enforce + - name: step-01 + try: + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: ns.yaml + - apply: + file: runtimeclass-prod.yaml + - apply: + file: runtimeclass-exp.yaml + - apply: + file: runtimeclass-foo.yaml + - name: step-03 + try: + - apply: + file: good-pods.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-pods.yaml diff --git a/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/good-pods.yaml b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/good-pods.yaml new file mode 100644 index 000000000..475c030e4 --- /dev/null +++ b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/good-pods.yaml @@ -0,0 +1,31 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 + namespace: restrict-runtimeclassname +spec: + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod02 + namespace: restrict-runtimeclassname +spec: + runtimeClassName: expclass + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod03 + namespace: restrict-runtimeclassname +spec: + runtimeClassName: prodclass + containers: + - name: container01 + image: dummyimagename diff --git a/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/ns.yaml b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/ns.yaml new file mode 100755 index 000000000..121c85370 --- /dev/null +++ b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/ns.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: restrict-runtimeclassname diff --git a/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/policy-ready.yaml b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/policy-ready.yaml new file mode 100644 index 000000000..126968a0f --- /dev/null +++ b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-runtimeclass +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready \ No newline at end of file diff --git a/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/runtimeclass-exp.yaml b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/runtimeclass-exp.yaml new file mode 100755 index 000000000..0318454a0 --- /dev/null +++ b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/runtimeclass-exp.yaml @@ -0,0 +1,5 @@ +apiVersion: node.k8s.io/v1 +handler: expconfig +kind: RuntimeClass +metadata: + name: expclass diff --git a/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/runtimeclass-foo.yaml b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/runtimeclass-foo.yaml new file mode 100755 index 000000000..6d03f568e --- /dev/null +++ b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/runtimeclass-foo.yaml @@ -0,0 +1,5 @@ +apiVersion: node.k8s.io/v1 +handler: fooconfig +kind: RuntimeClass +metadata: + name: fooclass diff --git a/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/runtimeclass-prod.yaml b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/runtimeclass-prod.yaml new file mode 100755 index 000000000..5616c1916 --- /dev/null +++ b/psp-migration-cel/restrict-runtimeClassName/.chainsaw-test/runtimeclass-prod.yaml @@ -0,0 +1,5 @@ +apiVersion: node.k8s.io/v1 +handler: prodconfig +kind: RuntimeClass +metadata: + name: prodclass diff --git a/psp-migration-cel/restrict-runtimeClassName/.kyverno-test/kyverno-test.yaml b/psp-migration-cel/restrict-runtimeClassName/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..faa23c777 --- /dev/null +++ b/psp-migration-cel/restrict-runtimeClassName/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,23 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: restrict-runtimeclass +policies: +- ../restrict-runtimeClassName.yaml +resources: +- resource.yaml +results: +- kind: Pod + policy: restrict-runtimeclass + resources: + - badpod01 + result: fail + rule: prodclass-or-expclass +- kind: Pod + policy: restrict-runtimeclass + resources: + - goodpod01 + - goodpod02 + - goodpod03 + result: pass + rule: prodclass-or-expclass diff --git a/psp-migration-cel/restrict-runtimeClassName/.kyverno-test/resource.yaml b/psp-migration-cel/restrict-runtimeClassName/.kyverno-test/resource.yaml new file mode 100644 index 000000000..2820962a2 --- /dev/null +++ b/psp-migration-cel/restrict-runtimeClassName/.kyverno-test/resource.yaml @@ -0,0 +1,42 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 + namespace: restrict-runtimeclassname +spec: + runtimeClassName: fooclass + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 + namespace: restrict-runtimeclassname +spec: + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod02 + namespace: restrict-runtimeclassname +spec: + runtimeClassName: expclass + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod03 + namespace: restrict-runtimeclassname +spec: + runtimeClassName: prodclass + containers: + - name: container01 + image: dummyimagename diff --git a/psp-migration-cel/restrict-runtimeClassName/artifacthub-pkg.yml b/psp-migration-cel/restrict-runtimeClassName/artifacthub-pkg.yml new file mode 100644 index 000000000..08f856608 --- /dev/null +++ b/psp-migration-cel/restrict-runtimeClassName/artifacthub-pkg.yml @@ -0,0 +1,23 @@ +name: restrict-runtimeclass-cel +version: 1.0.0 +displayName: Restrict runtimeClass in CEL expressions +description: >- + The runtimeClass field of a Pod spec defines which container engine runtime should be used. In the previous Pod Security Policy controller, defining restrictions on which classes were allowed was permitted. Limiting runtime classes to only those which have been defined can prevent unintended running states or Pods which may not come online. This policy restricts the runtimeClass field to the values `prodclass` or `expclass`. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/psp-migration-cel/restrict-runtimeClassName/restrict-runtimeClassName.yaml + ``` +keywords: + - kyverno + - PSP Migration + - CEL Expressions +readme: | + The runtimeClass field of a Pod spec defines which container engine runtime should be used. In the previous Pod Security Policy controller, defining restrictions on which classes were allowed was permitted. Limiting runtime classes to only those which have been defined can prevent unintended running states or Pods which may not come online. This policy restricts the runtimeClass field to the values `prodclass` or `expclass`. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "PSP Migration in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Pod" +digest: 7bbfbc460b7977c74d198e76f96419f6415141ad08f53819f6c3643b9e1e7ab0 +createdAt: "2024-05-23T14:25:37Z" diff --git a/psp-migration-cel/restrict-runtimeClassName/restrict-runtimeClassName.yaml b/psp-migration-cel/restrict-runtimeClassName/restrict-runtimeClassName.yaml new file mode 100644 index 000000000..1dd8abbc8 --- /dev/null +++ b/psp-migration-cel/restrict-runtimeClassName/restrict-runtimeClassName.yaml @@ -0,0 +1,36 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-runtimeclass + annotations: + policies.kyverno.io/title: Restrict runtimeClass in CEL expressions + policies.kyverno.io/category: PSP Migration in CEL + policies.kyverno.io/subject: Pod + kyverno.io/kyverno-version: 1.12.1 + kyverno.io/kubernetes-version: "1.26-1.27" + pod-policies.kyverno.io/autogen-controllers: none + policies.kyverno.io/description: >- + The runtimeClass field of a Pod spec defines which container engine runtime should be used. + In the previous Pod Security Policy controller, defining restrictions on which classes were allowed + was permitted. Limiting runtime classes to only those which have been defined can prevent + unintended running states or Pods which may not come online. This policy restricts the runtimeClass + field to the values `prodclass` or `expclass`. +spec: + validationFailureAction: Enforce + background: false + rules: + - name: prodclass-or-expclass + match: + any: + - resources: + kinds: + - Pod + celPreconditions: + - name: "operation-should-be-create" + expression: "request.operation == 'CREATE'" + validate: + cel: + expressions: + - expression: "!has(object.spec.runtimeClassName) || object.spec.runtimeClassName in ['prodclass', 'expclass']" + message: Only the runtime classes prodclass or expclass may be used. + diff --git a/tekton-cel/block-tekton-task-runs/.chainsaw-test/chainsaw-test.yaml b/tekton-cel/block-tekton-task-runs/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..c89a2230e --- /dev/null +++ b/tekton-cel/block-tekton-task-runs/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,33 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: block-tekton-task-runs +spec: + steps: + - name: step-00 + try: + - assert: + file: crd-assert.yaml + - name: step-01 + try: + - apply: + file: ../block-tekton-task-runs.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: block-tekton-task-runs + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + expect: + - check: + ($error != null): true + file: taskrun.yaml diff --git a/tekton-cel/block-tekton-task-runs/.chainsaw-test/crd-assert.yaml b/tekton-cel/block-tekton-task-runs/.chainsaw-test/crd-assert.yaml new file mode 100755 index 000000000..2934ff501 --- /dev/null +++ b/tekton-cel/block-tekton-task-runs/.chainsaw-test/crd-assert.yaml @@ -0,0 +1,12 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: taskruns.tekton.dev +spec: {} +status: + acceptedNames: + kind: TaskRun + plural: taskruns + singular: taskrun + storedVersions: + - v1 diff --git a/tekton-cel/block-tekton-task-runs/.chainsaw-test/policy-ready.yaml b/tekton-cel/block-tekton-task-runs/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..ca24ce66c --- /dev/null +++ b/tekton-cel/block-tekton-task-runs/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: block-tekton-task-runs +status: + ready: true diff --git a/tekton-cel/block-tekton-task-runs/.chainsaw-test/taskrun.yaml b/tekton-cel/block-tekton-task-runs/.chainsaw-test/taskrun.yaml new file mode 100644 index 000000000..d25f69cb0 --- /dev/null +++ b/tekton-cel/block-tekton-task-runs/.chainsaw-test/taskrun.yaml @@ -0,0 +1,7 @@ +apiVersion: tekton.dev/v1 +kind: TaskRun +metadata: + name: taskrun01 +spec: + taskRef: + name: read-task \ No newline at end of file diff --git a/tekton-cel/block-tekton-task-runs/.kyverno-test/kyverno-test.yaml b/tekton-cel/block-tekton-task-runs/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..f98351850 --- /dev/null +++ b/tekton-cel/block-tekton-task-runs/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,15 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: block-tekton-task-runs +policies: +- ../block-tekton-task-runs.yaml +resources: +- ../.chainsaw-test/taskrun.yaml +results: +- policy: block-tekton-task-runs + rule: check-taskrun-user + kind: TaskRun + resources: + - taskrun01 + result: fail diff --git a/tekton-cel/block-tekton-task-runs/artifacthub-pkg.yml b/tekton-cel/block-tekton-task-runs/artifacthub-pkg.yml new file mode 100644 index 000000000..20a5fe972 --- /dev/null +++ b/tekton-cel/block-tekton-task-runs/artifacthub-pkg.yml @@ -0,0 +1,23 @@ +name: block-tekton-task-runs-cel +version: 1.0.0 +displayName: Block Tekton TaskRun in CEL expressions +description: >- + Restrict creation of TaskRun resources to the Tekton pipelines controller. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/tekton-cel/block-tekton-task-runs/block-tekton-task-runs.yaml + ``` +keywords: + - kyverno + - Tekton + - CEL Expressions +readme: | + Restrict creation of TaskRun resources to the Tekton pipelines controller. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Tekton in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "TaskRun" +digest: 865b8ae10fc53e1bb258db975e122e386610b84cba4bbf7fa4549d93f3affca4 +createdAt: "2024-05-23T18:08:47Z" diff --git a/tekton-cel/block-tekton-task-runs/block-tekton-task-runs.yaml b/tekton-cel/block-tekton-task-runs/block-tekton-task-runs.yaml new file mode 100644 index 000000000..f1f786b34 --- /dev/null +++ b/tekton-cel/block-tekton-task-runs/block-tekton-task-runs.yaml @@ -0,0 +1,38 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: block-tekton-task-runs + annotations: + policies.kyverno.io/title: Block Tekton TaskRun in CEL expressions + policies.kyverno.io/category: Tekton in CEL + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: TaskRun + kyverno.io/kyverno-version: 1.11.0 + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/description: >- + Restrict creation of TaskRun resources to the Tekton pipelines controller. +spec: + validationFailureAction: Audit + background: false + rules: + - name: check-taskrun-user + match: + any: + - resources: + kinds: + - TaskRun + operations: + - CREATE + - UPDATE + exclude: + any: + - subjects: + - kind: User + name: "system:serviceaccount:tekton-pipelines:tekton-pipelines-controller" + validate: + cel: + expressions: + - expression: "false" + message: Creating a TaskRun is not allowed. + diff --git a/tekton-cel/require-tekton-bundle/.chainsaw-test/bad-pipelinerun.yaml b/tekton-cel/require-tekton-bundle/.chainsaw-test/bad-pipelinerun.yaml new file mode 100644 index 000000000..cad412909 --- /dev/null +++ b/tekton-cel/require-tekton-bundle/.chainsaw-test/bad-pipelinerun.yaml @@ -0,0 +1,18 @@ +apiVersion: tekton.dev/v1 +kind: PipelineRun +metadata: + name: badpipelinerun01 +spec: + pipelineRef: + name: mypipeline +--- +apiVersion: tekton.dev/v1 +kind: PipelineRun +metadata: + name: badpipelinerun02 +spec: + pipelineSpec: + tasks: + - name: task1 + taskRef: + name: mytask \ No newline at end of file diff --git a/tekton-cel/require-tekton-bundle/.chainsaw-test/bad-taskrun.yaml b/tekton-cel/require-tekton-bundle/.chainsaw-test/bad-taskrun.yaml new file mode 100644 index 000000000..22ac6a221 --- /dev/null +++ b/tekton-cel/require-tekton-bundle/.chainsaw-test/bad-taskrun.yaml @@ -0,0 +1,7 @@ +apiVersion: tekton.dev/v1 +kind: TaskRun +metadata: + name: badtaskrun01 +spec: + taskRef: + name: read-task \ No newline at end of file diff --git a/tekton-cel/require-tekton-bundle/.chainsaw-test/chainsaw-test.yaml b/tekton-cel/require-tekton-bundle/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..1ee775051 --- /dev/null +++ b/tekton-cel/require-tekton-bundle/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,44 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: require-tekton-bundle +spec: + steps: + - name: step-00 + try: + - assert: + file: crd-taskrun-assert.yaml + - assert: + file: crd-pipelinerun-assert.yaml + - name: step-01 + try: + - apply: + file: ../require-tekton-bundle.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: require-tekton-bundle + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: good-taskrun.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-taskrun.yaml + - apply: + file: good-pipelinerun.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-pipelinerun.yaml diff --git a/tekton-cel/require-tekton-bundle/.chainsaw-test/crd-pipelinerun-assert.yaml b/tekton-cel/require-tekton-bundle/.chainsaw-test/crd-pipelinerun-assert.yaml new file mode 100755 index 000000000..81ab957e7 --- /dev/null +++ b/tekton-cel/require-tekton-bundle/.chainsaw-test/crd-pipelinerun-assert.yaml @@ -0,0 +1,12 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: pipelineruns.tekton.dev +spec: {} +status: + acceptedNames: + kind: PipelineRun + plural: pipelineruns + singular: pipelinerun + storedVersions: + - v1 diff --git a/tekton-cel/require-tekton-bundle/.chainsaw-test/crd-taskrun-assert.yaml b/tekton-cel/require-tekton-bundle/.chainsaw-test/crd-taskrun-assert.yaml new file mode 100755 index 000000000..2934ff501 --- /dev/null +++ b/tekton-cel/require-tekton-bundle/.chainsaw-test/crd-taskrun-assert.yaml @@ -0,0 +1,12 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: taskruns.tekton.dev +spec: {} +status: + acceptedNames: + kind: TaskRun + plural: taskruns + singular: taskrun + storedVersions: + - v1 diff --git a/tekton-cel/require-tekton-bundle/.chainsaw-test/good-pipelinerun.yaml b/tekton-cel/require-tekton-bundle/.chainsaw-test/good-pipelinerun.yaml new file mode 100644 index 000000000..21403752f --- /dev/null +++ b/tekton-cel/require-tekton-bundle/.chainsaw-test/good-pipelinerun.yaml @@ -0,0 +1,8 @@ +apiVersion: tekton.dev/v1 +kind: PipelineRun +metadata: + name: goodpipelinerun01 +spec: + pipelineRef: + name: mypipeline + bundle: docker.io/foo/bar \ No newline at end of file diff --git a/tekton-cel/require-tekton-bundle/.chainsaw-test/good-taskrun.yaml b/tekton-cel/require-tekton-bundle/.chainsaw-test/good-taskrun.yaml new file mode 100644 index 000000000..51cc014b7 --- /dev/null +++ b/tekton-cel/require-tekton-bundle/.chainsaw-test/good-taskrun.yaml @@ -0,0 +1,8 @@ +apiVersion: tekton.dev/v1 +kind: TaskRun +metadata: + name: goodtaskrun01 +spec: + taskRef: + name: echo-task + bundle: docker.io/foo/bar \ No newline at end of file diff --git a/tekton-cel/require-tekton-bundle/.chainsaw-test/policy-ready.yaml b/tekton-cel/require-tekton-bundle/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..fe3d051fb --- /dev/null +++ b/tekton-cel/require-tekton-bundle/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: require-tekton-bundle +status: + ready: true diff --git a/tekton-cel/require-tekton-bundle/.kyverno-test/kyverno-test.yaml b/tekton-cel/require-tekton-bundle/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..5c6b040b6 --- /dev/null +++ b/tekton-cel/require-tekton-bundle/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,37 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: require-tekton-bundle +policies: +- ../require-tekton-bundle.yaml +resources: +- ../.chainsaw-test/bad-pipelinerun.yaml +- ../.chainsaw-test/bad-taskrun.yaml +- ../.chainsaw-test/good-pipelinerun.yaml +- ../.chainsaw-test/good-taskrun.yaml +results: +- policy: require-tekton-bundle + rule: check-bundle-pipelinerun + kind: PipelineRun + resources: + - badpipelinerun01 + - badpipelinerun02 + result: fail +- policy: require-tekton-bundle + rule: check-bundle-pipelinerun + kind: PipelineRun + resources: + - goodpipelinerun01 + result: pass +- policy: require-tekton-bundle + rule: check-bundle-taskrun + kind: TaskRun + resources: + - badtaskrun01 + result: fail +- policy: require-tekton-bundle + rule: check-bundle-taskrun + kind: TaskRun + resources: + - goodtaskrun01 + result: pass diff --git a/tekton-cel/require-tekton-bundle/artifacthub-pkg.yml b/tekton-cel/require-tekton-bundle/artifacthub-pkg.yml new file mode 100644 index 000000000..67bdf90ef --- /dev/null +++ b/tekton-cel/require-tekton-bundle/artifacthub-pkg.yml @@ -0,0 +1,23 @@ +name: require-tekton-bundle-cel +version: 1.0.0 +displayName: Require Tekton Bundle in CEL expressions +description: >- + PipelineRun and TaskRun resources must be executed from a bundle +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/tekton-cel/require-tekton-bundle/require-tekton-bundle.yaml + ``` +keywords: + - kyverno + - Tekton + - CEL Expressions +readme: | + PipelineRun and TaskRun resources must be executed from a bundle + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Tekton in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "TaskRun, PipelineRun" +digest: 396315ccb0132309267847614372230dbab14ab9935a1aac800d96981da37d10 +createdAt: "2024-05-24T04:26:34Z" diff --git a/tekton-cel/require-tekton-bundle/require-tekton-bundle.yaml b/tekton-cel/require-tekton-bundle/require-tekton-bundle.yaml new file mode 100644 index 000000000..359ae7f1e --- /dev/null +++ b/tekton-cel/require-tekton-bundle/require-tekton-bundle.yaml @@ -0,0 +1,44 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: require-tekton-bundle + annotations: + policies.kyverno.io/title: Require Tekton Bundle in CEL expressions + policies.kyverno.io/category: Tekton in CEL + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: TaskRun, PipelineRun + kyverno.io/kyverno-version: 1.11.0 + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/description: >- + PipelineRun and TaskRun resources must be executed from a bundle +spec: + validationFailureAction: Audit + background: true + rules: + - name: check-bundle-pipelinerun + match: + any: + - resources: + kinds: + - PipelineRun + operations: + - CREATE + - UPDATE + validate: + cel: + expressions: + - expression: "has(object.spec.pipelineRef) && has(object.spec.pipelineRef.bundle) && object.spec.pipelineRef.bundle != ''" + message: "A bundle is required." + - name: check-bundle-taskrun + match: + any: + - resources: + kinds: + - TaskRun + validate: + cel: + expressions: + - expression: "has(object.spec.taskRef) && has(object.spec.taskRef.bundle) && object.spec.taskRef.bundle != ''" + message: "A bundle is required." + diff --git a/tekton/require-tekton-bundle/.kyverno-test/kyverno-test.yaml b/tekton/require-tekton-bundle/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..5c6b040b6 --- /dev/null +++ b/tekton/require-tekton-bundle/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,37 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: require-tekton-bundle +policies: +- ../require-tekton-bundle.yaml +resources: +- ../.chainsaw-test/bad-pipelinerun.yaml +- ../.chainsaw-test/bad-taskrun.yaml +- ../.chainsaw-test/good-pipelinerun.yaml +- ../.chainsaw-test/good-taskrun.yaml +results: +- policy: require-tekton-bundle + rule: check-bundle-pipelinerun + kind: PipelineRun + resources: + - badpipelinerun01 + - badpipelinerun02 + result: fail +- policy: require-tekton-bundle + rule: check-bundle-pipelinerun + kind: PipelineRun + resources: + - goodpipelinerun01 + result: pass +- policy: require-tekton-bundle + rule: check-bundle-taskrun + kind: TaskRun + resources: + - badtaskrun01 + result: fail +- policy: require-tekton-bundle + rule: check-bundle-taskrun + kind: TaskRun + resources: + - goodtaskrun01 + result: pass diff --git a/tekton/require-tekton-namespace-pipelinerun/.kyverno-test/kyverno-test.yaml b/tekton/require-tekton-namespace-pipelinerun/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..141034c08 --- /dev/null +++ b/tekton/require-tekton-namespace-pipelinerun/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,22 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: require-tekton-namespace-pipelinerun +policies: +- ../require-tekton-namespace-pipelinerun.yaml +resources: +- ../.chainsaw-test/bad-pipelinerun.yaml +- ../.chainsaw-test/good-pipelinerun.yaml +results: +- policy: require-tekton-namespace-pipelinerun + rule: check-pipelinerun-namespace + kind: PipelineRun + resources: + - badpipelinerun01 + result: fail +- policy: require-tekton-namespace-pipelinerun + rule: check-pipelinerun-namespace + kind: PipelineRun + resources: + - goodpipelinerun01 + result: pass diff --git a/velero-cel/block-velero-restore/.chainsaw-test/bad-restore.yaml b/velero-cel/block-velero-restore/.chainsaw-test/bad-restore.yaml new file mode 100644 index 000000000..84e3ec4e6 --- /dev/null +++ b/velero-cel/block-velero-restore/.chainsaw-test/bad-restore.yaml @@ -0,0 +1,21 @@ +apiVersion: velero.io/v1 +kind: Restore +metadata: + name: badrestore01 +spec: + backupName: a-very-special-backup + namespaceMapping: + foo: kube-system +--- +apiVersion: velero.io/v1 +kind: Restore +metadata: + name: badrestore02 +spec: + backupName: a-very-special-backup + includedNamespaces: + - '*' + excludedNamespaces: + - some-namespace + namespaceMapping: + foo: kube-node-lease \ No newline at end of file diff --git a/velero-cel/block-velero-restore/.chainsaw-test/chainsaw-test.yaml b/velero-cel/block-velero-restore/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..d63f10b09 --- /dev/null +++ b/velero-cel/block-velero-restore/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,35 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: block-velero-restore +spec: + steps: + - name: step-00 + try: + - assert: + file: crd-restore-assert.yaml + - name: step-01 + try: + - apply: + file: ../block-velero-restore.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: block-velero-restore + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: good-restore.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-restore.yaml diff --git a/velero-cel/block-velero-restore/.chainsaw-test/crd-restore-assert.yaml b/velero-cel/block-velero-restore/.chainsaw-test/crd-restore-assert.yaml new file mode 100755 index 000000000..37aa83b76 --- /dev/null +++ b/velero-cel/block-velero-restore/.chainsaw-test/crd-restore-assert.yaml @@ -0,0 +1,13 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: restores.velero.io +spec: {} +status: + acceptedNames: + kind: Restore + listKind: RestoreList + plural: restores + singular: restore + storedVersions: + - v1 diff --git a/velero-cel/block-velero-restore/.chainsaw-test/good-restore.yaml b/velero-cel/block-velero-restore/.chainsaw-test/good-restore.yaml new file mode 100644 index 000000000..43052e805 --- /dev/null +++ b/velero-cel/block-velero-restore/.chainsaw-test/good-restore.yaml @@ -0,0 +1,28 @@ +apiVersion: velero.io/v1 +kind: Restore +metadata: + name: goodrestore01 +spec: + backupName: a-very-special-backup + namespaceMapping: + foo: bar +--- +apiVersion: velero.io/v1 +kind: Restore +metadata: + name: goodrestore02 +spec: + backupName: a-very-special-backup + includedNamespaces: + - '*' + excludedNamespaces: + - some-namespace +--- +apiVersion: velero.io/v1 +kind: Restore +metadata: + name: goodrestore03 +spec: + backupName: a-very-special-backup + namespaceMapping: + kube-system: bar \ No newline at end of file diff --git a/velero-cel/block-velero-restore/.chainsaw-test/policy-ready.yaml b/velero-cel/block-velero-restore/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..df978e12d --- /dev/null +++ b/velero-cel/block-velero-restore/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: block-velero-restore +status: + ready: true diff --git a/velero-cel/block-velero-restore/.kyverno-test/kyverno-test.yaml b/velero-cel/block-velero-restore/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..64ab3c92a --- /dev/null +++ b/velero-cel/block-velero-restore/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,22 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: block-velero-restore +policies: +- ../block-velero-restore.yaml +resources: +- resource.yaml +results: +- kind: Restore + policy: block-velero-restore + resources: + - badrestore01 + result: fail + rule: block-velero-restore-to-protected-namespace +- kind: Restore + policy: block-velero-restore + resources: + - restore-without-namespace-mapping + - goodrestore01 + result: pass + rule: block-velero-restore-to-protected-namespace diff --git a/velero-cel/block-velero-restore/.kyverno-test/resource.yaml b/velero-cel/block-velero-restore/.kyverno-test/resource.yaml new file mode 100644 index 000000000..9a7a09120 --- /dev/null +++ b/velero-cel/block-velero-restore/.kyverno-test/resource.yaml @@ -0,0 +1,52 @@ +####################################################### +## Rule: block-velero-restore-to-protected-namespace ## +####################################################### +###### Restore - Bad +--- +apiVersion: velero.io/v1 +kind: Restore +metadata: + name: badrestore01 + namespace: velero +spec: + backupName: my-backup + includedResources: + - '*' + namespaceMapping: + default: kube-system +restorePVs: true +--- +###### Restore - Good +apiVersion: velero.io/v1 +kind: Restore +metadata: + name: restore-without-namespace-mapping + namespace: velero +spec: + backupName: my-backup + excludedResources: + - nodes + - events + - events.events.k8s.io + - backups.velero.io + - restores.velero.io + - resticrepositories.velero.io + - csinodes.storage.k8s.io + - volumeattachments.storage.k8s.io + - backuprepositories.velero.io + includedNamespaces: + - '*' +--- +apiVersion: velero.io/v1 +kind: Restore +metadata: + name: goodrestore01 + namespace: velero +spec: + backupName: my-backup + includedResources: + - '*' + namespaceMapping: + default: ingress-nginx +restorePVs: true +--- diff --git a/velero-cel/block-velero-restore/artifacthub-pkg.yml b/velero-cel/block-velero-restore/artifacthub-pkg.yml new file mode 100644 index 000000000..31d9b5ce7 --- /dev/null +++ b/velero-cel/block-velero-restore/artifacthub-pkg.yml @@ -0,0 +1,31 @@ +name: block-velero-restore-cel +version: 1.0.0 +displayName: Block Velero Restore in CEL expressions +description: >- + Velero allows on backup and restore operations and is designed to be run with full cluster admin permissions. + It allows on cross namespace restore operations, which means you can restore backup of namespace A to namespace B. + This policy protect restore operation into system or any protected namespaces, listed in deny condition section. + It checks the Restore CRD object and its namespaceMapping field. If destination match protected namespace + then operation fails and warning message is throw. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/velero-cel/block-velero-restore/block-velero-restore.yaml + ``` +keywords: + - velero + - kyverno + - CEL Expressions +readme: | + Velero allows on backup and restore operations and is designed to be run with full cluster admin permissions. + It allows on cross namespace restore operations, which means you can restore backup of namespace A to namespace B. + This policy protect restore operation into system or any protected namespaces, listed in deny condition section. + It checks the Restore CRD object and its namespaceMapping field. If destination match protected namespace + then operation fails and warning message is throw. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Velero in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Restore" +digest: 375151c611cea4a9da84b11a69c580498e0688db59bddf056770ba416df8982e +createdAt: "2024-05-23T17:20:18Z" diff --git a/velero-cel/block-velero-restore/block-velero-restore.yaml b/velero-cel/block-velero-restore/block-velero-restore.yaml new file mode 100644 index 000000000..e1dd8aeb9 --- /dev/null +++ b/velero-cel/block-velero-restore/block-velero-restore.yaml @@ -0,0 +1,38 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: block-velero-restore + annotations: + policies.kyverno.io/title: Block Velero Restore to Protected Namespace in CEL expressions + policies.kyverno.io/category: Velero in CEL + policies.kyverno.io/subject: Restore + kyverno.io/kyverno-version: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/description: >- + Velero allows on backup and restore operations and is designed to be run with full cluster admin permissions. + It allows on cross namespace restore operations, which means you can restore backup of namespace A to namespace B. + This policy protect restore operation into system or any protected namespaces, listed in deny condition section. + It checks the Restore CRD object and its namespaceMapping field. If destination match protected namespace + then operation fails and warning message is throw. +spec: + validationFailureAction: Audit + background: false + rules: + - name: block-velero-restore-to-protected-namespace + match: + any: + - resources: + kinds: + - velero.io/v1/Restore + operations: + - CREATE + - UPDATE + validate: + cel: + variables: + - name: namespaceMappingValues + expression: "has(object.spec.namespaceMapping) ? object.spec.namespaceMapping.map(nsmap, object.spec.namespaceMapping[nsmap]) : []" + expressions: + - expression: "!variables.namespaceMappingValues.exists(val, val in ['kube-system', 'kube-node-lease'])" + messageExpression: "'Warning! Restore to protected namespace: ' + variables.namespaceMappingValues.join(', ') + ' is not allowed!'" + diff --git a/velero-cel/validate-cron-schedule/.chainsaw-test/bad-schedule.yaml b/velero-cel/validate-cron-schedule/.chainsaw-test/bad-schedule.yaml new file mode 100644 index 000000000..e08e5d4d9 --- /dev/null +++ b/velero-cel/validate-cron-schedule/.chainsaw-test/bad-schedule.yaml @@ -0,0 +1,19 @@ +apiVersion: velero.io/v1 +kind: Schedule +metadata: + name: badschedule01 +spec: + schedule: 0 7 * * * * + template: + includedNamespaces: + - 'default' +--- +apiVersion: velero.io/v1 +kind: Schedule +metadata: + name: badschedule02 +spec: + schedule: 0 7 * */ * + template: + includedNamespaces: + - 'default' diff --git a/velero-cel/validate-cron-schedule/.chainsaw-test/chainsaw-test.yaml b/velero-cel/validate-cron-schedule/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..a4df56dcc --- /dev/null +++ b/velero-cel/validate-cron-schedule/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,35 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: validate-cron-schedule +spec: + steps: + - name: step-00 + try: + - assert: + file: crd-schedule-assert.yaml + - name: step-01 + try: + - apply: + file: ../validate-cron-schedule.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: validate-cron-schedule + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: good-schedule.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-schedule.yaml diff --git a/velero-cel/validate-cron-schedule/.chainsaw-test/crd-schedule-assert.yaml b/velero-cel/validate-cron-schedule/.chainsaw-test/crd-schedule-assert.yaml new file mode 100755 index 000000000..9b0937ad9 --- /dev/null +++ b/velero-cel/validate-cron-schedule/.chainsaw-test/crd-schedule-assert.yaml @@ -0,0 +1,13 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: schedules.velero.io +spec: {} +status: + acceptedNames: + kind: Schedule + listKind: ScheduleList + plural: schedules + singular: schedule + storedVersions: + - v1 diff --git a/velero-cel/validate-cron-schedule/.chainsaw-test/good-schedule.yaml b/velero-cel/validate-cron-schedule/.chainsaw-test/good-schedule.yaml new file mode 100644 index 000000000..41e2f4914 --- /dev/null +++ b/velero-cel/validate-cron-schedule/.chainsaw-test/good-schedule.yaml @@ -0,0 +1,11 @@ +apiVersion: velero.io/v1 +kind: Schedule +metadata: + name: goodsched01 +spec: + schedule: 0 7 * * * + template: + includedNamespaces: + - '*' + excludedNamespaces: + - some-namespace \ No newline at end of file diff --git a/velero-cel/validate-cron-schedule/.chainsaw-test/policy-ready.yaml b/velero-cel/validate-cron-schedule/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..11afe59c1 --- /dev/null +++ b/velero-cel/validate-cron-schedule/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: validate-cron-schedule +status: + ready: true diff --git a/velero-cel/validate-cron-schedule/.kyverno-test/kyverno-test.yaml b/velero-cel/validate-cron-schedule/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..942f49cd4 --- /dev/null +++ b/velero-cel/validate-cron-schedule/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,21 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: validate-cron-schedule +policies: +- ../validate-cron-schedule.yaml +resources: +- resources.yaml +results: +- kind: Schedule + policy: validate-cron-schedule + resources: + - badschedule01 + result: fail + rule: validate-cron +- kind: Schedule + policy: validate-cron-schedule + resources: + - goodschedule01 + result: pass + rule: validate-cron diff --git a/velero-cel/validate-cron-schedule/.kyverno-test/resources.yaml b/velero-cel/validate-cron-schedule/.kyverno-test/resources.yaml new file mode 100644 index 000000000..dd6a0bee1 --- /dev/null +++ b/velero-cel/validate-cron-schedule/.kyverno-test/resources.yaml @@ -0,0 +1,20 @@ +--- +apiVersion: velero.io/v1 +kind: Schedule +metadata: + name: goodschedule01 +spec: + schedule: 0 7 * * * + template: + includedNamespaces: + - 'default' +--- +apiVersion: velero.io/v1 +kind: Schedule +metadata: + name: badschedule01 +spec: + schedule: 0 7 * * * * + template: + includedNamespaces: + - 'default' diff --git a/velero-cel/validate-cron-schedule/artifacthub-pkg.yml b/velero-cel/validate-cron-schedule/artifacthub-pkg.yml new file mode 100644 index 000000000..0a495f085 --- /dev/null +++ b/velero-cel/validate-cron-schedule/artifacthub-pkg.yml @@ -0,0 +1,25 @@ +name: validate-cron-schedule-cel +version: 1.0.0 +displayName: Validate Cron Schedule in CEL expressions +description: >- + A Velero Schedule is given in Cron format and must be accurate to ensure + operation. This policy validates that the schedule is a valid Cron format. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/velero-cel/validate-cron-schedule/validate-cron-schedule.yaml + ``` +keywords: + - velero + - kyverno + - CEL Expressions +readme: | + A Velero Schedule is given in Cron format and must be accurate to ensure + operation. This policy validates that the schedule is a valid Cron format. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Velero in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Schedule" +digest: a42222eee403614bcd88071eb5a6cdf15630cb27e0e03ea318511f359b63d899 +createdAt: "2024-05-23T17:34:19Z" diff --git a/velero-cel/validate-cron-schedule/validate-cron-schedule.yaml b/velero-cel/validate-cron-schedule/validate-cron-schedule.yaml new file mode 100644 index 000000000..86f135f8b --- /dev/null +++ b/velero-cel/validate-cron-schedule/validate-cron-schedule.yaml @@ -0,0 +1,33 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: validate-cron-schedule + annotations: + policies.kyverno.io/title: Validate Schedule in CEL expressions + policies.kyverno.io/category: Velero in CEL + policies.kyverno.io/subject: Schedule + kyverno.io/kyverno-version: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/description: >- + A Velero Schedule is given in Cron format and must be accurate to ensure + operation. This policy validates that the schedule is a valid Cron format. +spec: + background: true + validationFailureAction: Audit + rules: + - name: validate-cron + match: + any: + - resources: + kinds: + - velero.io/v1/Schedule + operations: + - CREATE + - UPDATE + validate: + cel: + expressions: + - expression: >- + object.spec.schedule.matches('^((?:\\*|[0-5]?[0-9](?:(?:-[0-5]?[0-9])|(?:,[0-5]?[0-9])+)?)(?:\\/[0-9]+)?)\\s+((?:\\*|(?:1?[0-9]|2[0-3])(?:(?:-(?:1?[0-9]|2[0-3]))|(?:,(?:1?[0-9]|2[0-3]))+)?)(?:\\/[0-9]+)?)\\s+((?:\\*|(?:[1-9]|[1-2][0-9]|3[0-1])(?:(?:-(?:[1-9]|[1-2][0-9]|3[0-1]))|(?:,(?:[1-9]|[1-2][0-9]|3[0-1]))+)?)(?:\\/[0-9]+)?)\\s+((?:\\*|(?:[1-9]|1[0-2])(?:(?:-(?:[1-9]|1[0-2]))|(?:,(?:[1-9]|1[0-2]))+)?)(?:\\/[0-9]+)?)\\s+((?:\\*|[0-7](?:-[0-7]|(?:,[0-7])+)?)(?:\\/[0-9]+)?)$') + message: The backup schedule must be in a valid cron format. +