diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 718a3a619..d07a3f019 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -53,6 +53,8 @@ jobs: - ^other$/^re[c-q] - ^other$/^res - ^other$/^[s-z] + - ^other-cel$/^a + - ^other-cel$/^[b-d] - ^other-cel$/^[m-q] - ^pod-security$ - ^pod-security-cel$ diff --git a/other-cel/allowed-annotations/.chainsaw-test/chainsaw-test.yaml b/other-cel/allowed-annotations/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..0b3284bbd --- /dev/null +++ b/other-cel/allowed-annotations/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,39 @@ +# 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: allowed-annotations +spec: + steps: + - name: step-01 + try: + - apply: + file: ../allowed-annotations.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: allowed-annotations + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: pod-good.yaml + - apply: + file: podcontroller-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: pod-bad.yaml + - apply: + expect: + - check: + ($error != null): true + file: podcontroller-bad.yaml + diff --git a/other-cel/allowed-annotations/.chainsaw-test/pod-bad.yaml b/other-cel/allowed-annotations/.chainsaw-test/pod-bad.yaml new file mode 100644 index 000000000..942e56ff7 --- /dev/null +++ b/other-cel/allowed-annotations/.chainsaw-test/pod-bad.yaml @@ -0,0 +1,47 @@ +apiVersion: v1 +kind: Pod +metadata: + annotations: + fluxcd.io/cat: meow + name: badpod01 +spec: + containers: + - name: pod01-01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + annotations: + foo: bar + fluxcd.io/foo: bar + name: badpod02 +spec: + containers: + - name: pod02-01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + annotations: + fluxcd.io/bar: foo + foo: bar + name: badpod03 +spec: + containers: + - name: pod-01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + annotations: + fluxcd.io/bar: foo + fluxcd.io/cow: moo + name: badpod04 +spec: + containers: + - name: pod-01 + image: busybox:1.35 + diff --git a/other-cel/allowed-annotations/.chainsaw-test/pod-good.yaml b/other-cel/allowed-annotations/.chainsaw-test/pod-good.yaml new file mode 100644 index 000000000..a71a48fcb --- /dev/null +++ b/other-cel/allowed-annotations/.chainsaw-test/pod-good.yaml @@ -0,0 +1,45 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 +spec: + containers: + - name: pod01-01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + annotations: + foo: bar + fluxcd.io/cow: ox + fluxcd.io/dog: cat + name: goodpod02 +spec: + containers: + - name: pod02-01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + annotations: + foo: bar + name: goodpod03 +spec: + containers: + - name: pod-01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + annotations: + fluxcd.io/cow: moo + foo: bar + name: goodpod04 +spec: + containers: + - name: pod-01 + image: busybox:1.35 + diff --git a/other-cel/allowed-annotations/.chainsaw-test/podcontroller-bad.yaml b/other-cel/allowed-annotations/.chainsaw-test/podcontroller-bad.yaml new file mode 100644 index 000000000..56f826e9a --- /dev/null +++ b/other-cel/allowed-annotations/.chainsaw-test/podcontroller-bad.yaml @@ -0,0 +1,94 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: busybox + name: baddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + strategy: {} + template: + metadata: + annotations: + foo: bar + fluxcd.io/foo: bar + labels: + app: busybox + spec: + containers: + - name: bb-01 + image: busybox:1.35 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: busybox + name: baddeployment02 +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + strategy: {} + template: + metadata: + annotations: + fluxcd.io/cat: meow + fluxcd.io/cow: moo + labels: + app: busybox + spec: + containers: + - name: bb-01 + image: busybox:1.35 +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob01 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + metadata: + annotations: + foo: bar + fluxcd.io/foo: bar + spec: + containers: + - name: hello + image: busybox:1.35 + imagePullPolicy: IfNotPresent + command: + - "sleep" + - "3600" + restartPolicy: OnFailure +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob02 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + metadata: + annotations: + fluxcd.io/cat: meow + fluxcd.io/cow: moo + spec: + containers: + - name: hello + image: busybox:1.35 + imagePullPolicy: IfNotPresent + command: + - "sleep" + - "3600" + restartPolicy: OnFailure + diff --git a/other-cel/allowed-annotations/.chainsaw-test/podcontroller-good.yaml b/other-cel/allowed-annotations/.chainsaw-test/podcontroller-good.yaml new file mode 100644 index 000000000..41f409f6c --- /dev/null +++ b/other-cel/allowed-annotations/.chainsaw-test/podcontroller-good.yaml @@ -0,0 +1,132 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: busybox + name: gooddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + strategy: {} + template: + metadata: + annotations: + foo: bar + labels: + app: busybox + spec: + containers: + - name: bb-01 + image: busybox:1.35 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: busybox + name: gooddeployment02 +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + strategy: {} + template: + metadata: + annotations: + fluxcd.io/cow: moo + fluxcd.io/dog: bark + labels: + app: busybox + spec: + containers: + - name: bb-01 + image: busybox:1.35 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: busybox + name: gooddeployment03 +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + strategy: {} + template: + metadata: + labels: + app: busybox + spec: + containers: + - name: bb-01 + image: busybox:1.35 +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob01 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + metadata: + annotations: + foo: bar + spec: + containers: + - name: hello + image: busybox:1.35 + imagePullPolicy: IfNotPresent + command: + - "sleep" + - "3600" + restartPolicy: OnFailure +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob02 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + metadata: + annotations: + fluxcd.io/cow: moo + fluxcd.io/dog: bark + spec: + containers: + - name: hello + image: busybox:1.35 + imagePullPolicy: IfNotPresent + command: + - "sleep" + - "3600" + restartPolicy: OnFailure +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob03 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + spec: + containers: + - name: hello + image: busybox:1.35 + imagePullPolicy: IfNotPresent + command: + - "sleep" + - "3600" + restartPolicy: OnFailure + diff --git a/other-cel/allowed-annotations/.chainsaw-test/policy-ready.yaml b/other-cel/allowed-annotations/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..e86a1d14c --- /dev/null +++ b/other-cel/allowed-annotations/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: allowed-annotations +status: + ready: true + diff --git a/other-cel/allowed-annotations/.kyverno-test/kyverno-test.yaml b/other-cel/allowed-annotations/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..4ebfa364c --- /dev/null +++ b/other-cel/allowed-annotations/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,22 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: allowed-annotations +policies: +- ../allowed-annotations.yaml +resources: +- resource.yaml +results: +- kind: Pod + policy: allowed-annotations + resources: + - badpod01 + result: fail + rule: allowed-fluxcd-annotations +- kind: Pod + policy: allowed-annotations + resources: + - goodpod01 + result: pass + rule: allowed-fluxcd-annotations + diff --git a/other-cel/allowed-annotations/.kyverno-test/resource.yaml b/other-cel/allowed-annotations/.kyverno-test/resource.yaml new file mode 100644 index 000000000..659009b95 --- /dev/null +++ b/other-cel/allowed-annotations/.kyverno-test/resource.yaml @@ -0,0 +1,29 @@ +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 + annotations: + fluxcd.io/bat: flap + corp.com/bar: baz + somethingsimple: else +spec: + automountServiceAccountToken: false + containers: + - name: busybox + image: registry.corp/sdf3vhadfa:1.28 +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 + annotations: + fluxcd.io/dog: bark + corp.com/bar: baz + somethingsimple: else +spec: + automountServiceAccountToken: false + containers: + - name: busybox + image: registry.corp/sdf3vhadfa:1.28 +--- diff --git a/other-cel/allowed-annotations/allowed-annotations.yaml b/other-cel/allowed-annotations/allowed-annotations.yaml new file mode 100644 index 000000000..6832fa2d1 --- /dev/null +++ b/other-cel/allowed-annotations/allowed-annotations.yaml @@ -0,0 +1,35 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: allowed-annotations + annotations: + policies.kyverno.io/title: Allowed Annotations in CEL expressions + policies.kyverno.io/category: Other 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, Annotation + policies.kyverno.io/description: >- + Rather than creating a deny list of annotations, it may be more useful + to invert that list and create an allow list which then denies any others. + This policy demonstrates how to allow two annotations with a specific key + name of fluxcd.io/ while denying others that do not meet the pattern. +spec: + validationFailureAction: Audit + background: true + rules: + - name: allowed-fluxcd-annotations + match: + any: + - resources: + kinds: + - Pod + validate: + cel: + expressions: + - expression: >- + !has(object.metadata.annotations) || + object.metadata.annotations.all(annotation, !annotation.contains('fluxcd.io/') || annotation in ['fluxcd.io/cow', 'fluxcd.io/dog']) + message: The only approved FluxCD annotations are `fluxcd.io/cow` and `fluxcd.io/dog`. + diff --git a/other-cel/allowed-annotations/artifacthub-pkg.yml b/other-cel/allowed-annotations/artifacthub-pkg.yml new file mode 100644 index 000000000..e549978d1 --- /dev/null +++ b/other-cel/allowed-annotations/artifacthub-pkg.yml @@ -0,0 +1,24 @@ +name: allowed-annotations-cel +version: 1.0.0 +displayName: Allowed Annotations in CEL expressions +description: >- + Rather than creating a deny list of annotations, it may be more useful to invert that list and create an allow list which then denies any others. This policy demonstrates how to allow two annotations with a specific key name of fluxcd.io/ while denying others that do not meet the pattern. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/other-cel/allowed-annotations/allowed-annotations.yaml + ``` +keywords: + - kyverno + - Other + - CEL Expressions +readme: | + Rather than creating a deny list of annotations, it may be more useful to invert that list and create an allow list which then denies any others. This policy demonstrates how to allow two annotations with a specific key name of fluxcd.io/ while denying others that do not meet the pattern. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Other in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Pod, Annotation" +digest: c917791b2d807cd00117591ba8fa05e7453aa3a8e0c9c1a8d20165ac63150e0c +createdAt: "2024-03-17T14:04:46Z" + diff --git a/other-cel/allowed-pod-priorities/.chainsaw-test/chainsaw-test.yaml b/other-cel/allowed-pod-priorities/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..8bd44427b --- /dev/null +++ b/other-cel/allowed-pod-priorities/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,45 @@ +# 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: allowed-pod-priorities +spec: + steps: + - name: step-01 + try: + - apply: + file: cm.yaml + - apply: + file: ns.yaml + - apply: + file: pc.yaml + - apply: + file: ../allowed-pod-priorities.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: allowed-podpriorities + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: pod-good.yaml + - apply: + file: podcontroller-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: pod-bad.yaml + - apply: + expect: + - check: + ($error != null): true + file: podcontroller-bad.yaml + diff --git a/other-cel/allowed-pod-priorities/.chainsaw-test/cm.yaml b/other-cel/allowed-pod-priorities/.chainsaw-test/cm.yaml new file mode 100644 index 000000000..555b7e5dc --- /dev/null +++ b/other-cel/allowed-pod-priorities/.chainsaw-test/cm.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +data: + pod-priority-ns: "high, medium, low" + no-priority-ns: foo +kind: ConfigMap +metadata: + name: allowed-pod-priorities + namespace: default + diff --git a/other-cel/allowed-pod-priorities/.chainsaw-test/ns.yaml b/other-cel/allowed-pod-priorities/.chainsaw-test/ns.yaml new file mode 100644 index 000000000..5a95db206 --- /dev/null +++ b/other-cel/allowed-pod-priorities/.chainsaw-test/ns.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: pod-priority-ns +--- +apiVersion: v1 +kind: Namespace +metadata: + name: no-priority-ns + diff --git a/other-cel/allowed-pod-priorities/.chainsaw-test/pc.yaml b/other-cel/allowed-pod-priorities/.chainsaw-test/pc.yaml new file mode 100644 index 000000000..817a2a8eb --- /dev/null +++ b/other-cel/allowed-pod-priorities/.chainsaw-test/pc.yaml @@ -0,0 +1,32 @@ +apiVersion: scheduling.k8s.io/v1 +kind: PriorityClass +metadata: + name: high +value: 1000000 +globalDefault: false +description: "This priority class should be used for XYZ service pods only." +--- +apiVersion: scheduling.k8s.io/v1 +kind: PriorityClass +metadata: + name: medium +value: 500000 +globalDefault: false +description: "This priority class should be used for XYZ service pods only." +--- +apiVersion: scheduling.k8s.io/v1 +kind: PriorityClass +metadata: + name: low +value: 100000 +globalDefault: false +description: "This priority class should be used for XYZ service pods only." +--- +apiVersion: scheduling.k8s.io/v1 +kind: PriorityClass +metadata: + name: foo +value: 100000 +globalDefault: false +description: "This priority class should be used for XYZ service pods only." + diff --git a/other-cel/allowed-pod-priorities/.chainsaw-test/pod-bad.yaml b/other-cel/allowed-pod-priorities/.chainsaw-test/pod-bad.yaml new file mode 100644 index 000000000..a74a0559a --- /dev/null +++ b/other-cel/allowed-pod-priorities/.chainsaw-test/pod-bad.yaml @@ -0,0 +1,22 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 + namespace: pod-priority-ns +spec: + containers: + - name: pod01 + image: busybox:1.35 + priorityClassName: foo +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod02 + namespace: no-priority-ns +spec: + containers: + - name: pod01 + image: busybox:1.35 + priorityClassName: low + diff --git a/other-cel/allowed-pod-priorities/.chainsaw-test/pod-good.yaml b/other-cel/allowed-pod-priorities/.chainsaw-test/pod-good.yaml new file mode 100644 index 000000000..cd959257d --- /dev/null +++ b/other-cel/allowed-pod-priorities/.chainsaw-test/pod-good.yaml @@ -0,0 +1,52 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 + namespace: pod-priority-ns +spec: + containers: + - name: pod01 + image: busybox:1.35 + priorityClassName: high +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod02 + namespace: pod-priority-ns +spec: + containers: + - name: pod01 + image: busybox:1.35 + priorityClassName: low +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod03 +spec: + containers: + - name: pod01 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod04 + namespace: no-priority-ns +spec: + containers: + - name: pod01 + image: busybox:1.35 + priorityClassName: foo +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod05 +spec: + containers: + - name: pod01 + image: busybox:1.35 + priorityClassName: low + diff --git a/other-cel/allowed-pod-priorities/.chainsaw-test/podcontroller-bad.yaml b/other-cel/allowed-pod-priorities/.chainsaw-test/podcontroller-bad.yaml new file mode 100644 index 000000000..df4200b22 --- /dev/null +++ b/other-cel/allowed-pod-priorities/.chainsaw-test/podcontroller-bad.yaml @@ -0,0 +1,80 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: busybox + name: baddeployment01 + namespace: pod-priority-ns +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + strategy: {} + template: + metadata: + labels: + app: busybox + spec: + priorityClassName: foo + containers: + - name: bb-01 + image: busybox:1.35 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: busybox + name: baddeployment02 + namespace: pod-priority-ns +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + strategy: {} + template: + metadata: + labels: + app: busybox + spec: + priorityClassName: foo + containers: + - name: bb-01 + image: busybox:1.35 +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob01 + namespace: pod-priority-ns +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + spec: + priorityClassName: med + containers: + - name: bb-01 + image: kyverno + restartPolicy: OnFailure +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob02 + namespace: pod-priority-ns +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + spec: + priorityClassName: foo + containers: + - name: bb-01 + image: kyverno + restartPolicy: OnFailure + diff --git a/other-cel/allowed-pod-priorities/.chainsaw-test/podcontroller-good.yaml b/other-cel/allowed-pod-priorities/.chainsaw-test/podcontroller-good.yaml new file mode 100644 index 000000000..7bbd8cba6 --- /dev/null +++ b/other-cel/allowed-pod-priorities/.chainsaw-test/podcontroller-good.yaml @@ -0,0 +1,80 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: busybox + name: gooddeployment01 + namespace: pod-priority-ns +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + strategy: {} + template: + metadata: + labels: + app: busybox + spec: + priorityClassName: high + containers: + - name: bb-01 + image: busybox:1.35 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: busybox + name: gooddeployment02 + namespace: no-priority-ns +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + strategy: {} + template: + metadata: + labels: + app: busybox + spec: + priorityClassName: foo + containers: + - name: bb-01 + image: busybox:1.35 +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob01 + namespace: pod-priority-ns +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + spec: + priorityClassName: medium + containers: + - name: bb-01 + image: kyverno + restartPolicy: OnFailure +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob02 + namespace: no-priority-ns +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + spec: + priorityClassName: foo + containers: + - name: bb-01 + image: kyverno + restartPolicy: OnFailure + diff --git a/other-cel/allowed-pod-priorities/.chainsaw-test/policy-ready.yaml b/other-cel/allowed-pod-priorities/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..668c9f4fc --- /dev/null +++ b/other-cel/allowed-pod-priorities/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: allowed-podpriorities +status: + ready: true + diff --git a/other-cel/allowed-pod-priorities/.chainsaw-test/priorityClass.yaml b/other-cel/allowed-pod-priorities/.chainsaw-test/priorityClass.yaml new file mode 100644 index 000000000..e33fe7984 --- /dev/null +++ b/other-cel/allowed-pod-priorities/.chainsaw-test/priorityClass.yaml @@ -0,0 +1,8 @@ +apiVersion: scheduling.k8s.io/v1 +kind: PriorityClass +metadata: + name: high-priority +value: 1000000 +globalDefault: false +description: "This priority class should be used for XYZ service pods only." + diff --git a/other-cel/allowed-pod-priorities/allowed-pod-priorities.yaml b/other-cel/allowed-pod-priorities/allowed-pod-priorities.yaml new file mode 100644 index 000000000..3f1dd2c03 --- /dev/null +++ b/other-cel/allowed-pod-priorities/allowed-pod-priorities.yaml @@ -0,0 +1,48 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: allowed-podpriorities + annotations: + policies.kyverno.io/title: Allowed Pod Priorities in CEL expressions + policies.kyverno.io/category: Sample in CEL + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/subject: Pod + policies.kyverno.io/description: >- + A Pod PriorityClass is used to provide a guarantee on the scheduling of a Pod relative to others. + In certain cases where not all users in a cluster are trusted, a malicious user could create Pods + at the highest possible priorities, causing other Pods to be evicted/not get scheduled. This policy + checks the defined `priorityClassName` in a Pod spec to a dictionary of allowable + PriorityClasses for the given Namespace stored in a ConfigMap. If the `priorityClassName` is not + among them, the Pod is blocked. +spec: + validationFailureAction: Audit + background: true + rules: + - name: validate-pod-priority + match: + any: + - resources: + kinds: + - Pod + validate: + cel: + paramKind: + apiVersion: v1 + kind: ConfigMap + paramRef: + name: allowed-pod-priorities + namespace: default + parameterNotFoundAction: Deny + variables: + - name: namespaceName + expression: "namespaceObject.metadata.name" + - name: priorities + expression: "variables.namespaceName in params.data ? params.data[variables.namespaceName].split(', ') : []" + expressions: + - expression: "variables.priorities == [] || object.spec.priorityClassName in variables.priorities" + messageExpression: >- + 'The Pod PriorityClass ' + object.spec.priorityClassName + + ' is not in the list of the following PriorityClasses allowed in this Namespace: ' + + params.data[variables.namespaceName] + diff --git a/other-cel/allowed-pod-priorities/artifacthub-pkg.yml b/other-cel/allowed-pod-priorities/artifacthub-pkg.yml new file mode 100644 index 000000000..e09855f14 --- /dev/null +++ b/other-cel/allowed-pod-priorities/artifacthub-pkg.yml @@ -0,0 +1,24 @@ +name: allowed-pod-priorities-cel +version: 1.0.0 +displayName: Allowed Pod Priorities in CEL expressions +description: >- + A Pod PriorityClass is used to provide a guarantee on the scheduling of a Pod relative to others. In certain cases where not all users in a cluster are trusted, a malicious user could create Pods at the highest possible priorities, causing other Pods to be evicted/not get scheduled. This policy checks the defined `priorityClassName` in a Pod spec to a dictionary of allowable PriorityClasses for the given Namespace stored in a ConfigMap. If the `priorityClassName` is not among them, the Pod is blocked. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/other-cel/allowed-pod-priorities/allowed-pod-priorities.yaml + ``` +keywords: + - kyverno + - Sample + - CEL Expressions +readme: | + A Pod PriorityClass is used to provide a guarantee on the scheduling of a Pod relative to others. In certain cases where not all users in a cluster are trusted, a malicious user could create Pods at the highest possible priorities, causing other Pods to be evicted/not get scheduled. This policy checks the defined `priorityClassName` in a Pod spec to a dictionary of allowable PriorityClasses for the given Namespace stored in a ConfigMap. If the `priorityClassName` is not among them, the Pod is blocked. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Sample in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Pod" +digest: a017b81b233cd26270cd2d5f74724846c44b9782997545805014a585115bf1f2 +createdAt: "2024-03-19T17:20:47Z" + diff --git a/other-cel/block-ephemeral-containers/.chainsaw-test/chainsaw-test.yaml b/other-cel/block-ephemeral-containers/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..bf3b869c1 --- /dev/null +++ b/other-cel/block-ephemeral-containers/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,52 @@ +# 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-ephemeral-containers +spec: + steps: + - name: step-01 + try: + - apply: + file: ../block-ephemeral-containers.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: block-ephemeral-containers + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: ns.yaml + - apply: + file: pod.yaml + - apply: + file: podcontrollers.yaml + - name: step-03 + try: + - script: + content: if kubectl debug -it pod01 --image=busybox:1.35 --target=busybox + -n block-ephemeral-ns; then exit 1; else exit 0; fi; + - script: + content: if kubectl debug -it pod02 --image=busybox:1.35 --target=busybox02 + -n block-ephemeral-ns; then exit 1; else exit 0; fi; + - script: + content: if kubectl debug -it pod03 --image=busybox:1.35 --target=busybox + -n block-ephemeral-ns; then exit 1; else exit 0; fi; + - script: + content: if kubectl debug -it $(kubectl get po -n block-ephemeral-ns | grep + deployment01 | awk '{print $1}') --image=busybox:1.35 --target=bb -n block-ephemeral-ns; + then exit 1; else exit 0; fi; + - name: step-98 + try: + - script: + content: kubectl delete deployments --all --force --grace-period=0 -n block-ephemeral-ns + - script: + content: kubectl delete pods --all --force --grace-period=0 -n block-ephemeral-ns + diff --git a/other-cel/block-ephemeral-containers/.chainsaw-test/ns.yaml b/other-cel/block-ephemeral-containers/.chainsaw-test/ns.yaml new file mode 100644 index 000000000..9881b9cb0 --- /dev/null +++ b/other-cel/block-ephemeral-containers/.chainsaw-test/ns.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: block-ephemeral-ns + diff --git a/other-cel/block-ephemeral-containers/.chainsaw-test/pod.yaml b/other-cel/block-ephemeral-containers/.chainsaw-test/pod.yaml new file mode 100644 index 000000000..0125550fd --- /dev/null +++ b/other-cel/block-ephemeral-containers/.chainsaw-test/pod.yaml @@ -0,0 +1,46 @@ +apiVersion: v1 +kind: Pod +metadata: + name: pod01 + namespace: block-ephemeral-ns +spec: + containers: + - name: busybox + image: busybox:1.35 + command: ["sleep", "300"] +--- +apiVersion: v1 +kind: Pod +metadata: + name: pod02 + namespace: block-ephemeral-ns +spec: + containers: + - name: busybox + image: busybox:1.35 + command: ["sleep", "300"] + - name: busybox02 + image: busybox:1.35 + command: ["sleep", "300"] +--- +apiVersion: v1 +kind: Pod +metadata: + name: pod03 + namespace: block-ephemeral-ns +spec: + initContainers: + - name: busybox-init + image: busybox:1.35 + command: ["sleep", "300"] + - name: busybox02-init + image: busybox:1.35 + command: ["sleep", "300"] + containers: + - name: busybox + image: busybox:1.35 + command: ["sleep", "300"] + - name: busybox02 + image: busybox:1.35 + command: ["sleep", "300"] + diff --git a/other-cel/block-ephemeral-containers/.chainsaw-test/podcontrollers.yaml b/other-cel/block-ephemeral-containers/.chainsaw-test/podcontrollers.yaml new file mode 100644 index 000000000..6efc61a3f --- /dev/null +++ b/other-cel/block-ephemeral-containers/.chainsaw-test/podcontrollers.yaml @@ -0,0 +1,26 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: busybox + name: deployment01 + namespace: block-ephemeral-ns +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + strategy: {} + template: + metadata: + labels: + app: busybox + spec: + containers: + - name: bb + image: busybox:1.35 + command: ["sleep", "300"] + - name: bb2 + image: busybox:1.35 + command: ["sleep", "300"] + diff --git a/other-cel/block-ephemeral-containers/.chainsaw-test/policy-ready.yaml b/other-cel/block-ephemeral-containers/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..612f342f3 --- /dev/null +++ b/other-cel/block-ephemeral-containers/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: block-ephemeral-containers +status: + ready: true + diff --git a/other-cel/block-ephemeral-containers/.kyverno-test/kyverno-test.yaml b/other-cel/block-ephemeral-containers/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..7d1210a48 --- /dev/null +++ b/other-cel/block-ephemeral-containers/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,26 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: block-ephemeral-containers +policies: +- ../block-ephemeral-containers.yaml +resources: +- resource.yaml +results: +- policy: block-ephemeral-containers + rule: block-ephemeral-containers + resources: + - goodpod01 + - goodpod02 + - goodpod03 + kind: Pod + result: pass +- policy: block-ephemeral-containers + rule: block-ephemeral-containers + resources: + - badpod01 + - badpod02 + - badpod03 + kind: Pod + result: fail + diff --git a/other-cel/block-ephemeral-containers/.kyverno-test/resource.yaml b/other-cel/block-ephemeral-containers/.kyverno-test/resource.yaml new file mode 100644 index 000000000..ba498bf1f --- /dev/null +++ b/other-cel/block-ephemeral-containers/.kyverno-test/resource.yaml @@ -0,0 +1,66 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 +spec: + initContainers: + - name: initcontainer01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod02 +spec: + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod03 +spec: + initContainers: + - name: initcontainer01 + image: dummyimagename + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 +spec: + ephemeralContainers: + - name: ephcontainer01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod02 +spec: + initContainers: + - name: initcontainer01 + image: dummyimagename + ephemeralContainers: + - name: ephcontainer01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod03 +spec: + initContainers: + - name: initcontainer01 + image: dummyimagename + containers: + - name: container01 + image: dummyimagename + ephemeralContainers: + - name: ephcontainer01 + image: dummyimagename + diff --git a/other-cel/block-ephemeral-containers/artifacthub-pkg.yml b/other-cel/block-ephemeral-containers/artifacthub-pkg.yml new file mode 100644 index 000000000..370efc51c --- /dev/null +++ b/other-cel/block-ephemeral-containers/artifacthub-pkg.yml @@ -0,0 +1,24 @@ +name: block-ephemeral-containers-cel +version: 1.0.0 +displayName: Block Ephemeral Containers in CEL expressions +description: >- + Ephemeral containers, enabled by default in Kubernetes 1.23, allow users to use the `kubectl debug` functionality and attach a temporary container to an existing Pod. This may potentially be used to gain access to unauthorized information executing inside one or more containers in that Pod. This policy blocks the use of ephemeral containers. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/other-cel/block-ephemeral-containers/block-ephemeral-containers.yaml + ``` +keywords: + - kyverno + - Other + - CEL Expressions +readme: | + Ephemeral containers, enabled by default in Kubernetes 1.23, allow users to use the `kubectl debug` functionality and attach a temporary container to an existing Pod. This may potentially be used to gain access to unauthorized information executing inside one or more containers in that Pod. This policy blocks the use of ephemeral containers. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Other in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Pod" +digest: 13da34209be549d9904eb9142840242db2ae000b1935e8c3c84d23368886fab9 +createdAt: "2024-03-20T08:34:56Z" + diff --git a/other-cel/block-ephemeral-containers/block-ephemeral-containers.yaml b/other-cel/block-ephemeral-containers/block-ephemeral-containers.yaml new file mode 100644 index 000000000..a9223784c --- /dev/null +++ b/other-cel/block-ephemeral-containers/block-ephemeral-containers.yaml @@ -0,0 +1,33 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: block-ephemeral-containers + annotations: + policies.kyverno.io/title: Block Ephemeral Containers in CEL expressions + policies.kyverno.io/category: Other 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: >- + Ephemeral containers, enabled by default in Kubernetes 1.23, allow users to use the + `kubectl debug` functionality and attach a temporary container to an existing Pod. + This may potentially be used to gain access to unauthorized information executing inside + one or more containers in that Pod. This policy blocks the use of ephemeral containers. +spec: + validationFailureAction: Audit + background: true + rules: + - name: block-ephemeral-containers + match: + any: + - resources: + kinds: + - Pod + validate: + cel: + expressions: + - expression: "!has(object.spec.ephemeralContainers)" + message: "Ephemeral (debug) containers are not permitted." + diff --git a/other-cel/check-env-vars/.chainsaw-test/chainsaw-test.yaml b/other-cel/check-env-vars/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..898591ce7 --- /dev/null +++ b/other-cel/check-env-vars/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,39 @@ +# 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-env-vars +spec: + steps: + - name: step-01 + try: + - apply: + file: ../check-env-vars.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: check-env-vars + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: pods-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: pods-bad.yaml + - apply: + file: podcontrollers-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: podcontrollers-bad.yaml + diff --git a/other-cel/check-env-vars/.chainsaw-test/podcontrollers-bad.yaml b/other-cel/check-env-vars/.chainsaw-test/podcontrollers-bad.yaml new file mode 100644 index 000000000..d45f5e825 --- /dev/null +++ b/other-cel/check-env-vars/.chainsaw-test/podcontrollers-bad.yaml @@ -0,0 +1,60 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: busybox + name: baddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + strategy: {} + template: + metadata: + labels: + app: busybox + spec: + containers: + - name: busybox + image: busybox:1.35 + env: + - name: DISABLE_OPA + value: "true" + - name: foo + value: bar + - name: busybox02 + image: busybox:1.35 + env: + - name: foo + value: bar + - name: DISABLE_OPA + value: "true" +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob01 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + spec: + containers: + - name: busybox + image: busybox:1.35 + env: + - name: DISABLE_OPA + value: "true" + - name: foo + value: bar + - name: busybox02 + image: busybox:1.35 + env: + - name: foo + value: bar + - name: DISABLE_OPA + value: "true" + restartPolicy: OnFailure + diff --git a/other-cel/check-env-vars/.chainsaw-test/podcontrollers-good.yaml b/other-cel/check-env-vars/.chainsaw-test/podcontrollers-good.yaml new file mode 100644 index 000000000..a5bb12fe4 --- /dev/null +++ b/other-cel/check-env-vars/.chainsaw-test/podcontrollers-good.yaml @@ -0,0 +1,60 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: busybox + name: gooddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + strategy: {} + template: + metadata: + labels: + app: busybox + spec: + containers: + - name: busybox + image: busybox:1.35 + env: + - name: DISABLE_OPA + value: "false" + - name: foo + value: bar + - name: busybox02 + image: busybox:1.35 + env: + - name: foo + value: bar + - name: DISABLE_OPA + value: "false" +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob01 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + spec: + containers: + - name: busybox + image: busybox:1.35 + env: + - name: DISABLE_OPA + value: "false" + - name: foo + value: bar + - name: busybox02 + image: busybox:1.35 + env: + - name: foo + value: bar + - name: DISABLE_OPA + value: "false" + restartPolicy: OnFailure + diff --git a/other-cel/check-env-vars/.chainsaw-test/pods-bad.yaml b/other-cel/check-env-vars/.chainsaw-test/pods-bad.yaml new file mode 100644 index 000000000..0e73ec3d5 --- /dev/null +++ b/other-cel/check-env-vars/.chainsaw-test/pods-bad.yaml @@ -0,0 +1,93 @@ +apiVersion: v1 +kind: Pod +metadata: + labels: + run: busybox + name: badpod01 +spec: + containers: + - image: busybox:1.35 + name: busybox + env: + - name: DISABLE_OPA + value: "true" +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + run: busybox + name: badpod02 +spec: + containers: + - image: busybox:1.35 + name: busybox + env: + - name: foo + value: bar + - name: DISABLE_OPA + value: "true" + - image: busybox:1.35 + name: busybox02 + env: + - name: DISABLE_OPA + value: "true" + - name: foo + value: bar +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + run: busybox + name: badpod03 +spec: + containers: + - image: busybox:1.35 + name: busybox + env: + - name: foo + value: bar + - image: busybox:1.35 + name: busybox02 + env: + - name: foo + value: bar + - name: DISABLE_OPA + value: "true" +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + run: busybox + name: badpod04 +spec: + containers: + - image: busybox:1.35 + name: busybox + - image: busybox:1.35 + name: busybox02 + env: + - name: DISABLE_OPA + value: "true" +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + run: busybox + name: badpod05 +spec: + containers: + - image: busybox:1.35 + name: busybox + env: + - name: DISABLE_OPA + value: "false" + - image: busybox:1.35 + name: busybox02 + env: + - name: DISABLE_OPA + value: "true" + diff --git a/other-cel/check-env-vars/.chainsaw-test/pods-good.yaml b/other-cel/check-env-vars/.chainsaw-test/pods-good.yaml new file mode 100644 index 000000000..5ed8c10f5 --- /dev/null +++ b/other-cel/check-env-vars/.chainsaw-test/pods-good.yaml @@ -0,0 +1,48 @@ +apiVersion: v1 +kind: Pod +metadata: + labels: + run: busybox + name: goodpod01 +spec: + containers: + - image: busybox:1.35 + name: busybox + env: + - name: DISABLE_OPA + value: "false" +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + run: busybox + name: goodpod02 +spec: + containers: + - image: busybox:1.35 + name: busybox + env: + - name: foo + value: bar + - name: DISABLE_OPA + value: "false" + - image: busybox:1.35 + name: busybox02 + env: + - name: foo + value: bar +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + run: busybox + name: goodpod03 +spec: + containers: + - image: busybox:1.35 + name: busybox + - image: busybox:1.35 + name: busybox02 + diff --git a/other-cel/check-env-vars/.chainsaw-test/policy-ready.yaml b/other-cel/check-env-vars/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..85d6f8e34 --- /dev/null +++ b/other-cel/check-env-vars/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: check-env-vars +status: + ready: true + diff --git a/other-cel/check-env-vars/.kyverno-test/kyverno-test.yaml b/other-cel/check-env-vars/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..6bcfe92b2 --- /dev/null +++ b/other-cel/check-env-vars/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,23 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: opa-env +policies: +- ../check-env-vars.yaml +resources: +- resource.yaml +results: +- kind: Pod + policy: check-env-vars + resources: + - pod-with-opa-enabled + result: fail + rule: check-disable-opa +- kind: Pod + policy: check-env-vars + resources: + - pod-with-opa-disabled + - pod-without-opa-env + result: pass + rule: check-disable-opa + diff --git a/other-cel/check-env-vars/.kyverno-test/resource.yaml b/other-cel/check-env-vars/.kyverno-test/resource.yaml new file mode 100644 index 000000000..b62815746 --- /dev/null +++ b/other-cel/check-env-vars/.kyverno-test/resource.yaml @@ -0,0 +1,36 @@ +apiVersion: v1 +kind: Pod +metadata: + name: pod-with-opa-disabled + namespace: myservice +spec: + containers: + - env: + - name: DISABLE_OPA + value: "false" + image: quay.io/sdase/sdase-version-collector + name: myservice +--- +apiVersion: v1 +kind: Pod +metadata: + name: pod-with-opa-enabled + namespace: myservice +spec: + containers: + - env: + - name: DISABLE_OPA + value: "true" + image: quay.io/sdase/sdase-version-collector + name: myservice +--- +apiVersion: v1 +kind: Pod +metadata: + name: pod-without-opa-env + namespace: myservice +spec: + containers: + - image: quay.io/sdase/sdase-version-collector + name: myservice + diff --git a/other-cel/check-env-vars/artifacthub-pkg.yml b/other-cel/check-env-vars/artifacthub-pkg.yml new file mode 100644 index 000000000..6fb029914 --- /dev/null +++ b/other-cel/check-env-vars/artifacthub-pkg.yml @@ -0,0 +1,24 @@ +name: check-env-vars-cel +version: 1.0.0 +displayName: Check Environment Variables in CEL expressions +description: >- + Environment variables control many aspects of a container's execution and are often the source of many different configuration settings. Being able to ensure that the value of a specific environment variable either is or is not set to a specific string is useful to maintain such controls. This policy checks every container to ensure that if the `DISABLE_OPA` environment variable is defined, it must not be set to a value of `"true"`. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/other-cel/check-env-vars/check-env-vars.yaml + ``` +keywords: + - kyverno + - Other + - CEL Expressions +readme: | + Environment variables control many aspects of a container's execution and are often the source of many different configuration settings. Being able to ensure that the value of a specific environment variable either is or is not set to a specific string is useful to maintain such controls. This policy checks every container to ensure that if the `DISABLE_OPA` environment variable is defined, it must not be set to a value of `"true"`. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Other in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Pod" +digest: 3cf38de6f83c3a51ab01548ea6fc0ae1f69538a5c0ed2f163180eaea1c60e4aa +createdAt: "2024-03-21T13:31:53Z" + diff --git a/other-cel/check-env-vars/check-env-vars.yaml b/other-cel/check-env-vars/check-env-vars.yaml new file mode 100644 index 000000000..b894fe30c --- /dev/null +++ b/other-cel/check-env-vars/check-env-vars.yaml @@ -0,0 +1,35 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: check-env-vars + annotations: + policies.kyverno.io/title: Check Environment Variables in CEL expressions + policies.kyverno.io/severity: medium + policies.kyverno.io/category: Other in CEL + policies.kyverno.io/subject: Pod + kyverno.io/kubernetes-version: "1.26-1.27" + kyverno.io/kyverno-version: 1.11.0 + policies.kyverno.io/description: >- + Environment variables control many aspects of a container's execution and are + often the source of many different configuration settings. Being able to ensure that + the value of a specific environment variable either is or is not set to a specific string + is useful to maintain such controls. This policy checks every container to ensure that if the + `DISABLE_OPA` environment variable is defined, it must not be set to a value of `"true"`. +spec: + background: true + validationFailureAction: Audit + rules: + - name: check-disable-opa + match: + any: + - resources: + kinds: + - Pod + validate: + cel: + expressions: + - expression: >- + !object.spec.containers.exists(container, has(container.env) && + container.env.exists(e, e.name == 'DISABLE_OPA' && e.value == 'true')) + message: "DISABLE_OPA must not be set to true." + diff --git a/other-cel/check-node-for-cve-2022-0185/artifacthub-pkg.yml b/other-cel/check-node-for-cve-2022-0185/artifacthub-pkg.yml new file mode 100644 index 000000000..8c045eaa9 --- /dev/null +++ b/other-cel/check-node-for-cve-2022-0185/artifacthub-pkg.yml @@ -0,0 +1,24 @@ +name: check-node-for-cve-2022-0185-cel +version: 1.0.0 +displayName: Check Node for CVE-2022-0185 in CEL expressions +description: >- + Linux CVE-2022-0185 can allow a container escape in Kubernetes if left unpatched. The affected Linux kernel versions, at this time, are 5.10.84-1 and 5.15.5-2. For more information, refer to https://security-tracker.debian.org/tracker/CVE-2022-0185. This policy runs in background mode and flags an entry in the ClusterPolicyReport if any Node is reporting one of the affected kernel versions. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/other-cel/check-node-for-cve-2022-0185/check-node-for-cve-2022-0185.yaml + ``` +keywords: + - kyverno + - Other + - CEL Expressions +readme: | + Linux CVE-2022-0185 can allow a container escape in Kubernetes if left unpatched. The affected Linux kernel versions, at this time, are 5.10.84-1 and 5.15.5-2. For more information, refer to https://security-tracker.debian.org/tracker/CVE-2022-0185. This policy runs in background mode and flags an entry in the ClusterPolicyReport if any Node is reporting one of the affected kernel versions. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Other in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Node" +digest: c45321cd579c25bc971467d63d146c6ebef7942b94f72069b6d4d97f332f2df3 +createdAt: "2024-03-21T14:21:00Z" + diff --git a/other-cel/check-node-for-cve-2022-0185/check-node-for-cve-2022-0185.yaml b/other-cel/check-node-for-cve-2022-0185/check-node-for-cve-2022-0185.yaml new file mode 100644 index 000000000..41937ed07 --- /dev/null +++ b/other-cel/check-node-for-cve-2022-0185/check-node-for-cve-2022-0185.yaml @@ -0,0 +1,34 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: check-kernel + annotations: + policies.kyverno.io/title: Check Node for CVE-2022-0185 in CEL expressions + policies.kyverno.io/category: Other in CEL + policies.kyverno.io/severity: high + kyverno.io/kyverno-version: 1.11.0 + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/subject: Node + policies.kyverno.io/description: >- + Linux CVE-2022-0185 can allow a container escape in Kubernetes if left unpatched. + The affected Linux kernel versions, at this time, are 5.10.84-1 and 5.15.5-2. + For more information, refer to https://security-tracker.debian.org/tracker/CVE-2022-0185. + This policy runs in background mode and flags an entry in the ClusterPolicyReport + if any Node is reporting one of the affected kernel versions. +spec: + validationFailureAction: Audit + background: true + rules: + - name: kernel-validate + match: + any: + - resources: + kinds: + - Node + validate: + cel: + expressions: + - expression: "!(object.status.nodeInfo.kernelVersion in ['5.10.84-1', '5.15.5-2'])" + message: "Kernel is vulnerable to CVE-2022-0185." + diff --git a/other-cel/check-serviceaccount-secrets/.chainsaw-test/bad-svc-account.yaml b/other-cel/check-serviceaccount-secrets/.chainsaw-test/bad-svc-account.yaml new file mode 100644 index 000000000..2a6640f04 --- /dev/null +++ b/other-cel/check-serviceaccount-secrets/.chainsaw-test/bad-svc-account.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: bad-svc-account-02 + namespace: default +secrets: + - name: example-automated-thing-token-zyxwv + diff --git a/other-cel/check-serviceaccount-secrets/.chainsaw-test/chainsaw-test.yaml b/other-cel/check-serviceaccount-secrets/.chainsaw-test/chainsaw-test.yaml new file mode 100644 index 000000000..92cb193cf --- /dev/null +++ b/other-cel/check-serviceaccount-secrets/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,30 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + name: check-service-accounts +spec: + steps: + - name: step-01 + try: + - script: + content: | + sed 's/validationFailureAction: Audit/validationFailureAction: Enforce/' ../check-serviceaccount-secrets.yaml | kubectl create -f - + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: good-svc-account.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-svc-account.yaml + - name: step-99 + try: + - delete: + ref: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + name: check-serviceaccount-secrets + diff --git a/other-cel/check-serviceaccount-secrets/.chainsaw-test/good-svc-account.yaml b/other-cel/check-serviceaccount-secrets/.chainsaw-test/good-svc-account.yaml new file mode 100644 index 000000000..9aceacc4e --- /dev/null +++ b/other-cel/check-serviceaccount-secrets/.chainsaw-test/good-svc-account.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: good-svc-account + namespace: default + diff --git a/other-cel/check-serviceaccount-secrets/.chainsaw-test/policy-ready.yaml b/other-cel/check-serviceaccount-secrets/.chainsaw-test/policy-ready.yaml new file mode 100644 index 000000000..f0246f6f7 --- /dev/null +++ b/other-cel/check-serviceaccount-secrets/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: check-serviceaccount-secrets +status: + ready: true + diff --git a/other-cel/check-serviceaccount-secrets/.kyverno-test/kyverno-test.yaml b/other-cel/check-serviceaccount-secrets/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..a3ca211f3 --- /dev/null +++ b/other-cel/check-serviceaccount-secrets/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,22 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: svc-name +policies: +- ../check-serviceaccount-secrets.yaml +resources: +- resource.yaml +results: +- kind: ServiceAccount + policy: check-serviceaccount-secrets + resources: + - bad-svc-account + result: fail + rule: deny-secrets +- kind: ServiceAccount + policy: check-serviceaccount-secrets + resources: + - good-svc-account + result: pass + rule: deny-secrets + diff --git a/other-cel/check-serviceaccount-secrets/.kyverno-test/resource.yaml b/other-cel/check-serviceaccount-secrets/.kyverno-test/resource.yaml new file mode 100644 index 000000000..e2d53b0dc --- /dev/null +++ b/other-cel/check-serviceaccount-secrets/.kyverno-test/resource.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: bad-svc-account + namespace: default +secrets: + - name: build-robot-secret +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: good-svc-account + namespace: default + diff --git a/other-cel/check-serviceaccount-secrets/artifacthub-pkg.yaml b/other-cel/check-serviceaccount-secrets/artifacthub-pkg.yaml new file mode 100644 index 000000000..b28ff7a4d --- /dev/null +++ b/other-cel/check-serviceaccount-secrets/artifacthub-pkg.yaml @@ -0,0 +1,34 @@ +name: check-serviceaccount-secrets-cel +version: 1.0.0 +displayName: Check Existence of Secrets in ServiceAccount in CEL expressions +description: >- + Before version 1.24, Kubernetes automatically generated Secret-based tokens + for ServiceAccounts. To distinguish between automatically generated tokens + and manually created ones, Kubernetes checks for a reference from the + ServiceAccount's secrets field. If the Secret is referenced in the secrets + field, it is considered an auto-generated legacy token. These legacy Tokens can + be of security concern and should be audited. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/other-cel/check-serviceaccount-secrets/check-serviceaccount-secrets.yaml + ``` +keywords: + - kyverno + - Sample + - CEL Expressions +readme: | + Before version 1.24, Kubernetes automatically generated Secret-based tokens + for ServiceAccounts. To distinguish between automatically generated tokens + and manually created ones, Kubernetes checks for a reference from the + ServiceAccount's secrets field. If the Secret is referenced in the secrets + field, it is considered an auto-generated legacy token. These legacy Tokens can + be of security concern and should be audited. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Security in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Secret,ServiceAccount" +digest: 8f7e2e179c7e7fe85cbc8cf05c0b7111301836260fc95f0c50cc35d1894a37c3 +createdAt: "2024-03-21T13:47:35Z" + diff --git a/other-cel/check-serviceaccount-secrets/check-serviceaccount-secrets.yaml b/other-cel/check-serviceaccount-secrets/check-serviceaccount-secrets.yaml new file mode 100644 index 000000000..8c66e11ba --- /dev/null +++ b/other-cel/check-serviceaccount-secrets/check-serviceaccount-secrets.yaml @@ -0,0 +1,34 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: check-serviceaccount-secrets + annotations: + policies.kyverno.io/title: Check Long-Lived Secrets in ServiceAccounts in CEL expressions + policies.kyverno.io/category: Security in CEL + policies.kyverno.io/severity: medium + kyverno.io/kyverno-version: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/subject: Secret,ServiceAccount + policies.kyverno.io/description: >- + Before version 1.24, Kubernetes automatically generated Secret-based tokens + for ServiceAccounts. To distinguish between automatically generated tokens + and manually created ones, Kubernetes checks for a reference from the + ServiceAccount's secrets field. If the Secret is referenced in the secrets + field, it is considered an auto-generated legacy token. These legacy Tokens can + be of security concern and should be audited. +spec: + validationFailureAction: Audit + background: true + rules: + - name: deny-secrets + match: + any: + - resources: + kinds: + - ServiceAccount + validate: + cel: + expressions: + - expression: "!has(object.secrets)" + message: "Long-lived API tokens are not allowed." + diff --git a/other-cel/deny-secret-service-account-token-type/.chainsaw-test/bad-secret.yaml b/other-cel/deny-secret-service-account-token-type/.chainsaw-test/bad-secret.yaml new file mode 100644 index 000000000..041b05a63 --- /dev/null +++ b/other-cel/deny-secret-service-account-token-type/.chainsaw-test/bad-secret.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Secret +metadata: + name: bad-secret + annotations: + kubernetes.io/service-account.name: build-robot +type: kubernetes.io/service-account-token + diff --git a/other-cel/deny-secret-service-account-token-type/.chainsaw-test/chainsaw-test.yaml b/other-cel/deny-secret-service-account-token-type/.chainsaw-test/chainsaw-test.yaml new file mode 100644 index 000000000..701fc765e --- /dev/null +++ b/other-cel/deny-secret-service-account-token-type/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,32 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: deny-secret-service-account-token-type +spec: + steps: + - name: step-01 + try: + - apply: + file: ../deny-secret-service-account-token-type.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: deny-secret-service-account-token-type + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: good-secret.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-secret.yaml + diff --git a/other-cel/deny-secret-service-account-token-type/.chainsaw-test/good-secret.yaml b/other-cel/deny-secret-service-account-token-type/.chainsaw-test/good-secret.yaml new file mode 100644 index 000000000..03ae03cfe --- /dev/null +++ b/other-cel/deny-secret-service-account-token-type/.chainsaw-test/good-secret.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Secret +metadata: + name: good-secret +type: kubernetes.io/basic-auth +stringData: + username: admin + password: t0p-Secret + diff --git a/other-cel/deny-secret-service-account-token-type/.chainsaw-test/policy-ready.yaml b/other-cel/deny-secret-service-account-token-type/.chainsaw-test/policy-ready.yaml new file mode 100644 index 000000000..7a079f736 --- /dev/null +++ b/other-cel/deny-secret-service-account-token-type/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: deny-secret-service-account-token-type +status: + ready: true + diff --git a/other-cel/deny-secret-service-account-token-type/.kyverno-test/kyverno-test.yaml b/other-cel/deny-secret-service-account-token-type/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..5d5cee243 --- /dev/null +++ b/other-cel/deny-secret-service-account-token-type/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,22 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: deny-secret-service-account-token-type +policies: +- ../deny-secret-service-account-token-type.yaml +resources: +- resource.yaml +results: +- kind: Secret + policy: deny-secret-service-account-token-type + resources: + - bad-secret + result: fail + rule: deny-secret-service-account-token-type +- kind: Secret + policy: deny-secret-service-account-token-type + resources: + - good-secret + result: pass + rule: deny-secret-service-account-token-type + diff --git a/other-cel/deny-secret-service-account-token-type/.kyverno-test/resource.yaml b/other-cel/deny-secret-service-account-token-type/.kyverno-test/resource.yaml new file mode 100644 index 000000000..a3e3b7240 --- /dev/null +++ b/other-cel/deny-secret-service-account-token-type/.kyverno-test/resource.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Secret +metadata: + name: bad-secret + annotations: + kubernetes.io/service-account.name: build-robot +type: kubernetes.io/service-account-token +--- +apiVersion: v1 +kind: Secret +metadata: + name: good-secret +type: kubernetes.io/basic-auth +stringData: + username: admin + password: t0p-Secret + diff --git a/other-cel/deny-secret-service-account-token-type/artifacthub-pkg.yaml b/other-cel/deny-secret-service-account-token-type/artifacthub-pkg.yaml new file mode 100644 index 000000000..66552de5a --- /dev/null +++ b/other-cel/deny-secret-service-account-token-type/artifacthub-pkg.yaml @@ -0,0 +1,32 @@ +name: deny-secret-service-account-token-type-cel +version: 1.0.0 +displayName: Deny Secret Service Account Token Type in CEL expressions +description: >- + Before version 1.24, Kubernetes automatically generated Secret-based tokens + for ServiceAccounts. When creating a Secret, you can specify its type using the + type field of the Secret resource . The type kubernetes.io/service-account-token + is used for legacy ServiceAccount tokens . These legacy Tokens can + be of security concern and should be audited. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/other-cel/deny-secret-service-account-token-type/deny-secret-service-account-token-type.yaml + ``` +keywords: + - kyverno + - Sample + - CEL Expressions +readme: | + Before version 1.24, Kubernetes automatically generated Secret-based tokens + for ServiceAccounts. When creating a Secret, you can specify its type using the + type field of the Secret resource . The type kubernetes.io/service-account-token + is used for legacy ServiceAccount tokens . These legacy Tokens can + be of security concern and should be audited. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Security in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Secret, ServiceAccount" +digest: 16324f38031f70d4a971bde9673ca51e70455478b832a005cbb415ee901f5e56 +createdAt: "2024-03-22T07:40:19Z" + diff --git a/other-cel/deny-secret-service-account-token-type/deny-secret-service-account-token-type.yaml b/other-cel/deny-secret-service-account-token-type/deny-secret-service-account-token-type.yaml new file mode 100644 index 000000000..5f5a76657 --- /dev/null +++ b/other-cel/deny-secret-service-account-token-type/deny-secret-service-account-token-type.yaml @@ -0,0 +1,33 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: deny-secret-service-account-token-type + annotations: + policies.kyverno.io/title: Deny Secret Service Account Token Type in CEL expressions + policies.kyverno.io/category: Security in CEL + kyverno.io/kubernetes-version: "1.26-1.27" + kyverno.io/kyverno-version: 1.11.0 + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Secret, ServiceAccount + policies.kyverno.io/description: >- + Before version 1.24, Kubernetes automatically generated Secret-based tokens + for ServiceAccounts. When creating a Secret, you can specify its type using the + type field of the Secret resource . The type kubernetes.io/service-account-token + is used for legacy ServiceAccount tokens . These legacy Tokens can + be of security concern and should be audited. +spec: + validationFailureAction: Audit + background: true + rules: + - name: deny-secret-service-account-token-type + match: + any: + - resources: + kinds: + - Secret + validate: + cel: + expressions: + - expression: "object.type != 'kubernetes.io/service-account-token'" + message: "Secret ServiceAccount token type is not allowed." + diff --git a/other-cel/disallow-all-secrets/.chainsaw-test/chainsaw-test.yaml b/other-cel/disallow-all-secrets/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..a735a05e2 --- /dev/null +++ b/other-cel/disallow-all-secrets/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,39 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: disallow-all-secrets +spec: + steps: + - name: step-01 + try: + - apply: + file: ../disallow-all-secrets.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: no-secrets + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: pods-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: pods-bad.yaml + - apply: + file: podcontrollers-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: podcontrollers-bad.yaml + diff --git a/other-cel/disallow-all-secrets/.chainsaw-test/podcontrollers-bad.yaml b/other-cel/disallow-all-secrets/.chainsaw-test/podcontrollers-bad.yaml new file mode 100644 index 000000000..214c97602 --- /dev/null +++ b/other-cel/disallow-all-secrets/.chainsaw-test/podcontrollers-bad.yaml @@ -0,0 +1,190 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: busybox + name: baddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + strategy: {} + template: + metadata: + labels: + app: busybox + spec: + initContainers: + - image: busybox:1.35 + name: busybox02-init + env: + - name: SECRET_BAD + valueFrom: + secretKeyRef: + name: foo + key: pass + - image: busybox:1.35 + name: busybox-init + env: + - name: foo + value: bar + containers: + - image: busybox:1.35 + name: busybox + env: + - name: SECRET_BAD + valueFrom: + secretKeyRef: + name: foo + key: pass + - image: busybox:1.35 + name: busybox02 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: busybox + name: baddeployment02 +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + strategy: {} + template: + metadata: + labels: + app: busybox + spec: + initContainers: + - image: busybox:1.35 + name: busybox02-init + - image: busybox:1.35 + name: busybox-init + envFrom: + - secretRef: + name: foo + containers: + - image: busybox:1.35 + name: busybox + envFrom: + - secretRef: + name: foo + - image: busybox:1.35 + name: busybox02 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: busybox + name: baddeployment03 +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + strategy: {} + template: + metadata: + labels: + app: busybox + spec: + containers: + - image: busybox:1.35 + name: busybox + - image: busybox:1.35 + name: busybox02 + volumes: + - name: foo-vol + secret: + secretName: foo-secret +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob01 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + spec: + initContainers: + - image: busybox:1.35 + name: busybox02-init + env: + - name: SECRET_BAD + valueFrom: + secretKeyRef: + name: foo + key: pass + - image: busybox:1.35 + name: busybox-init + env: + - name: foo + value: bar + containers: + - image: busybox:1.35 + name: busybox + env: + - name: SECRET_BAD + valueFrom: + secretKeyRef: + name: foo + key: pass + - image: busybox:1.35 + name: busybox02 + restartPolicy: OnFailure +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob02 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + spec: + initContainers: + - image: busybox:1.35 + name: busybox02-init + - image: busybox:1.35 + name: busybox-init + envFrom: + - secretRef: + name: foo + containers: + - image: busybox:1.35 + name: busybox + envFrom: + - secretRef: + name: foo + - image: busybox:1.35 + name: busybox02 + restartPolicy: OnFailure +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob03 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + spec: + containers: + - image: busybox:1.35 + name: busybox + - image: busybox:1.35 + name: busybox02 + volumes: + - name: foo-vol + secret: + secretName: foo-secret + restartPolicy: OnFailure + diff --git a/other-cel/disallow-all-secrets/.chainsaw-test/podcontrollers-good.yaml b/other-cel/disallow-all-secrets/.chainsaw-test/podcontrollers-good.yaml new file mode 100644 index 000000000..62db85c4b --- /dev/null +++ b/other-cel/disallow-all-secrets/.chainsaw-test/podcontrollers-good.yaml @@ -0,0 +1,176 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: busybox + name: gooddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + strategy: {} + template: + metadata: + labels: + app: busybox + spec: + initContainers: + - image: busybox:1.35 + name: busybox02-init + - image: busybox:1.35 + name: busybox-init + env: + - name: foo + value: bar + containers: + - image: busybox:1.35 + name: busybox + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - image: busybox:1.35 + name: busybox02 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: busybox + name: gooddeployment02 +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + strategy: {} + template: + metadata: + labels: + app: busybox + spec: + initContainers: + - image: busybox:1.35 + name: busybox02-init + - image: busybox:1.35 + name: busybox-init + envFrom: + - configMapRef: + name: foo-bar + containers: + - image: busybox:1.35 + name: busybox + envFrom: + - configMapRef: + name: foo-bar + - image: busybox:1.35 + name: busybox02 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: busybox + name: gooddeployment03 +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + strategy: {} + template: + metadata: + labels: + app: busybox + spec: + containers: + - image: busybox:1.35 + name: busybox + - image: busybox:1.35 + name: busybox02 + volumes: + - name: foo-vol + emptyDir: + sizeLimit: 100Mi +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob01 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + spec: + initContainers: + - image: busybox:1.35 + name: busybox02-init + - image: busybox:1.35 + name: busybox-init + env: + - name: foo + value: bar + containers: + - image: busybox:1.35 + name: busybox + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - image: busybox:1.35 + name: busybox02 + restartPolicy: OnFailure +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob02 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + spec: + initContainers: + - image: busybox:1.35 + name: busybox02-init + - image: busybox:1.35 + name: busybox-init + envFrom: + - configMapRef: + name: foo-bar + containers: + - image: busybox:1.35 + name: busybox + envFrom: + - configMapRef: + name: foo-bar + - image: busybox:1.35 + name: busybox02 + restartPolicy: OnFailure +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob03 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + spec: + containers: + - image: busybox:1.35 + name: busybox + - image: busybox:1.35 + name: busybox02 + volumes: + - name: foo-vol + emptyDir: + sizeLimit: 100Mi + restartPolicy: OnFailure + diff --git a/other-cel/disallow-all-secrets/.chainsaw-test/pods-bad.yaml b/other-cel/disallow-all-secrets/.chainsaw-test/pods-bad.yaml new file mode 100644 index 000000000..124a1c3d7 --- /dev/null +++ b/other-cel/disallow-all-secrets/.chainsaw-test/pods-bad.yaml @@ -0,0 +1,97 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 +spec: + initContainers: + - image: busybox:1.35 + name: busybox02-init + env: + - name: SECRET_BAD + valueFrom: + secretKeyRef: + name: foo + key: pass + - image: busybox:1.35 + name: busybox-init + env: + - name: foo + value: bar + containers: + - image: busybox:1.35 + name: busybox + env: + - name: SECRET_BAD + valueFrom: + secretKeyRef: + name: foo + key: pass + - image: busybox:1.35 + name: busybox02 +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod02 +spec: + initContainers: + - image: busybox:1.35 + name: busybox02-init + - image: busybox:1.35 + name: busybox-init + envFrom: + - secretRef: + name: foo + containers: + - image: busybox:1.35 + name: busybox + envFrom: + - secretRef: + name: foo + - image: busybox:1.35 + name: busybox02 +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod03 +spec: + containers: + - image: busybox:1.35 + name: busybox + - image: busybox:1.35 + name: busybox02 + volumes: + - name: foo-vol + secret: + secretName: foo-secret +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod04 +spec: + initContainers: + - image: busybox:1.35 + name: busybox02-init + - image: busybox:1.35 + name: busybox-init + env: + - name: SECRET_BAD + valueFrom: + secretKeyRef: + name: foo + key: pass + containers: + - image: busybox:1.35 + name: busybox + envFrom: + - secretRef: + name: foo + - image: busybox:1.35 + name: busybox02 + volumes: + - name: foo-vol + secret: + secretName: foo-secret + diff --git a/other-cel/disallow-all-secrets/.chainsaw-test/pods-good.yaml b/other-cel/disallow-all-secrets/.chainsaw-test/pods-good.yaml new file mode 100644 index 000000000..3dbc1f932 --- /dev/null +++ b/other-cel/disallow-all-secrets/.chainsaw-test/pods-good.yaml @@ -0,0 +1,72 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 +spec: + initContainers: + - image: busybox:1.35 + name: busybox02-init + - image: busybox:1.35 + name: busybox-init + env: + - name: foo + value: bar + containers: + - image: busybox:1.35 + name: busybox + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - image: busybox:1.35 + name: busybox02 +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod02 +spec: + containers: + - image: busybox:1.35 + name: busybox-init + - image: busybox:1.35 + name: busybox02-init +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod03 +spec: + initContainers: + - image: busybox:1.35 + name: busybox02-init + - image: busybox:1.35 + name: busybox-init + envFrom: + - configMapRef: + name: foo-bar + containers: + - image: busybox:1.35 + name: busybox + envFrom: + - configMapRef: + name: foo-bar + - image: busybox:1.35 + name: busybox02 +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod04 +spec: + containers: + - image: busybox:1.35 + name: busybox + - image: busybox:1.35 + name: busybox02 + volumes: + - name: foo-vol + emptyDir: + sizeLimit: 100Mi + diff --git a/other-cel/disallow-all-secrets/.chainsaw-test/policy-ready.yaml b/other-cel/disallow-all-secrets/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..a6c46920f --- /dev/null +++ b/other-cel/disallow-all-secrets/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: no-secrets +status: + ready: true + diff --git a/other-cel/disallow-all-secrets/.kyverno-test/kyverno-test.yaml b/other-cel/disallow-all-secrets/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..92a1574c1 --- /dev/null +++ b/other-cel/disallow-all-secrets/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,24 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: no-secrets +policies: +- ../disallow-all-secrets.yaml +resources: +- resource.yaml +results: +- kind: Pod + policy: no-secrets + resources: + - default/secret-env-pod + - default/secret-ref-pod + - default/secret-vol-pod + result: fail + rule: secrets-not-from-env-envFrom-and-volumes +- kind: Pod + policy: no-secrets + resources: + - default/good-pod + result: pass + rule: secrets-not-from-env-envFrom-and-volumes + diff --git a/other-cel/disallow-all-secrets/.kyverno-test/resource.yaml b/other-cel/disallow-all-secrets/.kyverno-test/resource.yaml new file mode 100644 index 000000000..868b535ba --- /dev/null +++ b/other-cel/disallow-all-secrets/.kyverno-test/resource.yaml @@ -0,0 +1,62 @@ +apiVersion: v1 +kind: Pod +metadata: + name: secret-env-pod +spec: + containers: + - name: mycontainer + image: redis + env: + - name: SECRET_USERNAME + valueFrom: + secretKeyRef: + name: mysecret + key: username + - name: SECRET_PASSWORD + valueFrom: + secretKeyRef: + name: mysecret + key: password + restartPolicy: Never + +--- +apiVersion: v1 +kind: Pod +metadata: + name: secret-ref-pod +spec: + containers: + - name: test-container + image: registry.k8s.io/busybox + command: [ "/bin/sh", "-c", "env" ] + envFrom: + - secretRef: + name: mysecret + restartPolicy: Never +--- +apiVersion: v1 +kind: Pod +metadata: + name: secret-vol-pod +spec: + volumes: + - name: secret-volume + secret: + secretName: mysecret + containers: + - name: test-container + image: registry.k8s.io/busybox + volumeMounts: + - name: secret-volume + readOnly: true + mountPath: "/etc/secret-volume" +--- +apiVersion: v1 +kind: Pod +metadata: + name: good-pod +spec: + containers: + - name: test-container + image: registry.k8s.io/busybox + diff --git a/other-cel/disallow-all-secrets/artifacthub-pkg.yml b/other-cel/disallow-all-secrets/artifacthub-pkg.yml new file mode 100644 index 000000000..4d98a3cc0 --- /dev/null +++ b/other-cel/disallow-all-secrets/artifacthub-pkg.yml @@ -0,0 +1,24 @@ +name: disallow-all-secrets-cel +version: 1.0.0 +displayName: Disallow all Secrets in CEL expressions +description: >- + Secrets often contain sensitive information which not all Pods need consume. This policy disables the use of all Secrets in a Pod definition. In order to work effectively, this Policy needs a separate Policy or rule to require `automountServiceAccountToken=false` at the Pod level or ServiceAccount level since this would otherwise result in a Secret being mounted. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/other-cel/disallow-all-secrets/disallow-all-secrets.yaml + ``` +keywords: + - kyverno + - Other + - CEL Expressions +readme: | + Secrets often contain sensitive information which not all Pods need consume. This policy disables the use of all Secrets in a Pod definition. In order to work effectively, this Policy needs a separate Policy or rule to require `automountServiceAccountToken=false` at the Pod level or ServiceAccount level since this would otherwise result in a Secret being mounted. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Other in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Pod, Secret" +digest: 298fbab361ee9e46721a4afb06212ac6689988f87f257709b82624ef5393ebd5 +createdAt: "2024-03-23T11:14:09Z" + diff --git a/other-cel/disallow-all-secrets/disallow-all-secrets.yaml b/other-cel/disallow-all-secrets/disallow-all-secrets.yaml new file mode 100644 index 000000000..944ac4aeb --- /dev/null +++ b/other-cel/disallow-all-secrets/disallow-all-secrets.yaml @@ -0,0 +1,50 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: no-secrets + annotations: + policies.kyverno.io/title: Disallow all Secrets in CEL expressions + policies.kyverno.io/category: Other in CEL + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod, Secret + 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: >- + Secrets often contain sensitive information which not all Pods need consume. + This policy disables the use of all Secrets in a Pod definition. In order to work effectively, + this Policy needs a separate Policy or rule to require `automountServiceAccountToken=false` + at the Pod level or ServiceAccount level since this would otherwise result in a Secret being mounted. +spec: + validationFailureAction: Audit + rules: + - name: secrets-not-from-env-envFrom-and-volumes + match: + any: + - resources: + kinds: + - Pod + validate: + cel: + variables: + - name: allContainers + expression: >- + object.spec.containers + + (has(object.spec.initContainers) ? object.spec.initContainers : []) + + (has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []) + expressions: + - expression: >- + variables.allContainers.all(container, + !has(container.env) || + container.env.all(env, !has(env.valueFrom) || !has(env.valueFrom.secretKeyRef))) + message: "No Secrets from env." + + - expression: >- + variables.allContainers.all(container, + !has(container.envFrom) || + container.envFrom.all(envFrom, !has(envFrom.secretRef))) + message: "No Secrets from envFrom." + + - expression: "!has(object.spec.volumes) || object.spec.volumes.all(volume, !has(volume.secret))" + message: "No Secrets from volumes." + diff --git a/other-cel/disallow-localhost-services/.chainsaw-test/chainsaw-test.yaml b/other-cel/disallow-localhost-services/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..a6d9212c5 --- /dev/null +++ b/other-cel/disallow-localhost-services/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,32 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: disallow-localhost-services +spec: + steps: + - name: step-01 + try: + - apply: + file: ../disallow-localhost-services.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: no-localhost-service + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: svc-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: svc-bad.yaml + diff --git a/other-cel/disallow-localhost-services/.chainsaw-test/policy-ready.yaml b/other-cel/disallow-localhost-services/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..34d9089d2 --- /dev/null +++ b/other-cel/disallow-localhost-services/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: no-localhost-service +status: + ready: true + diff --git a/other-cel/disallow-localhost-services/.chainsaw-test/svc-bad.yaml b/other-cel/disallow-localhost-services/.chainsaw-test/svc-bad.yaml new file mode 100644 index 000000000..c3e2722a4 --- /dev/null +++ b/other-cel/disallow-localhost-services/.chainsaw-test/svc-bad.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Service +metadata: + name: badsvc01 +spec: + type: ExternalName + externalName: localhost + diff --git a/other-cel/disallow-localhost-services/.chainsaw-test/svc-good.yaml b/other-cel/disallow-localhost-services/.chainsaw-test/svc-good.yaml new file mode 100644 index 000000000..cc1c8774d --- /dev/null +++ b/other-cel/disallow-localhost-services/.chainsaw-test/svc-good.yaml @@ -0,0 +1,34 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: nginx + name: goodsvc01 +spec: + ports: + - port: 80 + protocol: TCP + targetPort: 80 + selector: + run: nginx + type: ClusterIP +--- +apiVersion: v1 +kind: Service +metadata: + name: goodsvc02 +spec: + type: NodePort + ports: + - port: 80 + targetPort: 80 + nodePort: 30007 +--- +apiVersion: v1 +kind: Service +metadata: + name: goodsvc03 +spec: + type: ExternalName + externalName: foo.bar.com + diff --git a/other-cel/disallow-localhost-services/.kyverno-test/kyverno-test.yaml b/other-cel/disallow-localhost-services/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..08a0aff38 --- /dev/null +++ b/other-cel/disallow-localhost-services/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,22 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: no-localhost-service +policies: +- ../disallow-localhost-services.yaml +resources: +- resource.yaml +results: +- kind: Service + policy: no-localhost-service + resources: + - my-service + result: fail + rule: no-localhost-service +- kind: Service + policy: no-localhost-service + resources: + - my-np-service + result: pass + rule: no-localhost-service + diff --git a/other-cel/disallow-localhost-services/.kyverno-test/resource.yaml b/other-cel/disallow-localhost-services/.kyverno-test/resource.yaml new file mode 100644 index 000000000..c7ad17280 --- /dev/null +++ b/other-cel/disallow-localhost-services/.kyverno-test/resource.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: Service +metadata: + name: my-service +spec: + type: ExternalName + externalName: localhost +--- +apiVersion: v1 +kind: Service +metadata: + name: my-np-service +spec: + type: NodePort + selector: + app: MyApp + ports: + - port: 80 + targetPort: 80 + protocol: TCP + diff --git a/other-cel/disallow-localhost-services/artifacthub-pkg.yml b/other-cel/disallow-localhost-services/artifacthub-pkg.yml new file mode 100644 index 000000000..f27b28fb1 --- /dev/null +++ b/other-cel/disallow-localhost-services/artifacthub-pkg.yml @@ -0,0 +1,24 @@ +name: disallow-localhost-services-cel +version: 1.0.0 +displayName: Disallow Localhost ExternalName Services in CEL expressions +description: >- + A Service of type ExternalName which points back to localhost can potentially be used to exploit vulnerabilities in some Ingress controllers. This policy audits Services of type ExternalName if the externalName field refers to localhost. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/other-cel/disallow-localhost-services/disallow-localhost-services.yaml + ``` +keywords: + - kyverno + - Sample + - CEL Expressions +readme: | + A Service of type ExternalName which points back to localhost can potentially be used to exploit vulnerabilities in some Ingress controllers. This policy audits Services of type ExternalName if the externalName field refers to localhost. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Sample in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Service" +digest: 6987150bedeaf5bafe4c819cc48b6c2660de1a66b007f24807d88d7a0407a3ba +createdAt: "2024-03-23T12:17:54Z" + diff --git a/other-cel/disallow-localhost-services/disallow-localhost-services.yaml b/other-cel/disallow-localhost-services/disallow-localhost-services.yaml new file mode 100644 index 000000000..b2cdc2315 --- /dev/null +++ b/other-cel/disallow-localhost-services/disallow-localhost-services.yaml @@ -0,0 +1,31 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: no-localhost-service + annotations: + policies.kyverno.io/title: Disallow Localhost ExternalName Services in CEL expressions + policies.kyverno.io/category: Sample in CEL + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Service + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/description: >- + A Service of type ExternalName which points back to localhost can potentially be used to exploit + vulnerabilities in some Ingress controllers. This policy audits Services of type ExternalName + if the externalName field refers to localhost. +spec: + validationFailureAction: Audit + background: true + rules: + - name: no-localhost-service + match: + any: + - resources: + kinds: + - Service + validate: + cel: + expressions: + - expression: "object.spec.type != 'ExternalName' || object.spec.externalName != 'localhost'" + message: "Service of type ExternalName cannot point to localhost." + diff --git a/other-cel/disallow-secrets-from-env-vars/.chainsaw-test/chainsaw-test.yaml b/other-cel/disallow-secrets-from-env-vars/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..d52d2fab8 --- /dev/null +++ b/other-cel/disallow-secrets-from-env-vars/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,39 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: disallow-secrets-from-env-vars +spec: + steps: + - name: step-01 + try: + - apply: + file: ../disallow-secrets-from-env-vars.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: secrets-not-from-env-vars + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: pods-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: pods-bad.yaml + - apply: + file: podcontrollers-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: podcontrollers-bad.yaml + diff --git a/other-cel/disallow-secrets-from-env-vars/.chainsaw-test/podcontrollers-bad.yaml b/other-cel/disallow-secrets-from-env-vars/.chainsaw-test/podcontrollers-bad.yaml new file mode 100644 index 000000000..f2d6ff74a --- /dev/null +++ b/other-cel/disallow-secrets-from-env-vars/.chainsaw-test/podcontrollers-bad.yaml @@ -0,0 +1,104 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: busybox + name: baddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + strategy: {} + template: + metadata: + labels: + app: busybox + spec: + containers: + - image: busybox:1.35 + name: busybox + env: + - name: SECRET_BAD + valueFrom: + secretKeyRef: + name: foo + key: pass + - image: busybox:1.35 + name: busybox02 + env: + - name: foo + value: bar +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: busybox + name: baddeployment02 +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + strategy: {} + template: + metadata: + labels: + app: busybox + spec: + containers: + - image: busybox:1.35 + name: busybox + envFrom: + - secretRef: + name: foo + - image: busybox:1.35 + name: busybox02 +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob01 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + spec: + containers: + - image: busybox:1.35 + name: busybox + env: + - name: SECRET_BAD + valueFrom: + secretKeyRef: + name: foo + key: pass + - image: busybox:1.35 + name: busybox02 + env: + - name: foo + value: bar + restartPolicy: OnFailure +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob02 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + spec: + containers: + - image: busybox:1.35 + name: busybox + envFrom: + - secretRef: + name: foo + - image: busybox:1.35 + name: busybox02 + restartPolicy: OnFailure + diff --git a/other-cel/disallow-secrets-from-env-vars/.chainsaw-test/podcontrollers-good.yaml b/other-cel/disallow-secrets-from-env-vars/.chainsaw-test/podcontrollers-good.yaml new file mode 100644 index 000000000..d5b7d27aa --- /dev/null +++ b/other-cel/disallow-secrets-from-env-vars/.chainsaw-test/podcontrollers-good.yaml @@ -0,0 +1,96 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: busybox + name: gooddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + strategy: {} + template: + metadata: + labels: + app: busybox + spec: + containers: + - image: busybox:1.35 + name: busybox + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - image: busybox:1.35 + name: busybox02 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: busybox + name: gooddeployment02 +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + strategy: {} + template: + metadata: + labels: + app: busybox + spec: + containers: + - image: busybox:1.35 + name: busybox + envFrom: + - configMapRef: + name: foo-bar + - image: busybox:1.35 + name: busybox02 +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob01 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + spec: + containers: + - image: busybox:1.35 + name: busybox + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - image: busybox:1.35 + name: busybox02 + restartPolicy: OnFailure +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob02 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + spec: + containers: + - image: busybox:1.35 + name: busybox + envFrom: + - configMapRef: + name: foo-bar + - image: busybox:1.35 + name: busybox02 + restartPolicy: OnFailure + diff --git a/other-cel/disallow-secrets-from-env-vars/.chainsaw-test/pods-bad.yaml b/other-cel/disallow-secrets-from-env-vars/.chainsaw-test/pods-bad.yaml new file mode 100644 index 000000000..26f0cbf6e --- /dev/null +++ b/other-cel/disallow-secrets-from-env-vars/.chainsaw-test/pods-bad.yaml @@ -0,0 +1,51 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 +spec: + containers: + - image: busybox:1.35 + name: busybox + env: + - name: SECRET_BAD + valueFrom: + secretKeyRef: + name: foo + key: pass + - image: busybox:1.35 + name: busybox02 +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod02 +spec: + containers: + - image: busybox:1.35 + name: busybox + - image: busybox:1.35 + name: busybox02 + envFrom: + - secretRef: + name: foo +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod03 +spec: + containers: + - image: busybox:1.35 + name: busybox + envFrom: + - secretRef: + name: foo + - image: busybox:1.35 + name: busybox02 + env: + - name: SECRET_BAD + valueFrom: + secretKeyRef: + name: foo + key: pass + diff --git a/other-cel/disallow-secrets-from-env-vars/.chainsaw-test/pods-good.yaml b/other-cel/disallow-secrets-from-env-vars/.chainsaw-test/pods-good.yaml new file mode 100644 index 000000000..6a02634ee --- /dev/null +++ b/other-cel/disallow-secrets-from-env-vars/.chainsaw-test/pods-good.yaml @@ -0,0 +1,41 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 +spec: + containers: + - image: busybox:1.35 + name: busybox + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - image: busybox:1.35 + name: busybox02 +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod02 +spec: + containers: + - image: busybox:1.35 + name: busybox-init + - image: busybox:1.35 + name: busybox02-init +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod03 +spec: + containers: + - image: busybox:1.35 + name: busybox + envFrom: + - configMapRef: + name: foo-bar + - image: busybox:1.35 + name: busybox02 + diff --git a/other-cel/disallow-secrets-from-env-vars/.chainsaw-test/policy-ready.yaml b/other-cel/disallow-secrets-from-env-vars/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..5ee01d320 --- /dev/null +++ b/other-cel/disallow-secrets-from-env-vars/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: secrets-not-from-env-vars +status: + ready: true + diff --git a/other-cel/disallow-secrets-from-env-vars/.kyverno-test/kyverno-test.yaml b/other-cel/disallow-secrets-from-env-vars/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..b0fb70fb4 --- /dev/null +++ b/other-cel/disallow-secrets-from-env-vars/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,23 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: secrets-not-from-env-vars +policies: +- ../disallow-secrets-from-env-vars.yaml +resources: +- resource.yaml +results: +- kind: Pod + policy: secrets-not-from-env-vars + resources: + - default/secret-env-pod + - default/secret-ref-pod + result: fail + rule: secrets-not-from-env-vars +- kind: Pod + policy: secrets-not-from-env-vars + resources: + - default/good-pod + result: pass + rule: secrets-not-from-env-vars + diff --git a/other-cel/disallow-secrets-from-env-vars/.kyverno-test/resource.yaml b/other-cel/disallow-secrets-from-env-vars/.kyverno-test/resource.yaml new file mode 100644 index 000000000..c13f1437a --- /dev/null +++ b/other-cel/disallow-secrets-from-env-vars/.kyverno-test/resource.yaml @@ -0,0 +1,57 @@ +apiVersion: v1 +kind: Pod +metadata: + name: secret-env-pod +spec: + containers: + - name: mycontainer + image: redis + env: + - name: SECRET_USERNAME + valueFrom: + secretKeyRef: + name: mysecret + key: username + - name: SECRET_PASSWORD + valueFrom: + secretKeyRef: + name: mysecret + key: password + restartPolicy: Never + +--- +apiVersion: v1 +kind: Pod +metadata: + name: secret-ref-pod +spec: + containers: + - name: test-container + image: registry.k8s.io/busybox + command: [ "/bin/sh", "-c", "env" ] + envFrom: + - secretRef: + name: mysecret + restartPolicy: Never +--- +apiVersion: v1 +kind: Pod +metadata: + name: good-pod +spec: + containers: + - name: test-container + image: registry.k8s.io/busybox + env: + - name: ENV_VAR_1 + value: "value1" + - name: ENV_VAR_2 + value: "value2" + volumeMounts: + - name: mysecret + mountPath: /mnt/mysecret + volumes: + - name: mysecret + secret: + secretName: mysecret + diff --git a/other-cel/disallow-secrets-from-env-vars/artifacthub-pkg.yml b/other-cel/disallow-secrets-from-env-vars/artifacthub-pkg.yml new file mode 100644 index 000000000..2da9f7c41 --- /dev/null +++ b/other-cel/disallow-secrets-from-env-vars/artifacthub-pkg.yml @@ -0,0 +1,25 @@ +name: disallow-secrets-from-env-vars-cel +version: 1.0.0 +displayName: Disallow Secrets from Env Vars in CEL expressions +description: >- + Secrets used as environment variables containing sensitive information may, if not carefully controlled, be printed in log output which could be visible to unauthorized people and captured in forwarding applications. This policy disallows using Secrets as environment variables. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/other-cel/disallow-secrets-from-env-vars/disallow-secrets-from-env-vars.yaml + ``` +keywords: + - kyverno + - Sample + - EKS Best Practices + - CEL Expressions +readme: | + Secrets used as environment variables containing sensitive information may, if not carefully controlled, be printed in log output which could be visible to unauthorized people and captured in forwarding applications. This policy disallows using Secrets as environment variables. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Sample, EKS Best Practices in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Pod, Secret" +digest: 52e12553f5be68f8e155a88f87e81eefeb8008acea66939a570d597afe16184b +createdAt: "2024-03-24T16:54:45Z" + diff --git a/other-cel/disallow-secrets-from-env-vars/disallow-secrets-from-env-vars.yaml b/other-cel/disallow-secrets-from-env-vars/disallow-secrets-from-env-vars.yaml new file mode 100644 index 000000000..0f03a8b7e --- /dev/null +++ b/other-cel/disallow-secrets-from-env-vars/disallow-secrets-from-env-vars.yaml @@ -0,0 +1,33 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: secrets-not-from-env-vars + annotations: + policies.kyverno.io/title: Disallow Secrets from Env Vars in CEL expressions + policies.kyverno.io/category: Sample, EKS Best Practices in CEL + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod, Secret + kyverno.io/kyverno-version: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/description: >- + Secrets used as environment variables containing sensitive information may, if not carefully controlled, + be printed in log output which could be visible to unauthorized people and captured in forwarding + applications. This policy disallows using Secrets as environment variables. +spec: + validationFailureAction: Audit + background: true + rules: + - name: secrets-not-from-env-vars + match: + any: + - resources: + kinds: + - Pod + validate: + cel: + expressions: + - expression: "object.spec.containers.all(container, !has(container.env) || container.env.all(env, !has(env.valueFrom) || !has(env.valueFrom.secretKeyRef)))" + message: "Secrets must be mounted as volumes, not as environment variables." + - expression: "object.spec.containers.all(container, !has(container.envFrom) || container.envFrom.all(envFrom, !has(envFrom.secretRef)))" + message: "Secrets must not come from envFrom statements." + diff --git a/other-cel/docker-socket-requires-label/.chainsaw-test/chainsaw-test.yaml b/other-cel/docker-socket-requires-label/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..0fb756232 --- /dev/null +++ b/other-cel/docker-socket-requires-label/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,39 @@ +# 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: docker-socket-requires-label +spec: + steps: + - name: step-01 + try: + - apply: + file: ../docker-socket-requires-label.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: docker-socket-check + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: pods-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: pods-bad.yaml + - apply: + file: podcontrollers-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: podcontrollers-bad.yaml + diff --git a/other-cel/docker-socket-requires-label/.chainsaw-test/podcontrollers-bad.yaml b/other-cel/docker-socket-requires-label/.chainsaw-test/podcontrollers-bad.yaml new file mode 100644 index 000000000..61e78696a --- /dev/null +++ b/other-cel/docker-socket-requires-label/.chainsaw-test/podcontrollers-bad.yaml @@ -0,0 +1,96 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: busybox + name: baddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + strategy: {} + template: + metadata: + labels: + allow-docker: "false" + app: busybox + spec: + containers: + - image: busybox:1.35 + name: busybox + volumes: + - name: docker-vol + hostPath: + path: "/var/run/docker.sock" +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: busybox + name: baddeployment02 +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + strategy: {} + template: + metadata: + labels: + app: busybox + spec: + containers: + - image: busybox:1.35 + name: busybox + volumes: + - name: docker-vol + hostPath: + path: "/var/run/docker.sock" +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob01 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + metadata: + labels: + allow-docker: "false" + app: busybox + spec: + containers: + - image: busybox:1.35 + name: busybox + volumes: + - name: docker-vol + hostPath: + path: "/var/run/docker.sock" + restartPolicy: OnFailure +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob02 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + metadata: + labels: + app: busybox + spec: + containers: + - image: busybox:1.35 + name: busybox + volumes: + - name: docker-vol + hostPath: + path: "/var/run/docker.sock" + restartPolicy: OnFailure + diff --git a/other-cel/docker-socket-requires-label/.chainsaw-test/podcontrollers-good.yaml b/other-cel/docker-socket-requires-label/.chainsaw-test/podcontrollers-good.yaml new file mode 100644 index 000000000..381f46442 --- /dev/null +++ b/other-cel/docker-socket-requires-label/.chainsaw-test/podcontrollers-good.yaml @@ -0,0 +1,98 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: busybox + name: gooddeployment01 +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + strategy: {} + template: + metadata: + labels: + allow-docker: "true" + app: busybox + spec: + containers: + - image: busybox:1.35 + name: busybox + volumes: + - name: docker-vol + hostPath: + path: "/var/run/docker.sock" +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: busybox + name: gooddeployment02 +spec: + replicas: 1 + selector: + matchLabels: + app: busybox + strategy: {} + template: + metadata: + labels: + allow-docker: "false" + app: busybox + spec: + containers: + - image: busybox:1.35 + name: busybox + volumes: + - name: foo-vol + hostPath: + path: "/var/foo/bar" +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob01 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + metadata: + labels: + allow-docker: "true" + app: busybox + spec: + containers: + - image: busybox:1.35 + name: busybox + volumes: + - name: docker-vol + hostPath: + path: "/var/run/docker.sock" + restartPolicy: OnFailure +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob02 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + metadata: + labels: + allow-docker: "false" + app: busybox + spec: + containers: + - image: busybox:1.35 + name: busybox + volumes: + - name: foo-vol + hostPath: + path: "/var/foo/bar" + restartPolicy: OnFailure + diff --git a/other-cel/docker-socket-requires-label/.chainsaw-test/pods-bad.yaml b/other-cel/docker-socket-requires-label/.chainsaw-test/pods-bad.yaml new file mode 100644 index 000000000..a6a3bf162 --- /dev/null +++ b/other-cel/docker-socket-requires-label/.chainsaw-test/pods-bad.yaml @@ -0,0 +1,32 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 +spec: + containers: + - image: busybox:1.35 + name: busybox + volumes: + - name: docker-vol + hostPath: + path: "/var/run/docker.sock" +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + foo: bar + allow-docker: "false" + name: badpod02 +spec: + containers: + - image: busybox:1.35 + name: busybox + volumes: + - name: foo-vol + hostPath: + path: "/var/foo/bar" + - name: docker-vol + hostPath: + path: "/var/run/docker.sock" + diff --git a/other-cel/docker-socket-requires-label/.chainsaw-test/pods-good.yaml b/other-cel/docker-socket-requires-label/.chainsaw-test/pods-good.yaml new file mode 100644 index 000000000..79e584641 --- /dev/null +++ b/other-cel/docker-socket-requires-label/.chainsaw-test/pods-good.yaml @@ -0,0 +1,56 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 +spec: + containers: + - image: busybox:1.35 + name: busybox +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + foo: bar + allow-docker: "true" + name: goodpod02 +spec: + containers: + - image: busybox:1.35 + name: busybox +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + foo: bar + allow-docker: "false" + name: goodpod03 +spec: + containers: + - image: busybox:1.35 + name: busybox + volumes: + - name: foo-vol + hostPath: + path: "/var/foo/bar" +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + foo: bar + allow-docker: "true" + name: goodpod04 +spec: + containers: + - image: busybox:1.35 + name: busybox + volumes: + - name: foo-vol + hostPath: + path: "/var/foo/bar" + - name: docker-vol + hostPath: + path: "/var/run/docker.sock" + diff --git a/other-cel/docker-socket-requires-label/.chainsaw-test/policy-ready.yaml b/other-cel/docker-socket-requires-label/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..8698d373a --- /dev/null +++ b/other-cel/docker-socket-requires-label/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: docker-socket-check +status: + ready: true + diff --git a/other-cel/docker-socket-requires-label/.kyverno-test/kyverno-test.yaml b/other-cel/docker-socket-requires-label/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..bdcc535a5 --- /dev/null +++ b/other-cel/docker-socket-requires-label/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,25 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: docker-socket-check +policies: +- ../docker-socket-requires-label.yaml +resources: +- resource.yaml +results: +- kind: Pod + policy: docker-socket-check + resources: + - nginx-bad-1 + - nginx-bad-2 + result: fail + rule: docker-socket-check +- kind: Pod + policy: docker-socket-check + resources: + - nginx-allow-1 + - nginx-allow-2 + - nginx-allow-3 + result: pass + rule: docker-socket-check + diff --git a/other-cel/docker-socket-requires-label/.kyverno-test/resource.yaml b/other-cel/docker-socket-requires-label/.kyverno-test/resource.yaml new file mode 100644 index 000000000..cdd3bc0ec --- /dev/null +++ b/other-cel/docker-socket-requires-label/.kyverno-test/resource.yaml @@ -0,0 +1,74 @@ +apiVersion: v1 +kind: Pod +metadata: + labels: + run: nginx + name: nginx-allow-1 +spec: + containers: + - image: nothinghere + name: nginx +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + allow-docker: "true" + run: nginx + name: nginx-allow-2 +spec: + containers: + - image: nothinghere + name: nginx + volumes: + - hostPath: + path: /var/run/docker.sock + name: test +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + allow-docker: "false" + run: nginx + name: nginx-allow-3 +spec: + containers: + - image: nothinghere + name: nginx + volumes: + - hostPath: + path: /random/value + name: test +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + allow-docker: "false" + run: nginx + name: nginx-bad-1 +spec: + containers: + - image: nothinghere + name: nginx + volumes: + - hostPath: + path: /var/run/docker.sock + name: test +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + run: nginx + name: nginx-bad-2 +spec: + containers: + - image: nothinghere + name: nginx + volumes: + - hostPath: + path: /var/run/docker.sock + name: test + diff --git a/other-cel/docker-socket-requires-label/artifacthub-pkg.yml b/other-cel/docker-socket-requires-label/artifacthub-pkg.yml new file mode 100644 index 000000000..0a0e379c8 --- /dev/null +++ b/other-cel/docker-socket-requires-label/artifacthub-pkg.yml @@ -0,0 +1,24 @@ +name: docker-socket-requires-label-cel +version: 1.0.0 +displayName: Docker Socket Requires Label in CEL expressions +description: >- + Accessing a container engine's socket is for highly specialized use cases and should generally be disabled. If access must be granted, it should be done on an explicit basis. This policy requires that, for any Pod mounting the Docker socket, it must have the label `allow-docker` set to `true`. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/other-cel/docker-socket-requires-label/docker-socket-requires-label.yaml + ``` +keywords: + - kyverno + - Other + - CEL Expressions +readme: | + Accessing a container engine's socket is for highly specialized use cases and should generally be disabled. If access must be granted, it should be done on an explicit basis. This policy requires that, for any Pod mounting the Docker socket, it must have the label `allow-docker` set to `true`. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Other in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Pod" +digest: d577dea5bad5971c21bc1036f97a85c1701a3fdcb2800ee8b4f0708dc2b58101 +createdAt: "2024-03-27T12:13:52Z" + diff --git a/other-cel/docker-socket-requires-label/docker-socket-requires-label.yaml b/other-cel/docker-socket-requires-label/docker-socket-requires-label.yaml new file mode 100644 index 000000000..138b36336 --- /dev/null +++ b/other-cel/docker-socket-requires-label/docker-socket-requires-label.yaml @@ -0,0 +1,37 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: docker-socket-check + annotations: + policies.kyverno.io/title: Docker Socket Requires Label in CEL expressions + policies.kyverno.io/category: Other in CEL + policies.kyverno.io/severity: medium + kyverno.io/kyverno-version: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/subject: Pod + policies.kyverno.io/description: >- + Accessing a container engine's socket is for highly specialized use cases and should generally + be disabled. If access must be granted, it should be done on an explicit basis. This policy + requires that, for any Pod mounting the Docker socket, it must have the label `allow-docker` set + to `true`. +spec: + validationFailureAction: Audit + background: true + rules: + - name: docker-socket-check + match: + any: + - resources: + kinds: + - Pod + validate: + cel: + variables: + - name: hasDockerSocket + expression: "has(object.spec.volumes) && object.spec.volumes.exists(volume, has(volume.hostPath) && volume.hostPath.path == '/var/run/docker.sock')" + - name: isAllowDockerLabelTrue + expression: "has(object.metadata.labels) && 'allow-docker' in object.metadata.labels && object.metadata.labels['allow-docker'] == 'true'" + expressions: + - expression: "!variables.hasDockerSocket || variables.isAllowDockerLabelTrue" + message: "If a hostPath volume exists and is set to `/var/run/docker.sock`, the label `allow-docker` must equal `true`." + diff --git a/other/allowed-pod-priorities/.kyverno-test/kyverno-test.yaml b/other/allowed-pod-priorities/.kyverno-test/kyverno-test.yaml index 3ca64a787..cbafc79f4 100644 --- a/other/allowed-pod-priorities/.kyverno-test/kyverno-test.yaml +++ b/other/allowed-pod-priorities/.kyverno-test/kyverno-test.yaml @@ -16,13 +16,13 @@ results: - kind: CronJob policy: allowed-podpriorities resources: - - hello + - mycronjob result: pass - rule: validate-pod-priority-cronjob + rule: validate-pod-priority - kind: Pod policy: allowed-podpriorities resources: - myapp-pod result: pass - rule: validate-pod-priority-pods + rule: validate-pod-priority variables: values.yaml diff --git a/other/allowed-pod-priorities/.kyverno-test/resource.yaml b/other/allowed-pod-priorities/.kyverno-test/resource.yaml index 389e055f0..6e1aa5096 100644 --- a/other/allowed-pod-priorities/.kyverno-test/resource.yaml +++ b/other/allowed-pod-priorities/.kyverno-test/resource.yaml @@ -35,7 +35,7 @@ spec: apiVersion: batch/v1 kind: CronJob metadata: - name: hello + name: mycronjob namespace: production spec: schedule: "*/1 * * * *" diff --git a/other/allowed-pod-priorities/.kyverno-test/values.yaml b/other/allowed-pod-priorities/.kyverno-test/values.yaml index 6dbab6e10..b0696ce63 100644 --- a/other/allowed-pod-priorities/.kyverno-test/values.yaml +++ b/other/allowed-pod-priorities/.kyverno-test/values.yaml @@ -2,24 +2,16 @@ apiVersion: cli.kyverno.io/v1alpha1 kind: Values policies: - name: allowed-podpriorities - rules: - - name: validate-pod-priority-pods + resources: + - name: myapp-pod values: podprioritydict.data.default: '["high-priority", "moderate-priority", "low-priority"]' request.namespace: default - - name: validate-pod-priority + - name: mydeploy values: podprioritydict.data.default: '["high-priority", "moderate-priority", "low-priority"]' request.namespace: default - - name: validate-pod-priority-cronjob + - name: mycronjob values: podprioritydict.data.production: '["high-priority", "moderate-priority", "low-priority"]' request.namespace: production - - name: autogen-validate-pod-priority-pods - values: - podprioritydict.data.default: '["high-priority", "moderate-priority", "low-priority"]' - request.namespace: default - - name: autogen-cronjob-validate-pod-priority-pods - values: - podprioritydict.data.default: '["high-priority", "moderate-priority", "low-priority"]' - request.namespace: default diff --git a/other/allowed-pod-priorities/allowed-pod-priorities.yaml b/other/allowed-pod-priorities/allowed-pod-priorities.yaml index d8e79a14e..2d3ff6fdb 100644 --- a/other/allowed-pod-priorities/allowed-pod-priorities.yaml +++ b/other/allowed-pod-priorities/allowed-pod-priorities.yaml @@ -19,30 +19,6 @@ spec: background: true rules: - name: validate-pod-priority - context: - - name: podprioritydict - configMap: - name: allowed-pod-priorities - namespace: default - match: - any: - - resources: - kinds: - - Deployment - - DaemonSet - - StatefulSet - - Job - validate: - message: >- - The Pod PriorityClass {{ request.object.spec.template.spec.priorityClassName }} is not in the list - of the following PriorityClasses allowed in this Namespace: {{ podprioritydict.data."{{request.namespace}}" }}. - deny: - conditions: - any: - - key: "{{ request.object.spec.template.spec.priorityClassName }}" - operator: AnyNotIn - value: '{{ podprioritydict.data."{{request.namespace}}" || "" }}' - - name: validate-pod-priority-pods context: - name: podprioritydict configMap: @@ -63,24 +39,3 @@ spec: - key: "{{ request.object.spec.priorityClassName || '' }}" operator: AnyNotIn value: '{{ podprioritydict.data."{{request.namespace}}" || "" }}' - - name: validate-pod-priority-cronjob - context: - - name: podprioritydict - configMap: - name: allowed-pod-priorities - namespace: default - match: - any: - - resources: - kinds: - - CronJob - validate: - message: >- - The Pod PriorityClass {{ request.object.spec.jobTemplate.spec.template.spec.priorityClassName }} is not in the list - of the following PriorityClasses allowed in this Namespace: {{ podprioritydict.data."{{request.namespace}}" }}. - deny: - conditions: - any: - - key: "{{ request.object.spec.jobTemplate.spec.template.spec.priorityClassName }}" - operator: AnyNotIn - value: '{{ podprioritydict.data."{{request.namespace}}" || "" }}' diff --git a/other/allowed-pod-priorities/artifacthub-pkg.yml b/other/allowed-pod-priorities/artifacthub-pkg.yml index 9f01f1dcf..8e4de7306 100644 --- a/other/allowed-pod-priorities/artifacthub-pkg.yml +++ b/other/allowed-pod-priorities/artifacthub-pkg.yml @@ -18,4 +18,4 @@ readme: | annotations: kyverno/category: "Sample" kyverno/subject: "Pod" -digest: dfee34072f20005571e9d91d5f6f34a13b0874332196641ea43e67c7da1a4a1a +digest: 23857e576e4bdd7558082cd538b771f6714dd5d9ba39e32b064517dd701b9be7 diff --git a/other/block-ephemeral-containers/.kyverno-test/kyverno-test.yaml b/other/block-ephemeral-containers/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..84814cb06 --- /dev/null +++ b/other/block-ephemeral-containers/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,25 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: block-ephemeral-containers +policies: +- ../block-ephemeral-containers.yaml +resources: +- resource.yaml +results: +- policy: block-ephemeral-containers + rule: block-ephemeral-containers + resources: + - goodpod01 + - goodpod02 + - goodpod03 + kind: Pod + result: pass +- policy: block-ephemeral-containers + rule: block-ephemeral-containers + resources: + - badpod01 + - badpod02 + - badpod03 + kind: Pod + result: fail diff --git a/other/block-ephemeral-containers/.kyverno-test/resource.yaml b/other/block-ephemeral-containers/.kyverno-test/resource.yaml new file mode 100644 index 000000000..e641e696f --- /dev/null +++ b/other/block-ephemeral-containers/.kyverno-test/resource.yaml @@ -0,0 +1,65 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 +spec: + initContainers: + - name: initcontainer01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod02 +spec: + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod03 +spec: + initContainers: + - name: initcontainer01 + image: dummyimagename + containers: + - name: container01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 +spec: + ephemeralContainers: + - name: ephcontainer01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod02 +spec: + initContainers: + - name: initcontainer01 + image: dummyimagename + ephemeralContainers: + - name: ephcontainer01 + image: dummyimagename +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod03 +spec: + initContainers: + - name: initcontainer01 + image: dummyimagename + containers: + - name: container01 + image: dummyimagename + ephemeralContainers: + - name: ephcontainer01 + image: dummyimagename diff --git a/other/deny-secret-service-account-token-type/artifacthub-pkg.yaml b/other/deny-secret-service-account-token-type/artifacthub-pkg.yaml index 1cbd5e87b..ef11879ba 100644 --- a/other/deny-secret-service-account-token-type/artifacthub-pkg.yaml +++ b/other/deny-secret-service-account-token-type/artifacthub-pkg.yaml @@ -26,5 +26,5 @@ readme: | annotations: kyverno/category: "Security" kyverno/kubernetesVersion: "1.27" - kyverno/subject: "Secret,ServiceAccount" -digest: 106c14ef2f33f3426e8bceaa47f696c7a9a10262955862f680497f3daa34c545 + kyverno/subject: "Secret, ServiceAccount" +digest: 19a0b22cb870d6055ff3cd3e48a987ac1ef6f68ca773d840f4f7f606005859d9 diff --git a/other/deny-secret-service-account-token-type/deny-secret-service-account-token-type.yaml b/other/deny-secret-service-account-token-type/deny-secret-service-account-token-type.yaml index 69059b7be..899f0aef0 100644 --- a/other/deny-secret-service-account-token-type/deny-secret-service-account-token-type.yaml +++ b/other/deny-secret-service-account-token-type/deny-secret-service-account-token-type.yaml @@ -8,7 +8,7 @@ metadata: kyverno.io/kubernetes-version: "1.27" kyverno.io/kyverno-version: 1.11.1 policies.kyverno.io/severity: medium - policies.kyverno.io/subject: Secret + policies.kyverno.io/subject: Secret, ServiceAccount policies.kyverno.io/description: >- Before version 1.24, Kubernetes automatically generated Secret-based tokens for ServiceAccounts. When creating a Secret, you can specify its type using the