From 35b992d03a912db872f56b4cd0ad2f3d5fb184ff Mon Sep 17 00:00:00 2001 From: Chandan-DK Date: Thu, 6 Jun 2024 15:42:46 +0530 Subject: [PATCH] feat: add other policies in CEL expressions - Part 6 (#970) * add CI test for directories starting with res in other-cel Signed-off-by: Chandan-DK * copy restrict-loadbalancer Signed-off-by: Chandan-DK * convert restrict-loadbalancer Signed-off-by: Chandan-DK * copy restrict-networkpolicy-empty-podselector Signed-off-by: Chandan-DK * convert restrict-networkpolicy-empty-podselector Signed-off-by: Chandan-DK * copy restrict-node-affinity Signed-off-by: Chandan-DK * convert restrict-node-affinity Signed-off-by: Chandan-DK * copy restrict-sa-automount-sa-token Signed-off-by: Chandan-DK * convert restrict-sa-automount-sa-token Signed-off-by: Chandan-DK * copy restrict-secret-role-verbs Signed-off-by: Chandan-DK * add kyverno tests for restrict-secret-role-verbs Signed-off-by: Chandan-DK * convert restrict-secret-role-verbs Signed-off-by: Chandan-DK * copy restrict-service-port-range Signed-off-by: Chandan-DK * convert restrict-service-port-range Signed-off-by: Chandan-DK * copy restrict-secrets-by-name Signed-off-by: Chandan-DK * convert restrict-secrets-by-name Signed-off-by: Chandan-DK * copy restrict-storageclass Signed-off-by: Chandan-DK * convert restrict-storageclass Signed-off-by: Chandan-DK * copy restrict-usergroup-fsgroup-id Signed-off-by: Chandan-DK * add kyverno tests for restrict-usergroup-fsgroup-id Signed-off-by: Chandan-DK * convert restrict-usergroup-fsgroup-id Signed-off-by: Chandan-DK * copy restrict-wildcard-resources Signed-off-by: Chandan-DK * add kyverno tests for restrict-wildcard-resources Signed-off-by: Chandan-DK * convert restrict-wildcard-resources Signed-off-by: Chandan-DK * copy restrict-wildcard-verbs Signed-off-by: Chandan-DK * add kyverno tests for restrict-wildcard-verbs Signed-off-by: Chandan-DK * convert restrict-wildcard-verbs Signed-off-by: Chandan-DK * rename files for clarity Signed-off-by: Chandan-DK * add new lines at the end of file Signed-off-by: Chandan-DK * fix cel test Signed-off-by: Chandan-DK * add test case for pod creation without securityContext field Signed-off-by: Chandan-DK * handle case where rules is null in restrict-wildcard-verbs Signed-off-by: Chandan-DK * add edge cases to chainsaw test for restrict-wildcard-verbs Signed-off-by: Chandan-DK * add kyverno tests with edge cases for restrict-wildcard-verbs Signed-off-by: Chandan-DK * handle case where rules is null for restrict-wildcard-resources Signed-off-by: Chandan-DK * add edge cases to chainsaw tests for restrict-wildcard-resources Signed-off-by: Chandan-DK * handle case where rules is null for restrict-clusterrole-nodesproxy Signed-off-by: Chandan-DK * add kyverno test with edge cases for restrict-clusterrole-nodesproxy Signed-off-by: Chandan-DK * add chainsaw edge cases for restrict-clusterrole-nodesproxy Signed-off-by: Chandan-DK * handle case where rules is null in restrict-escalation-verbs-roles Signed-off-by: Chandan-DK * add edge case for kyverno tests in restrict-escalation-verbs-roles Signed-off-by: Chandan-DK * add edge cases to chainsaw tests for restrict-escalation-verbs-roles Signed-off-by: Chandan-DK * handle case where rules is null in restrict-secret-role-verbs Signed-off-by: Chandan-DK * add edge cases for restrict-secret-role-verbs Signed-off-by: Chandan-DK * add edge cases for chainsaw tests in restrict-secret-role-verbs Signed-off-by: Chandan-DK * rename kyverno test resources Signed-off-by: Chandan-DK * elaborate comment Signed-off-by: Chandan-DK --------- Signed-off-by: Chandan-DK Co-authored-by: Mariam Fahmy --- .github/workflows/test.yml | 1 + .../.chainsaw-test/cr-good.yaml | 13 +- .../.kyverno-test/kyverno-test.yaml | 4 +- .../.kyverno-test/resource.yaml | 50 +++++ .../artifacthub-pkg.yml | 2 +- .../restrict-clusterrole-nodesproxy.yaml | 1 + .../.chainsaw-test/cr-good.yaml | 13 +- .../.chainsaw-test/role-good.yaml | 13 +- .../.kyverno-test/kyverno-test.yaml | 2 + .../.kyverno-test/resource.yaml | 18 +- .../artifacthub-pkg.yml | 2 +- .../restrict-escalation-verbs-roles.yaml | 1 + .../.chainsaw-test/chainsaw-test.yaml | 32 +++ .../.chainsaw-test/policy-ready.yaml | 7 + .../.chainsaw-test/svc-bad.yaml | 12 ++ .../.chainsaw-test/svc-good.yaml | 13 ++ .../.kyverno-test/kyverno-test.yaml | 22 +++ .../.kyverno-test/resource.yaml | 26 +++ .../restrict-loadbalancer/artifacthub-pkg.yml | 24 +++ .../restrict-loadbalancer.yaml | 33 ++++ .../.chainsaw-test/chainsaw-test.yaml | 32 +++ .../.chainsaw-test/netpol-bad.yaml | 24 +++ .../.chainsaw-test/netpol-good.yaml | 35 ++++ .../.chainsaw-test/policy-ready.yaml | 7 + .../.kyverno-test/kyverno-test.yaml | 22 +++ .../.kyverno-test/resource.yaml | 35 ++++ .../artifacthub-pkg.yml | 25 +++ ...trict-networkpolicy-empty-podselector.yaml | 39 ++++ .../.chainsaw-test/chainsaw-test.yaml | 39 ++++ .../.chainsaw-test/pod-bad.yaml | 47 +++++ .../.chainsaw-test/pod-good.yaml | 39 ++++ .../.chainsaw-test/podcontroller-bad.yaml | 56 ++++++ .../.chainsaw-test/podcontroller-good.yaml | 46 +++++ .../.chainsaw-test/policy-ready.yaml | 7 + .../.kyverno-test/kyverno-test.yaml | 34 ++++ .../.kyverno-test/resource.yaml | 92 +++++++++ .../artifacthub-pkg.yml | 24 +++ .../restrict-node-affinity.yaml | 33 ++++ .../.chainsaw-test/bad-sa.yaml | 29 +++ .../.chainsaw-test/chainsaw-test.yaml | 32 +++ .../.chainsaw-test/good-sa.yaml | 16 ++ .../.chainsaw-test/policy-ready.yaml | 7 + .../.kyverno-test/kyverno-test.yaml | 22 +++ .../.kyverno-test/resource.yaml | 12 ++ .../artifacthub-pkg.yml | 32 +++ .../restrict-sa-automount-sa-token.yaml | 33 ++++ .../.chainsaw-test/chainsaw-test.yaml | 39 ++++ .../.chainsaw-test/cr-bad.yaml | 33 ++++ .../.chainsaw-test/cr-good.yaml | 41 ++++ .../.chainsaw-test/policy-ready.yaml | 7 + .../.chainsaw-test/role-bad.yaml | 33 ++++ .../.chainsaw-test/role-good.yaml | 41 ++++ .../.kyverno-test/kyverno-test.yaml | 44 +++++ .../.kyverno-test/resource.yaml | 143 ++++++++++++++ .../artifacthub-pkg.yml | 24 +++ .../restrict-secret-role-verbs.yaml | 42 ++++ .../.chainsaw-test/chainsaw-test.yaml | 41 ++++ .../.chainsaw-test/pod-bad.yaml | 93 +++++++++ .../.chainsaw-test/pod-good.yaml | 92 +++++++++ .../.chainsaw-test/podcontroller-bad.yaml | 122 ++++++++++++ .../.chainsaw-test/podcontroller-good.yaml | 122 ++++++++++++ .../.chainsaw-test/policy-ready.yaml | 7 + .../.kyverno-test/kyverno-test.yaml | 64 ++++++ .../.kyverno-test/resource.yaml | 182 ++++++++++++++++++ .../artifacthub-pkg.yml | 24 +++ .../restrict-secrets-by-name.yaml | 70 +++++++ .../.chainsaw-test/chainsaw-test.yaml | 32 +++ .../.chainsaw-test/policy-ready.yaml | 7 + .../.chainsaw-test/svc-bad.yaml | 50 +++++ .../.chainsaw-test/svc-good.yaml | 32 +++ .../.kyverno-test/kyverno-test.yaml | 22 +++ .../.kyverno-test/resource.yaml | 26 +++ .../artifacthub-pkg.yml | 24 +++ .../restrict-service-port-range.yaml | 33 ++++ .../.chainsaw-test/chainsaw-test.yaml | 32 +++ .../.chainsaw-test/policy-ready.yaml | 7 + .../.chainsaw-test/sc-bad.yaml | 13 ++ .../.chainsaw-test/sc-good.yaml | 25 +++ .../.kyverno-test/kyverno-test.yaml | 22 +++ .../.kyverno-test/resource.yaml | 26 +++ .../restrict-storageclass/artifacthub-pkg.yml | 25 +++ .../restrict-storageclass.yaml | 34 ++++ .../.chainsaw-test/chainsaw-test.yaml | 39 ++++ .../.chainsaw-test/pod-bad.yaml | 64 ++++++ .../.chainsaw-test/pod-good.yaml | 15 ++ .../.chainsaw-test/podcontroller-bad.yaml | 88 +++++++++ .../.chainsaw-test/podcontroller-good.yaml | 48 +++++ .../.chainsaw-test/policy-ready.yaml | 7 + .../.kyverno-test/kyverno-test.yaml | 25 +++ .../.kyverno-test/resource.yaml | 72 +++++++ .../artifacthub-pkg.yml | 24 +++ .../restrict-usergroup-fsgroup-id.yaml | 37 ++++ .../.chainsaw-test/chainsaw-test.yaml | 39 ++++ .../.chainsaw-test/cr-bad.yaml | 33 ++++ .../.chainsaw-test/cr-good.yaml | 59 ++++++ .../.chainsaw-test/policy-ready.yaml | 7 + .../.chainsaw-test/role-bad.yaml | 33 ++++ .../.chainsaw-test/role-good.yaml | 59 ++++++ .../.kyverno-test/kyverno-test.yaml | 48 +++++ .../.kyverno-test/resource.yaml | 179 +++++++++++++++++ .../artifacthub-pkg.yml | 25 +++ .../restrict-wildcard-resources.yaml | 35 ++++ .../.chainsaw-test/chainsaw-test.yaml | 39 ++++ .../.chainsaw-test/cr-bad.yaml | 33 ++++ .../.chainsaw-test/cr-good.yaml | 51 +++++ .../.chainsaw-test/policy-ready.yaml | 7 + .../.chainsaw-test/role-bad.yaml | 33 ++++ .../.chainsaw-test/role-good.yaml | 50 +++++ .../.kyverno-test/kyverno-test.yaml | 46 +++++ .../.kyverno-test/resource.yaml | 160 +++++++++++++++ .../artifacthub-pkg.yml | 25 +++ .../restrict-wildcard-verbs.yaml | 35 ++++ .../.kyverno-test/kyverno-test.yaml | 45 +++++ .../.kyverno-test/kyverno-test.yaml | 27 ++- .../.kyverno-test/resource.yaml | 20 +- .../.kyverno-test/kyverno-test.yaml | 48 +++++ 116 files changed, 4323 insertions(+), 14 deletions(-) create mode 100644 other-cel/restrict-clusterrole-nodesproxy/.kyverno-test/resource.yaml create mode 100755 other-cel/restrict-loadbalancer/.chainsaw-test/chainsaw-test.yaml create mode 100755 other-cel/restrict-loadbalancer/.chainsaw-test/policy-ready.yaml create mode 100644 other-cel/restrict-loadbalancer/.chainsaw-test/svc-bad.yaml create mode 100644 other-cel/restrict-loadbalancer/.chainsaw-test/svc-good.yaml create mode 100644 other-cel/restrict-loadbalancer/.kyverno-test/kyverno-test.yaml create mode 100644 other-cel/restrict-loadbalancer/.kyverno-test/resource.yaml create mode 100644 other-cel/restrict-loadbalancer/artifacthub-pkg.yml create mode 100644 other-cel/restrict-loadbalancer/restrict-loadbalancer.yaml create mode 100755 other-cel/restrict-networkpolicy-empty-podselector/.chainsaw-test/chainsaw-test.yaml create mode 100644 other-cel/restrict-networkpolicy-empty-podselector/.chainsaw-test/netpol-bad.yaml create mode 100644 other-cel/restrict-networkpolicy-empty-podselector/.chainsaw-test/netpol-good.yaml create mode 100755 other-cel/restrict-networkpolicy-empty-podselector/.chainsaw-test/policy-ready.yaml create mode 100644 other-cel/restrict-networkpolicy-empty-podselector/.kyverno-test/kyverno-test.yaml create mode 100644 other-cel/restrict-networkpolicy-empty-podselector/.kyverno-test/resource.yaml create mode 100644 other-cel/restrict-networkpolicy-empty-podselector/artifacthub-pkg.yml create mode 100644 other-cel/restrict-networkpolicy-empty-podselector/restrict-networkpolicy-empty-podselector.yaml create mode 100755 other-cel/restrict-node-affinity/.chainsaw-test/chainsaw-test.yaml create mode 100644 other-cel/restrict-node-affinity/.chainsaw-test/pod-bad.yaml create mode 100644 other-cel/restrict-node-affinity/.chainsaw-test/pod-good.yaml create mode 100644 other-cel/restrict-node-affinity/.chainsaw-test/podcontroller-bad.yaml create mode 100644 other-cel/restrict-node-affinity/.chainsaw-test/podcontroller-good.yaml create mode 100755 other-cel/restrict-node-affinity/.chainsaw-test/policy-ready.yaml create mode 100644 other-cel/restrict-node-affinity/.kyverno-test/kyverno-test.yaml create mode 100644 other-cel/restrict-node-affinity/.kyverno-test/resource.yaml create mode 100644 other-cel/restrict-node-affinity/artifacthub-pkg.yml create mode 100644 other-cel/restrict-node-affinity/restrict-node-affinity.yaml create mode 100644 other-cel/restrict-sa-automount-sa-token/.chainsaw-test/bad-sa.yaml create mode 100644 other-cel/restrict-sa-automount-sa-token/.chainsaw-test/chainsaw-test.yaml create mode 100644 other-cel/restrict-sa-automount-sa-token/.chainsaw-test/good-sa.yaml create mode 100644 other-cel/restrict-sa-automount-sa-token/.chainsaw-test/policy-ready.yaml create mode 100644 other-cel/restrict-sa-automount-sa-token/.kyverno-test/kyverno-test.yaml create mode 100644 other-cel/restrict-sa-automount-sa-token/.kyverno-test/resource.yaml create mode 100644 other-cel/restrict-sa-automount-sa-token/artifacthub-pkg.yml create mode 100644 other-cel/restrict-sa-automount-sa-token/restrict-sa-automount-sa-token.yaml create mode 100755 other-cel/restrict-secret-role-verbs/.chainsaw-test/chainsaw-test.yaml create mode 100644 other-cel/restrict-secret-role-verbs/.chainsaw-test/cr-bad.yaml create mode 100644 other-cel/restrict-secret-role-verbs/.chainsaw-test/cr-good.yaml create mode 100755 other-cel/restrict-secret-role-verbs/.chainsaw-test/policy-ready.yaml create mode 100644 other-cel/restrict-secret-role-verbs/.chainsaw-test/role-bad.yaml create mode 100644 other-cel/restrict-secret-role-verbs/.chainsaw-test/role-good.yaml create mode 100644 other-cel/restrict-secret-role-verbs/.kyverno-test/kyverno-test.yaml create mode 100644 other-cel/restrict-secret-role-verbs/.kyverno-test/resource.yaml create mode 100644 other-cel/restrict-secret-role-verbs/artifacthub-pkg.yml create mode 100644 other-cel/restrict-secret-role-verbs/restrict-secret-role-verbs.yaml create mode 100755 other-cel/restrict-secrets-by-name/.chainsaw-test/chainsaw-test.yaml create mode 100644 other-cel/restrict-secrets-by-name/.chainsaw-test/pod-bad.yaml create mode 100644 other-cel/restrict-secrets-by-name/.chainsaw-test/pod-good.yaml create mode 100644 other-cel/restrict-secrets-by-name/.chainsaw-test/podcontroller-bad.yaml create mode 100644 other-cel/restrict-secrets-by-name/.chainsaw-test/podcontroller-good.yaml create mode 100755 other-cel/restrict-secrets-by-name/.chainsaw-test/policy-ready.yaml create mode 100644 other-cel/restrict-secrets-by-name/.kyverno-test/kyverno-test.yaml create mode 100644 other-cel/restrict-secrets-by-name/.kyverno-test/resource.yaml create mode 100644 other-cel/restrict-secrets-by-name/artifacthub-pkg.yml create mode 100644 other-cel/restrict-secrets-by-name/restrict-secrets-by-name.yaml create mode 100755 other-cel/restrict-service-port-range/.chainsaw-test/chainsaw-test.yaml create mode 100755 other-cel/restrict-service-port-range/.chainsaw-test/policy-ready.yaml create mode 100644 other-cel/restrict-service-port-range/.chainsaw-test/svc-bad.yaml create mode 100644 other-cel/restrict-service-port-range/.chainsaw-test/svc-good.yaml create mode 100644 other-cel/restrict-service-port-range/.kyverno-test/kyverno-test.yaml create mode 100644 other-cel/restrict-service-port-range/.kyverno-test/resource.yaml create mode 100644 other-cel/restrict-service-port-range/artifacthub-pkg.yml create mode 100644 other-cel/restrict-service-port-range/restrict-service-port-range.yaml create mode 100755 other-cel/restrict-storageclass/.chainsaw-test/chainsaw-test.yaml create mode 100755 other-cel/restrict-storageclass/.chainsaw-test/policy-ready.yaml create mode 100644 other-cel/restrict-storageclass/.chainsaw-test/sc-bad.yaml create mode 100644 other-cel/restrict-storageclass/.chainsaw-test/sc-good.yaml create mode 100644 other-cel/restrict-storageclass/.kyverno-test/kyverno-test.yaml create mode 100644 other-cel/restrict-storageclass/.kyverno-test/resource.yaml create mode 100644 other-cel/restrict-storageclass/artifacthub-pkg.yml create mode 100644 other-cel/restrict-storageclass/restrict-storageclass.yaml create mode 100755 other-cel/restrict-usergroup-fsgroup-id/.chainsaw-test/chainsaw-test.yaml create mode 100644 other-cel/restrict-usergroup-fsgroup-id/.chainsaw-test/pod-bad.yaml create mode 100644 other-cel/restrict-usergroup-fsgroup-id/.chainsaw-test/pod-good.yaml create mode 100644 other-cel/restrict-usergroup-fsgroup-id/.chainsaw-test/podcontroller-bad.yaml create mode 100644 other-cel/restrict-usergroup-fsgroup-id/.chainsaw-test/podcontroller-good.yaml create mode 100755 other-cel/restrict-usergroup-fsgroup-id/.chainsaw-test/policy-ready.yaml create mode 100644 other-cel/restrict-usergroup-fsgroup-id/.kyverno-test/kyverno-test.yaml create mode 100644 other-cel/restrict-usergroup-fsgroup-id/.kyverno-test/resource.yaml create mode 100644 other-cel/restrict-usergroup-fsgroup-id/artifacthub-pkg.yml create mode 100644 other-cel/restrict-usergroup-fsgroup-id/restrict-usergroup-fsgroup-id.yaml create mode 100755 other-cel/restrict-wildcard-resources/.chainsaw-test/chainsaw-test.yaml create mode 100644 other-cel/restrict-wildcard-resources/.chainsaw-test/cr-bad.yaml create mode 100644 other-cel/restrict-wildcard-resources/.chainsaw-test/cr-good.yaml create mode 100755 other-cel/restrict-wildcard-resources/.chainsaw-test/policy-ready.yaml create mode 100644 other-cel/restrict-wildcard-resources/.chainsaw-test/role-bad.yaml create mode 100644 other-cel/restrict-wildcard-resources/.chainsaw-test/role-good.yaml create mode 100644 other-cel/restrict-wildcard-resources/.kyverno-test/kyverno-test.yaml create mode 100644 other-cel/restrict-wildcard-resources/.kyverno-test/resource.yaml create mode 100644 other-cel/restrict-wildcard-resources/artifacthub-pkg.yml create mode 100644 other-cel/restrict-wildcard-resources/restrict-wildcard-resources.yaml create mode 100755 other-cel/restrict-wildcard-verbs/.chainsaw-test/chainsaw-test.yaml create mode 100644 other-cel/restrict-wildcard-verbs/.chainsaw-test/cr-bad.yaml create mode 100644 other-cel/restrict-wildcard-verbs/.chainsaw-test/cr-good.yaml create mode 100755 other-cel/restrict-wildcard-verbs/.chainsaw-test/policy-ready.yaml create mode 100644 other-cel/restrict-wildcard-verbs/.chainsaw-test/role-bad.yaml create mode 100644 other-cel/restrict-wildcard-verbs/.chainsaw-test/role-good.yaml create mode 100644 other-cel/restrict-wildcard-verbs/.kyverno-test/kyverno-test.yaml create mode 100644 other-cel/restrict-wildcard-verbs/.kyverno-test/resource.yaml create mode 100644 other-cel/restrict-wildcard-verbs/artifacthub-pkg.yml create mode 100644 other-cel/restrict-wildcard-verbs/restrict-wildcard-verbs.yaml create mode 100644 other/restrict-secret-role-verbs/.kyverno-test/kyverno-test.yaml create mode 100644 other/restrict-wildcard-resources/.kyverno-test/kyverno-test.yaml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index da15d9e01..4f138314f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -60,6 +60,7 @@ jobs: - ^other$/^res - ^other-cel$/^res - ^other$/^[s-z] + - ^other-cel$/^res - ^pod-security$ - ^pod-security-cel$ - ^psa$ diff --git a/other-cel/restrict-clusterrole-nodesproxy/.chainsaw-test/cr-good.yaml b/other-cel/restrict-clusterrole-nodesproxy/.chainsaw-test/cr-good.yaml index fa3403cdc..ebb870b7c 100644 --- a/other-cel/restrict-clusterrole-nodesproxy/.chainsaw-test/cr-good.yaml +++ b/other-cel/restrict-clusterrole-nodesproxy/.chainsaw-test/cr-good.yaml @@ -18,4 +18,15 @@ rules: - apiGroups: [""] resources: ["nodes"] verbs: ["get", "watch", "list"] - +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: empty-rules +rules: +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: omitted-rules +--- diff --git a/other-cel/restrict-clusterrole-nodesproxy/.kyverno-test/kyverno-test.yaml b/other-cel/restrict-clusterrole-nodesproxy/.kyverno-test/kyverno-test.yaml index 9a119fe0d..1aa25d73c 100644 --- a/other-cel/restrict-clusterrole-nodesproxy/.kyverno-test/kyverno-test.yaml +++ b/other-cel/restrict-clusterrole-nodesproxy/.kyverno-test/kyverno-test.yaml @@ -5,8 +5,7 @@ metadata: policies: - ../restrict-clusterrole-nodesproxy.yaml resources: -- ../.chainsaw-test/cr-bad.yaml -- ../.chainsaw-test/cr-good.yaml +- resource.yaml results: - policy: restrict-clusterrole-nodesproxy rule: clusterrole-nodesproxy @@ -21,5 +20,6 @@ results: resources: - goodcr01 - goodcr02 + - default-rules result: pass diff --git a/other-cel/restrict-clusterrole-nodesproxy/.kyverno-test/resource.yaml b/other-cel/restrict-clusterrole-nodesproxy/.kyverno-test/resource.yaml new file mode 100644 index 000000000..e33b146f9 --- /dev/null +++ b/other-cel/restrict-clusterrole-nodesproxy/.kyverno-test/resource.yaml @@ -0,0 +1,50 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: badcr01 +rules: +- apiGroups: [""] + resources: ["nodes/proxy", "namespaces"] + verbs: ["get", "watch", "list"] +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: badcr02 +rules: +- apiGroups: [""] + resources: ["pods", "nodes/proxy"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: goodcr01 +rules: +- apiGroups: [""] + resources: ["pods", "namespaces"] + verbs: ["get", "watch", "list"] +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: goodcr02 +rules: +- apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "watch", "list"] +--- +# In the manifest, if the 'rules' field is not specified or is specified as 'rules: ' without a value, +# it will be set to null by default when created in the cluster +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: default-rules +rules: null +--- diff --git a/other-cel/restrict-clusterrole-nodesproxy/artifacthub-pkg.yml b/other-cel/restrict-clusterrole-nodesproxy/artifacthub-pkg.yml index 8d44e34aa..1234f553d 100644 --- a/other-cel/restrict-clusterrole-nodesproxy/artifacthub-pkg.yml +++ b/other-cel/restrict-clusterrole-nodesproxy/artifacthub-pkg.yml @@ -19,6 +19,6 @@ annotations: kyverno/category: "Sample in CEL" kyverno/kubernetesVersion: "1.26-1.27" kyverno/subject: "ClusterRole, RBAC" -digest: 54304b50ebe12dab7f36afa09eaadf5f591d39a2bfe3ee83c150df30cbf66c4b +digest: 5c78dc50201f3223c42e0ac414e23dcc418f487ae76031aa85eb4fbd6fa1a2c1 createdAt: "2024-04-13T16:12:56Z" diff --git a/other-cel/restrict-clusterrole-nodesproxy/restrict-clusterrole-nodesproxy.yaml b/other-cel/restrict-clusterrole-nodesproxy/restrict-clusterrole-nodesproxy.yaml index a3aad1c3f..194bb5ff4 100644 --- a/other-cel/restrict-clusterrole-nodesproxy/restrict-clusterrole-nodesproxy.yaml +++ b/other-cel/restrict-clusterrole-nodesproxy/restrict-clusterrole-nodesproxy.yaml @@ -31,6 +31,7 @@ spec: cel: expressions: - expression: >- + object.rules == null || !object.rules.exists(rule, rule.resources.exists(resource, resource == 'nodes/proxy') && rule.apiGroups.exists(apiGroup, apiGroup == '')) diff --git a/other-cel/restrict-escalation-verbs-roles/.chainsaw-test/cr-good.yaml b/other-cel/restrict-escalation-verbs-roles/.chainsaw-test/cr-good.yaml index 12697fdf8..01050774c 100644 --- a/other-cel/restrict-escalation-verbs-roles/.chainsaw-test/cr-good.yaml +++ b/other-cel/restrict-escalation-verbs-roles/.chainsaw-test/cr-good.yaml @@ -21,4 +21,15 @@ rules: - apiGroups: [""] resources: ["pods", "namespaces"] verbs: ["get", "watch", "list"] - +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: empty-rules +rules: +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: omitted-rules +--- diff --git a/other-cel/restrict-escalation-verbs-roles/.chainsaw-test/role-good.yaml b/other-cel/restrict-escalation-verbs-roles/.chainsaw-test/role-good.yaml index e04eb72ab..a12463103 100644 --- a/other-cel/restrict-escalation-verbs-roles/.chainsaw-test/role-good.yaml +++ b/other-cel/restrict-escalation-verbs-roles/.chainsaw-test/role-good.yaml @@ -21,4 +21,15 @@ rules: - apiGroups: [""] resources: ["pods", "namespaces"] verbs: ["get", "watch", "list"] - +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: empty-rules +rules: +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: omitted-rules +--- diff --git a/other-cel/restrict-escalation-verbs-roles/.kyverno-test/kyverno-test.yaml b/other-cel/restrict-escalation-verbs-roles/.kyverno-test/kyverno-test.yaml index 3ff164eed..ca7c0fea2 100644 --- a/other-cel/restrict-escalation-verbs-roles/.kyverno-test/kyverno-test.yaml +++ b/other-cel/restrict-escalation-verbs-roles/.kyverno-test/kyverno-test.yaml @@ -25,12 +25,14 @@ results: resources: - goodclusterrole01 - goodclusterrole02 + - default-rules result: pass rule: escalate - kind: Role policy: restrict-escalation-verbs-roles resources: - goodrole01 + - default-rules result: pass rule: escalate diff --git a/other-cel/restrict-escalation-verbs-roles/.kyverno-test/resource.yaml b/other-cel/restrict-escalation-verbs-roles/.kyverno-test/resource.yaml index 9eff62656..fcb657c25 100644 --- a/other-cel/restrict-escalation-verbs-roles/.kyverno-test/resource.yaml +++ b/other-cel/restrict-escalation-verbs-roles/.kyverno-test/resource.yaml @@ -101,6 +101,14 @@ rules: verbs: - '*' --- +# In the manifest, if the 'rules' field is not specified or is specified as 'rules: ' without a value, +# it will be set to null by default when created in the cluster +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: default-rules +rules: null +--- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: @@ -126,4 +134,12 @@ rules: - roles verbs: - impersonate - +--- +# In the manifest, if the 'rules' field is not specified or is specified as 'rules: ' without a value, +# it will be set to null by default when created in the cluster +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: default-rules +rules: null +--- diff --git a/other-cel/restrict-escalation-verbs-roles/artifacthub-pkg.yml b/other-cel/restrict-escalation-verbs-roles/artifacthub-pkg.yml index 613ca2550..ae1cb4bef 100644 --- a/other-cel/restrict-escalation-verbs-roles/artifacthub-pkg.yml +++ b/other-cel/restrict-escalation-verbs-roles/artifacthub-pkg.yml @@ -19,6 +19,6 @@ annotations: kyverno/category: "Security in CEL" kyverno/kubernetesVersion: "1.26-1.27" kyverno/subject: "Role, ClusterRole, RBAC" -digest: 79d9c85060d55996f3be6bbc06321edfed00daeaca5bd24a7f4436f23a96bd73 +digest: 145bfa9745d524e77c11d35ea267c3c2323eb6d9d13c3b7c00632eb358da7d75 createdAt: "2024-04-14T15:40:58Z" diff --git a/other-cel/restrict-escalation-verbs-roles/restrict-escalation-verbs-roles.yaml b/other-cel/restrict-escalation-verbs-roles/restrict-escalation-verbs-roles.yaml index f91c58a51..0bbe51474 100644 --- a/other-cel/restrict-escalation-verbs-roles/restrict-escalation-verbs-roles.yaml +++ b/other-cel/restrict-escalation-verbs-roles/restrict-escalation-verbs-roles.yaml @@ -36,6 +36,7 @@ spec: expression: "['*', 'bind', 'escalate', 'impersonate']" expressions: - expression: >- + object.rules == null || !object.rules.exists(rule, rule.apiGroups.exists(apiGroup, apiGroup in variables.apiGroups) && rule.resources.exists(resource, resource in variables.resources) && diff --git a/other-cel/restrict-loadbalancer/.chainsaw-test/chainsaw-test.yaml b/other-cel/restrict-loadbalancer/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..95651dfd0 --- /dev/null +++ b/other-cel/restrict-loadbalancer/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,32 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: restrict-loadbalancer +spec: + steps: + - name: step-01 + try: + - apply: + file: ../restrict-loadbalancer.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: no-loadbalancer-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/restrict-loadbalancer/.chainsaw-test/policy-ready.yaml b/other-cel/restrict-loadbalancer/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..65c013180 --- /dev/null +++ b/other-cel/restrict-loadbalancer/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: no-loadbalancer-service +status: + ready: true + diff --git a/other-cel/restrict-loadbalancer/.chainsaw-test/svc-bad.yaml b/other-cel/restrict-loadbalancer/.chainsaw-test/svc-bad.yaml new file mode 100644 index 000000000..255ca0c2f --- /dev/null +++ b/other-cel/restrict-loadbalancer/.chainsaw-test/svc-bad.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Service +metadata: + name: badsvc01 +spec: + selector: + app: nginx + ports: + - port: 80 + targetPort: 80 + type: LoadBalancer + diff --git a/other-cel/restrict-loadbalancer/.chainsaw-test/svc-good.yaml b/other-cel/restrict-loadbalancer/.chainsaw-test/svc-good.yaml new file mode 100644 index 000000000..a14a0e652 --- /dev/null +++ b/other-cel/restrict-loadbalancer/.chainsaw-test/svc-good.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: goodsvc01 +spec: + selector: + app: nginx + ports: + - port: 80 + targetPort: 80 + nodePort: 30007 + type: NodePort + diff --git a/other-cel/restrict-loadbalancer/.kyverno-test/kyverno-test.yaml b/other-cel/restrict-loadbalancer/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..088d61db2 --- /dev/null +++ b/other-cel/restrict-loadbalancer/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,22 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: no-loadbalancer-service +policies: +- ../restrict-loadbalancer.yaml +resources: +- resource.yaml +results: +- kind: Service + policy: no-loadbalancer-service + resources: + - default/my-service-1 + result: fail + rule: no-LoadBalancer +- kind: Service + policy: no-loadbalancer-service + resources: + - default/my-service-2 + result: pass + rule: no-LoadBalancer + diff --git a/other-cel/restrict-loadbalancer/.kyverno-test/resource.yaml b/other-cel/restrict-loadbalancer/.kyverno-test/resource.yaml new file mode 100644 index 000000000..eaa1dd3ee --- /dev/null +++ b/other-cel/restrict-loadbalancer/.kyverno-test/resource.yaml @@ -0,0 +1,26 @@ +apiVersion: v1 +kind: Service +metadata: + name: my-service-1 +spec: + selector: + app: myapp-1 + ports: + - port: 80 + targetPort: 80 + type: LoadBalancer + +--- +apiVersion: v1 +kind: Service +metadata: + name: my-service-2 +spec: + selector: + app: MyApp + ports: + - port: 80 + targetPort: 80 + nodePort: 30007 + type: NodePort + diff --git a/other-cel/restrict-loadbalancer/artifacthub-pkg.yml b/other-cel/restrict-loadbalancer/artifacthub-pkg.yml new file mode 100644 index 000000000..27245180d --- /dev/null +++ b/other-cel/restrict-loadbalancer/artifacthub-pkg.yml @@ -0,0 +1,24 @@ +name: restrict-loadbalancer-cel +version: 1.0.0 +displayName: Disallow Service Type LoadBalancer in CEL expressions +description: >- + Especially in cloud provider environments, a Service having type LoadBalancer will cause the provider to respond by creating a load balancer somewhere in the customer account. This adds cost and complexity to a deployment. Without restricting this ability, users may easily overrun established budgets and security practices set by the organization. This policy restricts use of the Service type LoadBalancer. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/other-cel/restrict-loadbalancer/restrict-loadbalancer.yaml + ``` +keywords: + - kyverno + - Sample + - CEL Expressions +readme: | + Especially in cloud provider environments, a Service having type LoadBalancer will cause the provider to respond by creating a load balancer somewhere in the customer account. This adds cost and complexity to a deployment. Without restricting this ability, users may easily overrun established budgets and security practices set by the organization. This policy restricts use of the Service type LoadBalancer. + + 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: 33b5031b68eb2f05d6dc535516fff514947846c6b64b1944e1546c897afae750 +createdAt: "2024-04-17T17:49:00Z" + diff --git a/other-cel/restrict-loadbalancer/restrict-loadbalancer.yaml b/other-cel/restrict-loadbalancer/restrict-loadbalancer.yaml new file mode 100644 index 000000000..3d68595b9 --- /dev/null +++ b/other-cel/restrict-loadbalancer/restrict-loadbalancer.yaml @@ -0,0 +1,33 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: no-loadbalancer-service + annotations: + policies.kyverno.io/title: Disallow Service Type LoadBalancer 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: >- + Especially in cloud provider environments, a Service having type LoadBalancer will cause the + provider to respond by creating a load balancer somewhere in the customer account. This adds + cost and complexity to a deployment. Without restricting this ability, users may easily + overrun established budgets and security practices set by the organization. This policy restricts + use of the Service type LoadBalancer. +spec: + validationFailureAction: Audit + background: true + rules: + - name: no-LoadBalancer + match: + any: + - resources: + kinds: + - Service + validate: + cel: + expressions: + - expression: "object.spec.type != 'LoadBalancer'" + message: "Service of type LoadBalancer is not allowed." + diff --git a/other-cel/restrict-networkpolicy-empty-podselector/.chainsaw-test/chainsaw-test.yaml b/other-cel/restrict-networkpolicy-empty-podselector/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..67192a45e --- /dev/null +++ b/other-cel/restrict-networkpolicy-empty-podselector/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,32 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: restrict-networkpolicy-empty-podselector +spec: + steps: + - name: step-01 + try: + - apply: + file: ../restrict-networkpolicy-empty-podselector.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: restrict-networkpolicy-empty-podselector + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: netpol-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: netpol-bad.yaml + diff --git a/other-cel/restrict-networkpolicy-empty-podselector/.chainsaw-test/netpol-bad.yaml b/other-cel/restrict-networkpolicy-empty-podselector/.chainsaw-test/netpol-bad.yaml new file mode 100644 index 000000000..4f6ce4c29 --- /dev/null +++ b/other-cel/restrict-networkpolicy-empty-podselector/.chainsaw-test/netpol-bad.yaml @@ -0,0 +1,24 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: badnetpol01 +spec: + podSelector: {} + policyTypes: + - Egress + ingress: + - from: + - ipBlock: + cidr: 172.17.0.0/16 + except: + - 172.17.1.0/24 + - namespaceSelector: + matchLabels: + project: myproject + - podSelector: + matchLabels: + role: frontend + ports: + - protocol: TCP + port: 6379 + diff --git a/other-cel/restrict-networkpolicy-empty-podselector/.chainsaw-test/netpol-good.yaml b/other-cel/restrict-networkpolicy-empty-podselector/.chainsaw-test/netpol-good.yaml new file mode 100644 index 000000000..0bfd17cf7 --- /dev/null +++ b/other-cel/restrict-networkpolicy-empty-podselector/.chainsaw-test/netpol-good.yaml @@ -0,0 +1,35 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: default-deny +spec: + podSelector: {} + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: goodnetpol01 +spec: + podSelector: + matchLabels: + foo: bar + app: busybox + see: saw + policyTypes: + - Egress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: goodnetpol02 +spec: + podSelector: + matchLabels: + bar: foo + saw: see + app: nginbox + policyTypes: + - Egress + diff --git a/other-cel/restrict-networkpolicy-empty-podselector/.chainsaw-test/policy-ready.yaml b/other-cel/restrict-networkpolicy-empty-podselector/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..156ee3c49 --- /dev/null +++ b/other-cel/restrict-networkpolicy-empty-podselector/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-networkpolicy-empty-podselector +status: + ready: true + diff --git a/other-cel/restrict-networkpolicy-empty-podselector/.kyverno-test/kyverno-test.yaml b/other-cel/restrict-networkpolicy-empty-podselector/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..23941358f --- /dev/null +++ b/other-cel/restrict-networkpolicy-empty-podselector/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,22 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: restrict-networkpolicy-empty-podselector +policies: +- ../restrict-networkpolicy-empty-podselector.yaml +resources: +- resource.yaml +results: +- kind: NetworkPolicy + policy: restrict-networkpolicy-empty-podselector + resources: + - badnetworkpolicy + result: fail + rule: empty-podselector +- kind: NetworkPolicy + policy: restrict-networkpolicy-empty-podselector + resources: + - goodnetworkpolicy + result: pass + rule: empty-podselector + diff --git a/other-cel/restrict-networkpolicy-empty-podselector/.kyverno-test/resource.yaml b/other-cel/restrict-networkpolicy-empty-podselector/.kyverno-test/resource.yaml new file mode 100644 index 000000000..1ea8f1d32 --- /dev/null +++ b/other-cel/restrict-networkpolicy-empty-podselector/.kyverno-test/resource.yaml @@ -0,0 +1,35 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: badnetworkpolicy + namespace: qa +spec: + podSelector: {} + policyTypes: + - Ingress + - Egress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: goodnetworkpolicy + namespace: qa +spec: + podSelector: + matchLabels: + foo: bar + policyTypes: + - Ingress + - Egress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: default-deny + namespace: qa +spec: + podSelector: {} + policyTypes: + - Ingress + - Egress + diff --git a/other-cel/restrict-networkpolicy-empty-podselector/artifacthub-pkg.yml b/other-cel/restrict-networkpolicy-empty-podselector/artifacthub-pkg.yml new file mode 100644 index 000000000..6ff9f7a40 --- /dev/null +++ b/other-cel/restrict-networkpolicy-empty-podselector/artifacthub-pkg.yml @@ -0,0 +1,25 @@ +name: restrict-networkpolicy-empty-podselector-cel +version: 1.0.0 +displayName: Restrict NetworkPolicy with Empty podSelector in CEL expressions +description: >- + By default, all pods in a Kubernetes cluster are allowed to communicate with each other, and all network traffic is unencrypted. It is recommended to not use an empty podSelector in order to more closely control the necessary traffic flows. This policy requires that all NetworkPolicies other than that of `default-deny` not use an empty podSelector. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/other-cel/restrict-networkpolicy-empty-podselector/restrict-networkpolicy-empty-podselector.yaml + ``` +keywords: + - kyverno + - Other + - Multi-Tenancy + - CEL Expressions +readme: | + By default, all pods in a Kubernetes cluster are allowed to communicate with each other, and all network traffic is unencrypted. It is recommended to not use an empty podSelector in order to more closely control the necessary traffic flows. This policy requires that all NetworkPolicies other than that of `default-deny` not use an empty podSelector. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Other, Multi-Tenancy in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "NetworkPolicy" +digest: 3eeb200fc6a3efbfd7855a39e6c39d4d1a9222435b02a81b871a9da523012c63 +createdAt: "2024-04-17T17:51:58Z" + diff --git a/other-cel/restrict-networkpolicy-empty-podselector/restrict-networkpolicy-empty-podselector.yaml b/other-cel/restrict-networkpolicy-empty-podselector/restrict-networkpolicy-empty-podselector.yaml new file mode 100644 index 000000000..ac560629a --- /dev/null +++ b/other-cel/restrict-networkpolicy-empty-podselector/restrict-networkpolicy-empty-podselector.yaml @@ -0,0 +1,39 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-networkpolicy-empty-podselector + annotations: + policies.kyverno.io/title: Restrict NetworkPolicy with Empty podSelector in CEL expressions + policies.kyverno.io/category: Other, Multi-Tenancy in CEL + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: NetworkPolicy + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/description: >- + By default, all pods in a Kubernetes cluster are allowed to communicate with each other, and all + network traffic is unencrypted. It is recommended to not use an empty podSelector in order to + more closely control the necessary traffic flows. This policy requires that all NetworkPolicies + other than that of `default-deny` not use an empty podSelector. +spec: + validationFailureAction: Audit + background: true + rules: + - name: empty-podselector + match: + any: + - resources: + kinds: + - NetworkPolicy + exclude: + any: + - resources: + kinds: + - NetworkPolicy + names: + - default-deny + validate: + cel: + expressions: + - expression: "size(object.spec.podSelector) != 0" + message: "NetworkPolicies must not use an empty podSelector." + diff --git a/other-cel/restrict-node-affinity/.chainsaw-test/chainsaw-test.yaml b/other-cel/restrict-node-affinity/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..867cdf3ae --- /dev/null +++ b/other-cel/restrict-node-affinity/.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: restrict-node-affinity +spec: + steps: + - name: step-01 + try: + - apply: + file: ../restrict-node-affinity.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: restrict-node-affinity + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: pod-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: pod-bad.yaml + - apply: + file: podcontroller-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: podcontroller-bad.yaml + diff --git a/other-cel/restrict-node-affinity/.chainsaw-test/pod-bad.yaml b/other-cel/restrict-node-affinity/.chainsaw-test/pod-bad.yaml new file mode 100644 index 000000000..6b604e991 --- /dev/null +++ b/other-cel/restrict-node-affinity/.chainsaw-test/pod-bad.yaml @@ -0,0 +1,47 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 +spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + preference: + matchExpressions: + - key: foo + operator: In + values: + - bar + containers: + - name: busybox + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod02 +spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + preference: + matchExpressions: + - key: foo + operator: In + values: + - bar + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: security + operator: In + values: + - S1 + topologyKey: topology.kubernetes.io/zone + containers: + - name: busybox + image: busybox:1.35 + diff --git a/other-cel/restrict-node-affinity/.chainsaw-test/pod-good.yaml b/other-cel/restrict-node-affinity/.chainsaw-test/pod-good.yaml new file mode 100644 index 000000000..f30a43957 --- /dev/null +++ b/other-cel/restrict-node-affinity/.chainsaw-test/pod-good.yaml @@ -0,0 +1,39 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 +spec: + containers: + - name: busybox + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod02 +spec: + affinity: + podAffinity: + prefferedDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: bar + operator: In + values: + - bar + topologyKey: topology.kubernetes.io/zone + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + - key: security + operator: In + values: + - S2 + topologyKey: topology.kubernetes.io/zone + containers: + - name: busybox + image: busybox:1.35 + diff --git a/other-cel/restrict-node-affinity/.chainsaw-test/podcontroller-bad.yaml b/other-cel/restrict-node-affinity/.chainsaw-test/podcontroller-bad.yaml new file mode 100644 index 000000000..9e4569861 --- /dev/null +++ b/other-cel/restrict-node-affinity/.chainsaw-test/podcontroller-bad.yaml @@ -0,0 +1,56 @@ +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: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + preference: + matchExpressions: + - key: foo + operator: In + values: + - bar + containers: + - name: busybox + image: busybox:1.35 +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob01 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + preference: + matchExpressions: + - key: foo + operator: In + values: + - bar + containers: + - name: busybox + image: busybox:1.35 + restartPolicy: OnFailure + diff --git a/other-cel/restrict-node-affinity/.chainsaw-test/podcontroller-good.yaml b/other-cel/restrict-node-affinity/.chainsaw-test/podcontroller-good.yaml new file mode 100644 index 000000000..1e7996a78 --- /dev/null +++ b/other-cel/restrict-node-affinity/.chainsaw-test/podcontroller-good.yaml @@ -0,0 +1,46 @@ +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: + affinity: + podAffinity: + prefferedDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: bar + operator: In + values: + - bar + topologyKey: topology.kubernetes.io/zone + containers: + - name: busybox + image: busybox:1.35 +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob01 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + spec: + containers: + - name: busybox + image: busybox:1.35 + restartPolicy: OnFailure + diff --git a/other-cel/restrict-node-affinity/.chainsaw-test/policy-ready.yaml b/other-cel/restrict-node-affinity/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..323503563 --- /dev/null +++ b/other-cel/restrict-node-affinity/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-node-affinity +status: + ready: true + diff --git a/other-cel/restrict-node-affinity/.kyverno-test/kyverno-test.yaml b/other-cel/restrict-node-affinity/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..c48346eda --- /dev/null +++ b/other-cel/restrict-node-affinity/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,34 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: restrict-node-affinity +policies: +- ../restrict-node-affinity.yaml +resources: +- resource.yaml +results: +- kind: Deployment + policy: restrict-node-affinity + resources: + - baddeploy01 + result: fail + rule: check-nodeaffinity +- kind: Pod + policy: restrict-node-affinity + resources: + - badpod01 + result: fail + rule: check-nodeaffinity +- kind: Deployment + policy: restrict-node-affinity + resources: + - gooddeploy01 + result: pass + rule: check-nodeaffinity +- kind: Pod + policy: restrict-node-affinity + resources: + - goodpod01 + result: pass + rule: check-nodeaffinity + diff --git a/other-cel/restrict-node-affinity/.kyverno-test/resource.yaml b/other-cel/restrict-node-affinity/.kyverno-test/resource.yaml new file mode 100644 index 000000000..d3f7d1d9f --- /dev/null +++ b/other-cel/restrict-node-affinity/.kyverno-test/resource.yaml @@ -0,0 +1,92 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 + labels: + app: myapp +spec: + containers: + - name: nginx + image: nginx +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 + labels: + app: myapp +spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: node.info.kubernetes.io/city + operator: In + values: + - shanghai + containers: + - name: nginx + image: nginx +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: baddeploy01 +spec: + replicas: 1 + selector: + matchLabels: + app: web + template: + metadata: + labels: + app: web + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: node.info.kubernetes.io/city + operator: In + values: + - shanghai + containers: + - name: web + image: asfadafdasdfsasasa:latest + imagePullPolicy: Always + resources: + requests: + memory: "256Mi" + cpu: "500m" + limits: + memory: "256Mi" + cpu: "500m" +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gooddeploy01 +spec: + replicas: 1 + selector: + matchLabels: + app: web + template: + metadata: + labels: + app: web + spec: + containers: + - name: web + image: asfadafdasdfsasasa:latest + imagePullPolicy: Always + resources: + requests: + memory: "256Mi" + cpu: "500m" + limits: + memory: "256Mi" + cpu: "500m" + diff --git a/other-cel/restrict-node-affinity/artifacthub-pkg.yml b/other-cel/restrict-node-affinity/artifacthub-pkg.yml new file mode 100644 index 000000000..74c9ede34 --- /dev/null +++ b/other-cel/restrict-node-affinity/artifacthub-pkg.yml @@ -0,0 +1,24 @@ +name: restrict-node-affinity-cel +version: 1.0.0 +displayName: Restrict Node Affinity in CEL expressions +description: >- + Pods may use several mechanisms to prefer scheduling on a set of nodes, and nodeAffinity is one of them. nodeAffinity uses expressions to select eligible nodes for scheduling decisions and may override intended placement options by cluster administrators. This policy ensures that nodeAffinity is not used in a Pod spec. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/other-cel/restrict-node-affinity/restrict-node-affinity.yaml + ``` +keywords: + - kyverno + - Other + - CEL Expressions +readme: | + Pods may use several mechanisms to prefer scheduling on a set of nodes, and nodeAffinity is one of them. nodeAffinity uses expressions to select eligible nodes for scheduling decisions and may override intended placement options by cluster administrators. This policy ensures that nodeAffinity is not used in a Pod spec. + + 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: 333f074f29fd324ac79a1fc9a191d39f73cb83d8c2d17f0dbde5668f959584f3 +createdAt: "2024-04-18T18:08:24Z" + diff --git a/other-cel/restrict-node-affinity/restrict-node-affinity.yaml b/other-cel/restrict-node-affinity/restrict-node-affinity.yaml new file mode 100644 index 000000000..0cd3c3d84 --- /dev/null +++ b/other-cel/restrict-node-affinity/restrict-node-affinity.yaml @@ -0,0 +1,33 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-node-affinity + annotations: + policies.kyverno.io/title: Restrict Node Affinity in CEL expressions + policies.kyverno.io/category: Other in CEL + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + kyverno.io/kyverno-version: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/description: >- + Pods may use several mechanisms to prefer scheduling on a set of nodes, + and nodeAffinity is one of them. nodeAffinity uses expressions to select + eligible nodes for scheduling decisions and may override intended placement + options by cluster administrators. This policy ensures that nodeAffinity + is not used in a Pod spec. +spec: + background: true + validationFailureAction: Audit + rules: + - name: check-nodeaffinity + match: + any: + - resources: + kinds: + - Pod + validate: + cel: + expressions: + - expression: "!has(object.spec.affinity) || !has(object.spec.affinity.nodeAffinity)" + message: "Node affinity cannot be used." + diff --git a/other-cel/restrict-sa-automount-sa-token/.chainsaw-test/bad-sa.yaml b/other-cel/restrict-sa-automount-sa-token/.chainsaw-test/bad-sa.yaml new file mode 100644 index 000000000..89880f707 --- /dev/null +++ b/other-cel/restrict-sa-automount-sa-token/.chainsaw-test/bad-sa.yaml @@ -0,0 +1,29 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: bad-sa-01 +automountServiceAccountToken: true +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + creationTimestamp: 2021-07-07T22:02:39Z + name: bad-sa-02 + namespace: default + uid: 052fb0f4-3d50-11e5-b066-42010af0d7b6 +automountServiceAccountToken: true +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"v1","kind":"ServiceAccount","metadata":{"annotations":{},"name":"example-automated-thing","namespace":"examplens"}} + creationTimestamp: "2019-07-21T07:07:07Z" + name: bad-sa-03 + namespace: default + resourceVersion: "777" + selfLink: /api/v1/namespaces/examplens/serviceaccounts/example-automated-thing + uid: f23fd170-66f2-4697-b049-e1e266b7f835 +automountServiceAccountToken: true + diff --git a/other-cel/restrict-sa-automount-sa-token/.chainsaw-test/chainsaw-test.yaml b/other-cel/restrict-sa-automount-sa-token/.chainsaw-test/chainsaw-test.yaml new file mode 100644 index 000000000..a3a4c4c86 --- /dev/null +++ b/other-cel/restrict-sa-automount-sa-token/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,32 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: restrict-sa-automount-sa-token +spec: + steps: + - name: step-01 + try: + - apply: + file: ../restrict-sa-automount-sa-token.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: restrict-sa-automount-sa-token + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: good-sa.yaml + - apply: + expect: + - check: + ($error != null): true + file: bad-sa.yaml + diff --git a/other-cel/restrict-sa-automount-sa-token/.chainsaw-test/good-sa.yaml b/other-cel/restrict-sa-automount-sa-token/.chainsaw-test/good-sa.yaml new file mode 100644 index 000000000..953ae1484 --- /dev/null +++ b/other-cel/restrict-sa-automount-sa-token/.chainsaw-test/good-sa.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: good-sa + namespace: default +automountServiceAccountToken: false +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + creationTimestamp: 2021-07-07T22:02:39Z + name: good-sa-02 + namespace: default + uid: 052fb0f4-3d50-11e5-b066-42010af0d7b6 +automountServiceAccountToken: false + diff --git a/other-cel/restrict-sa-automount-sa-token/.chainsaw-test/policy-ready.yaml b/other-cel/restrict-sa-automount-sa-token/.chainsaw-test/policy-ready.yaml new file mode 100644 index 000000000..246854703 --- /dev/null +++ b/other-cel/restrict-sa-automount-sa-token/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-sa-automount-sa-token +status: + ready: true + diff --git a/other-cel/restrict-sa-automount-sa-token/.kyverno-test/kyverno-test.yaml b/other-cel/restrict-sa-automount-sa-token/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..29e8dd191 --- /dev/null +++ b/other-cel/restrict-sa-automount-sa-token/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,22 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: restrict-sa-automount-sa-token +policies: +- ../restrict-sa-automount-sa-token.yaml +resources: +- resource.yaml +results: +- kind: ServiceAccount + policy: restrict-sa-automount-sa-token + resources: + - bad-svc + result: fail + rule: validate-sa-automountServiceAccountToken +- kind: ServiceAccount + policy: restrict-sa-automount-sa-token + resources: + - good-svc + result: pass + rule: validate-sa-automountServiceAccountToken + diff --git a/other-cel/restrict-sa-automount-sa-token/.kyverno-test/resource.yaml b/other-cel/restrict-sa-automount-sa-token/.kyverno-test/resource.yaml new file mode 100644 index 000000000..4952d7a9f --- /dev/null +++ b/other-cel/restrict-sa-automount-sa-token/.kyverno-test/resource.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: good-svc +automountServiceAccountToken: false +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: bad-svc +automountServiceAccountToken: true + diff --git a/other-cel/restrict-sa-automount-sa-token/artifacthub-pkg.yml b/other-cel/restrict-sa-automount-sa-token/artifacthub-pkg.yml new file mode 100644 index 000000000..6681c477c --- /dev/null +++ b/other-cel/restrict-sa-automount-sa-token/artifacthub-pkg.yml @@ -0,0 +1,32 @@ +name: restrict-sa-automount-sa-token-cel +version: 1.0.0 +displayName: Restrict Auto-Mount of Service Account Tokens in Service Account in CEL expressions +description: >- + Kubernetes automatically mounts ServiceAccount credentials in each ServiceAccount. + The ServiceAccount may be assigned roles allowing Pods to access API resources. + Blocking this ability is an extension of the least privilege best practice and should + be followed if Pods do not need to speak to the API server to function. + This policy ensures that mounting of these ServiceAccount tokens is blocked. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/other-cel/restrict-sa-automount-sa-token/restrict-sa-automount-sa-token.yaml + ``` +keywords: + - kyverno + - Other + - CEL Expressions +readme: | + Kubernetes automatically mounts ServiceAccount credentials in each ServiceAccount. + The ServiceAccount may be assigned roles allowing Pods to access API resources. + Blocking this ability is an extension of the least privilege best practice and should + be followed if Pods do not need to speak to the API server to function. + This policy ensures that mounting of these ServiceAccount tokens is blocked. + + 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: "ServiceAccount" +digest: 8df2f43e524f85ca4d1ba0b5034a821de452c8affb89c6177db70c53e016ad36 +createdAt: "2024-04-18T18:11:04Z" + diff --git a/other-cel/restrict-sa-automount-sa-token/restrict-sa-automount-sa-token.yaml b/other-cel/restrict-sa-automount-sa-token/restrict-sa-automount-sa-token.yaml new file mode 100644 index 000000000..49e64b3fd --- /dev/null +++ b/other-cel/restrict-sa-automount-sa-token/restrict-sa-automount-sa-token.yaml @@ -0,0 +1,33 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-sa-automount-sa-token + annotations: + policies.kyverno.io/title: Restrict Auto-Mount of Service Account Tokens in Service Account in CEL expressions + policies.kyverno.io/category: Security in CEL + kyverno.io/kyverno-version: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Secret,ServiceAccount + policies.kyverno.io/description: >- + Kubernetes automatically mounts ServiceAccount credentials in each ServiceAccount. + The ServiceAccount may be assigned roles allowing Pods to access API resources. + Blocking this ability is an extension of the least privilege best practice and should + be followed if Pods do not need to speak to the API server to function. + This policy ensures that mounting of these ServiceAccount tokens is blocked. +spec: + validationFailureAction: Audit + background: true + rules: + - name: validate-sa-automountServiceAccountToken + match: + any: + - resources: + kinds: + - ServiceAccount + validate: + cel: + expressions: + - expression: "has(object.automountServiceAccountToken) && object.automountServiceAccountToken == false" + message: "ServiceAccounts must set automountServiceAccountToken to false." + diff --git a/other-cel/restrict-secret-role-verbs/.chainsaw-test/chainsaw-test.yaml b/other-cel/restrict-secret-role-verbs/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..221a87950 --- /dev/null +++ b/other-cel/restrict-secret-role-verbs/.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: restrict-secret-role-verbs +spec: + steps: + - name: step-01 + try: + - apply: + file: ../restrict-secret-role-verbs.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: restrict-secret-role-verbs + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: cr-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: cr-bad.yaml + - apply: + file: role-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: role-bad.yaml + diff --git a/other-cel/restrict-secret-role-verbs/.chainsaw-test/cr-bad.yaml b/other-cel/restrict-secret-role-verbs/.chainsaw-test/cr-bad.yaml new file mode 100644 index 000000000..0e8c5ae8a --- /dev/null +++ b/other-cel/restrict-secret-role-verbs/.chainsaw-test/cr-bad.yaml @@ -0,0 +1,33 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: badcr01 +rules: +- apiGroups: [""] + resources: ["namespaces", "secrets", "pods"] + verbs: ["get", "create"] +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: badcr02 +rules: +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +- apiGroups: [""] + resources: ["namespaces", "secrets", "pods"] + verbs: ["create", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: badcr03 +rules: +- apiGroups: [""] + resources: ["secrets"] + verbs: ["update", "list", "create"] + diff --git a/other-cel/restrict-secret-role-verbs/.chainsaw-test/cr-good.yaml b/other-cel/restrict-secret-role-verbs/.chainsaw-test/cr-good.yaml new file mode 100644 index 000000000..35f80ef44 --- /dev/null +++ b/other-cel/restrict-secret-role-verbs/.chainsaw-test/cr-good.yaml @@ -0,0 +1,41 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: goodcr01 +rules: +- apiGroups: [""] + resources: ["pods", "namespaces"] + verbs: ["get", "watch", "list"] +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: goodcr02 +rules: +- apiGroups: [""] + resources: ["pods"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: goodcr03 +rules: +- apiGroups: [""] + resources: ["secrets"] + verbs: ["create", "update", "patch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: empty-rules +rules: +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: omitted-rules +--- diff --git a/other-cel/restrict-secret-role-verbs/.chainsaw-test/policy-ready.yaml b/other-cel/restrict-secret-role-verbs/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..67a19e521 --- /dev/null +++ b/other-cel/restrict-secret-role-verbs/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-secret-role-verbs +status: + ready: true + diff --git a/other-cel/restrict-secret-role-verbs/.chainsaw-test/role-bad.yaml b/other-cel/restrict-secret-role-verbs/.chainsaw-test/role-bad.yaml new file mode 100644 index 000000000..fbfc92ad8 --- /dev/null +++ b/other-cel/restrict-secret-role-verbs/.chainsaw-test/role-bad.yaml @@ -0,0 +1,33 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: badcr01 +rules: +- apiGroups: [""] + resources: ["namespaces", "secrets", "pods"] + verbs: ["get", "create"] +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: badcr02 +rules: +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +- apiGroups: [""] + resources: ["namespaces", "secrets", "pods"] + verbs: ["create", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: badcr03 +rules: +- apiGroups: [""] + resources: ["secrets"] + verbs: ["update", "list", "create"] + diff --git a/other-cel/restrict-secret-role-verbs/.chainsaw-test/role-good.yaml b/other-cel/restrict-secret-role-verbs/.chainsaw-test/role-good.yaml new file mode 100644 index 000000000..c252062bb --- /dev/null +++ b/other-cel/restrict-secret-role-verbs/.chainsaw-test/role-good.yaml @@ -0,0 +1,41 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: goodcr01 +rules: +- apiGroups: [""] + resources: ["pods", "namespaces"] + verbs: ["get", "watch", "list"] +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: goodcr02 +rules: +- apiGroups: [""] + resources: ["pods"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: goodcr03 +rules: +- apiGroups: [""] + resources: ["secrets"] + verbs: ["create", "update", "patch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: omitted-rules +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: empty-rules +rules: +--- diff --git a/other-cel/restrict-secret-role-verbs/.kyverno-test/kyverno-test.yaml b/other-cel/restrict-secret-role-verbs/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..6373017eb --- /dev/null +++ b/other-cel/restrict-secret-role-verbs/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,44 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: restrict-secret-role-verbs +policies: +- ../restrict-secret-role-verbs.yaml +resources: +- resource.yaml +results: +- kind: ClusterRole + policy: restrict-secret-role-verbs + resources: + - badcr01 + - badcr02 + - badcr03 + result: fail + rule: secret-verbs +- kind: ClusterRole + policy: restrict-secret-role-verbs + resources: + - goodcr01 + - goodcr02 + - goodcr03 + - default-rules + result: pass + rule: secret-verbs +- kind: Role + policy: restrict-secret-role-verbs + resources: + - badrole01 + - badrole02 + - badrole03 + result: fail + rule: secret-verbs +- kind: Role + policy: restrict-secret-role-verbs + resources: + - goodrole01 + - goodrole02 + - goodrole03 + - default-rules + result: pass + rule: secret-verbs + diff --git a/other-cel/restrict-secret-role-verbs/.kyverno-test/resource.yaml b/other-cel/restrict-secret-role-verbs/.kyverno-test/resource.yaml new file mode 100644 index 000000000..b4cc6f887 --- /dev/null +++ b/other-cel/restrict-secret-role-verbs/.kyverno-test/resource.yaml @@ -0,0 +1,143 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: badcr01 +rules: +- apiGroups: [""] + resources: ["namespaces", "secrets", "pods"] + verbs: ["get", "create"] +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: badcr02 +rules: +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +- apiGroups: [""] + resources: ["namespaces", "secrets", "pods"] + verbs: ["create", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: badcr03 +rules: +- apiGroups: [""] + resources: ["secrets"] + verbs: ["update", "list", "create"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: goodcr01 +rules: +- apiGroups: [""] + resources: ["pods", "namespaces"] + verbs: ["get", "watch", "list"] +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: goodcr02 +rules: +- apiGroups: [""] + resources: ["pods"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: goodcr03 +rules: +- apiGroups: [""] + resources: ["secrets"] + verbs: ["create", "update", "patch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: badrole01 +rules: +- apiGroups: [""] + resources: ["namespaces", "secrets", "pods"] + verbs: ["get", "create"] +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: badrole02 +rules: +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +- apiGroups: [""] + resources: ["namespaces", "secrets", "pods"] + verbs: ["create", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: badrole03 +rules: +- apiGroups: [""] + resources: ["secrets"] + verbs: ["update", "list", "create"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: goodrole01 +rules: +- apiGroups: [""] + resources: ["pods", "namespaces"] + verbs: ["get", "watch", "list"] +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: goodrole02 +rules: +- apiGroups: [""] + resources: ["pods"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: goodrole03 +rules: +- apiGroups: [""] + resources: ["secrets"] + verbs: ["create", "update", "patch"] +--- +# In the manifest, if the 'rules' field is not specified or is specified as 'rules: ' without a value, +# it will be set to null by default when created in the cluster +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: default-rules +rules: null +--- +# In the manifest, if the 'rules' field is not specified or is specified as 'rules: ' without a value, +# it will be set to null by default when created in the cluster +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: default-rules +rules: null +--- + diff --git a/other-cel/restrict-secret-role-verbs/artifacthub-pkg.yml b/other-cel/restrict-secret-role-verbs/artifacthub-pkg.yml new file mode 100644 index 000000000..1880c3791 --- /dev/null +++ b/other-cel/restrict-secret-role-verbs/artifacthub-pkg.yml @@ -0,0 +1,24 @@ +name: restrict-secret-role-verbs-cel +version: 1.0.0 +displayName: Restrict Secret Verbs in Roles in CEL expressions +description: >- + The verbs `get`, `list`, and `watch` in a Role or ClusterRole, when paired with the Secrets resource, effectively allows Secrets to be read which may expose sensitive information. This policy prevents a Role or ClusterRole from using these verbs in tandem with Secret resources. In order to fully implement this control, it is recommended to pair this policy with another which also prevents use of the wildcard ('*') in the verbs list either when explicitly naming Secrets or when also using a wildcard in the base API group. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/other-cel/restrict-secret-role-verbs/restrict-secret-role-verbs.yaml + ``` +keywords: + - kyverno + - Security + - CEL Expressions +readme: | + The verbs `get`, `list`, and `watch` in a Role or ClusterRole, when paired with the Secrets resource, effectively allows Secrets to be read which may expose sensitive information. This policy prevents a Role or ClusterRole from using these verbs in tandem with Secret resources. In order to fully implement this control, it is recommended to pair this policy with another which also prevents use of the wildcard ('*') in the verbs list either when explicitly naming Secrets or when also using a wildcard in the base API group. + + 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: "Role, ClusterRole, RBAC" +digest: 87450e9a836bbad32f36134630508ba015ccf9935723807e688cf1e865564163 +createdAt: "2024-04-19T16:41:34Z" + diff --git a/other-cel/restrict-secret-role-verbs/restrict-secret-role-verbs.yaml b/other-cel/restrict-secret-role-verbs/restrict-secret-role-verbs.yaml new file mode 100644 index 000000000..62ffe4ea0 --- /dev/null +++ b/other-cel/restrict-secret-role-verbs/restrict-secret-role-verbs.yaml @@ -0,0 +1,42 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-secret-role-verbs + annotations: + policies.kyverno.io/title: Restrict Secret Verbs in Roles in CEL expressions + policies.kyverno.io/category: Security in CEL + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Role, ClusterRole, RBAC + 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: >- + The verbs `get`, `list`, and `watch` in a Role or ClusterRole, when paired with the Secrets resource, effectively + allows Secrets to be read which may expose sensitive information. This policy prevents + a Role or ClusterRole from using these verbs in tandem with Secret resources. In order to + fully implement this control, it is recommended to pair this policy with another which + also prevents use of the wildcard ('*') in the verbs list either when explicitly naming Secrets + or when also using a wildcard in the base API group. +spec: + validationFailureAction: Audit + background: true + rules: + - name: secret-verbs + match: + any: + - resources: + kinds: + - Role + - ClusterRole + validate: + cel: + variables: + - name: forbiddenVerbs + expression: "['get','list','watch']" + expressions: + - expression: >- + object.rules == null || + !object.rules.exists(rule, + 'secrets' in rule.resources && rule.verbs.exists(verb, verb in variables.forbiddenVerbs)) + message: "Requesting verbs `get`, `list`, or `watch` on Secrets is forbidden." + diff --git a/other-cel/restrict-secrets-by-name/.chainsaw-test/chainsaw-test.yaml b/other-cel/restrict-secrets-by-name/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..7e4b9719a --- /dev/null +++ b/other-cel/restrict-secrets-by-name/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,41 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: restrict-secrets-by-name +spec: + # disable templating because it can cause issues with CEL expressions + template: false + steps: + - name: step-01 + try: + - apply: + file: ../restrict-secrets-by-name.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: restrict-secrets-by-name + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: pod-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: pod-bad.yaml + - apply: + file: podcontroller-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: podcontroller-bad.yaml + diff --git a/other-cel/restrict-secrets-by-name/.chainsaw-test/pod-bad.yaml b/other-cel/restrict-secrets-by-name/.chainsaw-test/pod-bad.yaml new file mode 100644 index 000000000..1860c7f8a --- /dev/null +++ b/other-cel/restrict-secrets-by-name/.chainsaw-test/pod-bad.yaml @@ -0,0 +1,93 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 +spec: + containers: + - name: busybox + image: busybox:1.35 + - name: busybox02 + image: busybox:1.35 + env: + - name: ENV_SECRET + valueFrom: + secretKeyRef: + name: top-secret + key: foo +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod02 +spec: + initContainers: + - name: busybox-init + image: busybox:1.35 + - name: busybox02-init + image: busybox:1.35 + env: + - name: ENV_FOO + value: "bar" + - name: ENV_SECRET + valueFrom: + secretKeyRef: + name: top-secret + key: foo + containers: + - name: busybox + image: busybox:1.35 + - name: busybox02 + image: busybox:1.35 + env: + - name: ENV_SECRET + valueFrom: + secretKeyRef: + name: safe-secret + key: foo +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod03 +spec: + initContainers: + - name: busybox-init + image: busybox:1.35 + envFrom: + - secretRef: + name: safe-secret + - name: busybox02-init + image: busybox:1.35 + containers: + - name: busybox + image: busybox:1.35 + envFrom: + - secretRef: + name: top-secret + - name: busybox02 + image: busybox:1.35 + env: + - name: ENV_SECRET + valueFrom: + secretKeyRef: + name: safe-secret + key: foo +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod04 +spec: + containers: + - name: busybox + image: busybox:1.35 + - name: busybox02 + image: busybox:1.35 + volumes: + - name: not-secret-volume + secret: + secretName: safe-secret + - name: secret-volume + secret: + secretName: top-secret + diff --git a/other-cel/restrict-secrets-by-name/.chainsaw-test/pod-good.yaml b/other-cel/restrict-secrets-by-name/.chainsaw-test/pod-good.yaml new file mode 100644 index 000000000..27a1a5908 --- /dev/null +++ b/other-cel/restrict-secrets-by-name/.chainsaw-test/pod-good.yaml @@ -0,0 +1,92 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 +spec: + containers: + - name: busybox + image: busybox:1.35 + - name: busybox02 + image: busybox:1.35 + env: + - name: ENV_SECRET + valueFrom: + secretKeyRef: + name: safe-secret + key: foo +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod02 +spec: + initContainers: + - name: busybox-init + image: busybox:1.35 + - name: busybox02-init + image: busybox:1.35 + env: + - name: ENV_FOO + value: "bar" + - name: ENV_SECRET + valueFrom: + secretKeyRef: + name: safe-secret + key: foo + containers: + - name: busybox + image: busybox:1.35 + - name: busybox02 + image: busybox:1.35 + env: + - name: ENV_SECRET + valueFrom: + secretKeyRef: + name: safe-secret + key: foo +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod03 +spec: + initContainers: + - name: busybox-init + image: busybox:1.35 + envFrom: + - secretRef: + name: safe-secret + - name: busybox02-init + image: busybox:1.35 + containers: + - name: busybox + image: busybox:1.35 + envFrom: + - secretRef: + name: safe-secret + - name: busybox02 + image: busybox:1.35 + env: + - name: ENV_SECRET + valueFrom: + secretKeyRef: + name: safe-secret + key: foo +--- +apiVersion: v1 +kind: Pod +metadata: + name: goodpod04 +spec: + containers: + - name: busybox + image: busybox:1.35 + - name: busybox02 + image: busybox:1.35 + volumes: + - name: empty-volume + emptyDir: {} + - name: secret-volume + secret: + secretName: safe-secret + diff --git a/other-cel/restrict-secrets-by-name/.chainsaw-test/podcontroller-bad.yaml b/other-cel/restrict-secrets-by-name/.chainsaw-test/podcontroller-bad.yaml new file mode 100644 index 000000000..a7a8666b5 --- /dev/null +++ b/other-cel/restrict-secrets-by-name/.chainsaw-test/podcontroller-bad.yaml @@ -0,0 +1,122 @@ +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: + - name: busybox-init + image: busybox:1.35 + envFrom: + - secretRef: + name: safe-secret + - name: busybox02-init + image: busybox:1.35 + containers: + - name: busybox + image: busybox:1.35 + - name: busybox02 + image: busybox:1.35 + env: + - name: ENV_FOO + value: "bar" + - name: ENV_SECRET + valueFrom: + secretKeyRef: + name: top-secret + key: foo +--- +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: + - name: busybox + image: busybox:1.35 + - name: busybox02 + image: busybox:1.35 + volumes: + - name: secret-volume + secret: + secretName: top-secret +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob01 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + spec: + initContainers: + - name: busybox-init + image: busybox:1.35 + envFrom: + - secretRef: + name: top-secret + - name: busybox02-init + image: busybox:1.35 + containers: + - name: busybox + image: busybox:1.35 + - name: busybox02 + image: busybox:1.35 + env: + - name: ENV_FOO + value: "bar" + - name: ENV_SECRET + valueFrom: + secretKeyRef: + name: safe-secret + key: foo + restartPolicy: OnFailure +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob02 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + spec: + containers: + - name: busybox + image: busybox:1.35 + - name: busybox02 + image: busybox:1.35 + volumes: + - name: empty-volume + emptyDir: {} + - name: secret-volume + secret: + secretName: top-secret + restartPolicy: OnFailure + diff --git a/other-cel/restrict-secrets-by-name/.chainsaw-test/podcontroller-good.yaml b/other-cel/restrict-secrets-by-name/.chainsaw-test/podcontroller-good.yaml new file mode 100644 index 000000000..cc2fde919 --- /dev/null +++ b/other-cel/restrict-secrets-by-name/.chainsaw-test/podcontroller-good.yaml @@ -0,0 +1,122 @@ +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: + - name: busybox-init + image: busybox:1.35 + envFrom: + - secretRef: + name: safe-secret + - name: busybox02-init + image: busybox:1.35 + containers: + - name: busybox + image: busybox:1.35 + - name: busybox02 + image: busybox:1.35 + env: + - name: ENV_FOO + value: "bar" + - name: ENV_SECRET + valueFrom: + secretKeyRef: + name: safe-secret + key: foo +--- +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: + - name: busybox + image: busybox:1.35 + - name: busybox02 + image: busybox:1.35 + volumes: + - name: secret-volume + secret: + secretName: safe-secret +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob01 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + spec: + initContainers: + - name: busybox-init + image: busybox:1.35 + envFrom: + - secretRef: + name: safe-secret + - name: busybox02-init + image: busybox:1.35 + containers: + - name: busybox + image: busybox:1.35 + - name: busybox02 + image: busybox:1.35 + env: + - name: ENV_FOO + value: "bar" + - name: ENV_SECRET + valueFrom: + secretKeyRef: + name: safe-secret + key: foo + restartPolicy: OnFailure +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob02 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + spec: + containers: + - name: busybox + image: busybox:1.35 + - name: busybox02 + image: busybox:1.35 + volumes: + - name: empty-volume + emptyDir: {} + - name: secret-volume + secret: + secretName: safe-secret + restartPolicy: OnFailure + diff --git a/other-cel/restrict-secrets-by-name/.chainsaw-test/policy-ready.yaml b/other-cel/restrict-secrets-by-name/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..2b34811d6 --- /dev/null +++ b/other-cel/restrict-secrets-by-name/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-secrets-by-name +status: + ready: true + diff --git a/other-cel/restrict-secrets-by-name/.kyverno-test/kyverno-test.yaml b/other-cel/restrict-secrets-by-name/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..589fe0f88 --- /dev/null +++ b/other-cel/restrict-secrets-by-name/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,64 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: test-secrets-policy +policies: +- ../restrict-secrets-by-name.yaml +resources: +- resource.yaml +results: +- kind: Deployment + policy: restrict-secrets-by-name + resources: + - bad-deploy-env + result: fail + rule: safe-secrets-from-env +- kind: Pod + policy: restrict-secrets-by-name + resources: + - bad-pod-env + result: fail + rule: safe-secrets-from-env +- kind: Pod + policy: restrict-secrets-by-name + resources: + - good-pod-all + result: pass + rule: safe-secrets-from-env +- kind: Deployment + policy: restrict-secrets-by-name + resources: + - bad-deploy-envfrom + result: fail + rule: safe-secrets-from-envfrom +- kind: Pod + policy: restrict-secrets-by-name + resources: + - bad-pod-envfrom + result: fail + rule: safe-secrets-from-envfrom +- kind: Pod + policy: restrict-secrets-by-name + resources: + - good-pod-all + result: pass + rule: safe-secrets-from-envfrom +- kind: Deployment + policy: restrict-secrets-by-name + resources: + - bad-deploy-vol + result: fail + rule: safe-secrets-from-volumes +- kind: Pod + policy: restrict-secrets-by-name + resources: + - bad-pod-vol + result: fail + rule: safe-secrets-from-volumes +- kind: Pod + policy: restrict-secrets-by-name + resources: + - good-pod-all + result: pass + rule: safe-secrets-from-volumes + diff --git a/other-cel/restrict-secrets-by-name/.kyverno-test/resource.yaml b/other-cel/restrict-secrets-by-name/.kyverno-test/resource.yaml new file mode 100644 index 000000000..b5284b320 --- /dev/null +++ b/other-cel/restrict-secrets-by-name/.kyverno-test/resource.yaml @@ -0,0 +1,182 @@ +--- +apiVersion: v1 +kind: Pod +metadata: + name: good-pod-all + labels: + name: kyvernopod +spec: + automountServiceAccountToken: false + initContainers: + - name: initbusybox-harbor + image: busybox:1.28 + command: ["sleep", "9999"] + env: + - name: initsomething + valueFrom: + secretKeyRef: + name: safe-foo + key: bar + envFrom: + - secretRef: + name: safe-secured + containers: + - name: busybox + image: busybox:1.28 + command: ["sleep", "9999"] + env: + - name: something + valueFrom: + secretKeyRef: + name: safe-foo + key: bar + - name: somethingelse + valueFrom: + secretKeyRef: + name: safe-umbru + key: bissel + envFrom: + - secretRef: + name: safe-secured + volumes: + - name: supersecret + secret: + secretName: safe-testing + - name: vol1 + secret: + secretName: safe-secret + - name: vol2 + secret: + secretName: safe-moresecret +--- +apiVersion: v1 +kind: Pod +metadata: + name: bad-pod-env + labels: + name: kyvernopod +spec: + automountServiceAccountToken: false + containers: + - name: busybox + image: busybox:1.28 + command: ["sleep", "9999"] + env: + - name: something + valueFrom: + secretKeyRef: + name: bad-foo + key: bar +--- +apiVersion: v1 +kind: Pod +metadata: + name: bad-pod-envfrom + labels: + name: kyvernopod +spec: + automountServiceAccountToken: false + containers: + - name: busybox + image: busybox:1.28 + command: ["sleep", "9999"] + envFrom: + - secretRef: + name: bad-secured +--- +apiVersion: v1 +kind: Pod +metadata: + name: bad-pod-vol + labels: + name: kyvernopod +spec: + automountServiceAccountToken: false + containers: + - name: busybox + image: busybox:1.28 + command: ["sleep", "9999"] + volumes: + - name: mysecret + secret: + secretName: boo-secret +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: bad-deploy-env + labels: + blog: forward +spec: + replicas: 1 + selector: + matchLabels: + blog: forward + template: + metadata: + labels: + blog: forward + spec: + automountServiceAccountToken: false + containers: + - name: busybox + image: busybox:1.28 + command: ["sleep", "9999"] + env: + - name: something + valueFrom: + secretKeyRef: + name: bad-foo + key: bar +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: bad-deploy-envfrom + labels: + blog: forward +spec: + replicas: 1 + selector: + matchLabels: + blog: forward + template: + metadata: + labels: + blog: forward + spec: + automountServiceAccountToken: false + containers: + - name: busybox + image: busybox:1.28 + command: ["sleep", "9999"] + envFrom: + - secretRef: + name: bad-secured +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: bad-deploy-vol + labels: + blog: forward +spec: + replicas: 1 + selector: + matchLabels: + blog: forward + template: + metadata: + labels: + blog: forward + spec: + automountServiceAccountToken: false + containers: + - name: busybox + image: busybox:1.28 + command: ["sleep", "9999"] + volumes: + - name: mysecret + secret: + secretName: boo-secret + diff --git a/other-cel/restrict-secrets-by-name/artifacthub-pkg.yml b/other-cel/restrict-secrets-by-name/artifacthub-pkg.yml new file mode 100644 index 000000000..745aa5960 --- /dev/null +++ b/other-cel/restrict-secrets-by-name/artifacthub-pkg.yml @@ -0,0 +1,24 @@ +name: restrict-secrets-by-name-cel +version: 1.0.0 +displayName: Restrict Secrets by Name in CEL expressions +description: >- + Secrets often contain sensitive information and their access should be carefully controlled. Although Kubernetes RBAC can be effective at restricting them in several ways, it lacks the ability to use wildcards in resource names. This policy ensures that only Secrets beginning with the name `safe-` can be consumed by Pods. In order to work effectively, this policy needs to be paired with a separate policy or rule to require `automountServiceAccountToken=false` since this would otherwise result in a Secret being mounted. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/other-cel/restrict-secrets-by-name/restrict-secrets-by-name.yaml + ``` +keywords: + - kyverno + - Other + - CEL Expressions +readme: | + Secrets often contain sensitive information and their access should be carefully controlled. Although Kubernetes RBAC can be effective at restricting them in several ways, it lacks the ability to use wildcards in resource names. This policy ensures that only Secrets beginning with the name `safe-` can be consumed by Pods. In order to work effectively, this policy needs to be paired with a separate policy or rule to require `automountServiceAccountToken=false` 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: 5ea208df44ec2a54705cc73244a374cb2593612182f9d4da8e17749e548e39ad +createdAt: "2024-04-20T16:40:34Z" + diff --git a/other-cel/restrict-secrets-by-name/restrict-secrets-by-name.yaml b/other-cel/restrict-secrets-by-name/restrict-secrets-by-name.yaml new file mode 100644 index 000000000..2f1403578 --- /dev/null +++ b/other-cel/restrict-secrets-by-name/restrict-secrets-by-name.yaml @@ -0,0 +1,70 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-secrets-by-name + annotations: + policies.kyverno.io/title: Restrict Secrets by Name in CEL expressions + policies.kyverno.io/category: Other in CEL + 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 often contain sensitive information and their access should be carefully controlled. + Although Kubernetes RBAC can be effective at restricting them in several ways, + it lacks the ability to use wildcards in resource names. This policy ensures + that only Secrets beginning with the name `safe-` can be consumed by Pods. + In order to work effectively, this policy needs to be paired with a separate policy + or rule to require `automountServiceAccountToken=false` since this would otherwise + result in a Secret being mounted. +spec: + background: false + validationFailureAction: Audit + rules: + - name: safe-secrets-from-env + 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) || env.valueFrom.secretKeyRef.name.startsWith("safe-"))) + message: "Only Secrets beginning with `safe-` may be consumed in env statements." + - name: safe-secrets-from-envfrom + 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.envFrom) || container.envFrom.all(env, + !has(env.secretRef) || env.secretRef.name.startsWith("safe-"))) + message: "Only Secrets beginning with `safe-` may be consumed in envFrom statements." + - name: safe-secrets-from-volumes + match: + any: + - resources: + kinds: + - Pod + validate: + cel: + expressions: + - expression: >- + !has(object.spec.volumes) || object.spec.volumes.all(volume, + !has(volume.secret) || volume.secret.secretName.startsWith("safe-")) + message: "Only Secrets beginning with `safe-` may be consumed in volumes." + diff --git a/other-cel/restrict-service-port-range/.chainsaw-test/chainsaw-test.yaml b/other-cel/restrict-service-port-range/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..5a47d722b --- /dev/null +++ b/other-cel/restrict-service-port-range/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,32 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: restrict-service-port-range +spec: + steps: + - name: step-01 + try: + - apply: + file: ../restrict-service-port-range.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: restrict-service-port-range + 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/restrict-service-port-range/.chainsaw-test/policy-ready.yaml b/other-cel/restrict-service-port-range/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..079120fd4 --- /dev/null +++ b/other-cel/restrict-service-port-range/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-service-port-range +status: + ready: true + diff --git a/other-cel/restrict-service-port-range/.chainsaw-test/svc-bad.yaml b/other-cel/restrict-service-port-range/.chainsaw-test/svc-bad.yaml new file mode 100644 index 000000000..13753a310 --- /dev/null +++ b/other-cel/restrict-service-port-range/.chainsaw-test/svc-bad.yaml @@ -0,0 +1,50 @@ +apiVersion: v1 +kind: Service +metadata: + name: badsvc01 +spec: + selector: + app: nginx + ports: + - name: foo-port + port: 80 + targetPort: 80 + nodePort: 30001 + type: NodePort +--- +apiVersion: v1 +kind: Service +metadata: + name: badsvc02 +spec: + selector: + app: nginx + ports: + - name: foo-port + port: 32111 + targetPort: 32111 + nodePort: 32333 + - name: bar-port + port: 443 + targetPort: 443 + nodePort: 31234 + type: NodePort +--- +apiVersion: v1 +kind: Service +metadata: + name: badsvc03 +spec: + selector: + app: nginx + ports: + - name: foo-port + port: 80 + targetPort: 80 + nodePort: 30001 + - name: bar-port + port: 32999 + targetPort: 32999 + nodePort: 30009 + type: NodePort + diff --git a/other-cel/restrict-service-port-range/.chainsaw-test/svc-good.yaml b/other-cel/restrict-service-port-range/.chainsaw-test/svc-good.yaml new file mode 100644 index 000000000..ab42b93a2 --- /dev/null +++ b/other-cel/restrict-service-port-range/.chainsaw-test/svc-good.yaml @@ -0,0 +1,32 @@ +apiVersion: v1 +kind: Service +metadata: + name: goodsvc01 +spec: + selector: + app: nginx + ports: + - name: port-a + port: 32123 + targetPort: 32123 + nodePort: 31000 + - name: port-b + port: 32444 + targetPort: 32444 + nodePort: 30001 + type: NodePort +--- +apiVersion: v1 +kind: Service +metadata: + name: goodsvc02 +spec: + selector: + app: nginx + ports: + - name: foo-port + port: 32999 + targetPort: 32999 + nodePort: 30009 + type: NodePort + diff --git a/other-cel/restrict-service-port-range/.kyverno-test/kyverno-test.yaml b/other-cel/restrict-service-port-range/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..844ca78ff --- /dev/null +++ b/other-cel/restrict-service-port-range/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,22 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: restrict-service-port-range +policies: +- ../restrict-service-port-range.yaml +resources: +- resource.yaml +results: +- kind: Service + policy: restrict-service-port-range + resources: + - bad-service + result: fail + rule: restrict-port-range +- kind: Service + policy: restrict-service-port-range + resources: + - good-service + result: pass + rule: restrict-port-range + diff --git a/other-cel/restrict-service-port-range/.kyverno-test/resource.yaml b/other-cel/restrict-service-port-range/.kyverno-test/resource.yaml new file mode 100644 index 000000000..96d18f2fa --- /dev/null +++ b/other-cel/restrict-service-port-range/.kyverno-test/resource.yaml @@ -0,0 +1,26 @@ +apiVersion: v1 +kind: Service +metadata: + name: bad-service +spec: + type: NodePort + selector: + app: MyApp + ports: + - port: 80 + targetPort: 80 + nodePort: 30007 +--- +apiVersion: v1 +kind: Service +metadata: + name: good-service +spec: + type: NodePort + selector: + app: MyApp + ports: + - port: 32000 + targetPort: 80 + nodePort: 32000 + diff --git a/other-cel/restrict-service-port-range/artifacthub-pkg.yml b/other-cel/restrict-service-port-range/artifacthub-pkg.yml new file mode 100644 index 000000000..2ed9cf0b7 --- /dev/null +++ b/other-cel/restrict-service-port-range/artifacthub-pkg.yml @@ -0,0 +1,24 @@ +name: restrict-service-port-range-cel +version: 1.0.0 +displayName: Restrict Service Port Range in CEL expressions +description: >- + Services which are allowed to expose any port number may be able to impact other applications running on the Node which require them, or may make specifying security policy externally more challenging. This policy enforces that only the port range 32000 to 33000 may be used for Service resources. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/other-cel/restrict-service-port-range/restrict-service-port-range.yaml + ``` +keywords: + - kyverno + - Other + - CEL Expressions +readme: | + Services which are allowed to expose any port number may be able to impact other applications running on the Node which require them, or may make specifying security policy externally more challenging. This policy enforces that only the port range 32000 to 33000 may be used for Service resources. + + 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: "Service" +digest: 3813e2ff29ae51c28c1a9240be2893dc8a6f94e4229402012f587adbc4af7248 +createdAt: "2024-04-19T16:44:39Z" + diff --git a/other-cel/restrict-service-port-range/restrict-service-port-range.yaml b/other-cel/restrict-service-port-range/restrict-service-port-range.yaml new file mode 100644 index 000000000..53da4a635 --- /dev/null +++ b/other-cel/restrict-service-port-range/restrict-service-port-range.yaml @@ -0,0 +1,33 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-service-port-range + annotations: + policies.kyverno.io/title: Restrict Service Port Range 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: Service + policies.kyverno.io/description: >- + Services which are allowed to expose any port number may be able + to impact other applications running on the Node which require them, + or may make specifying security policy externally more challenging. + This policy enforces that only the port range 32000 to 33000 may + be used for Service resources. +spec: + validationFailureAction: Audit + rules: + - name: restrict-port-range + match: + any: + - resources: + kinds: + - Service + validate: + cel: + expressions: + - expression: "object.spec.ports.all(p, p.port >= 32000 && p.port <= 33000)" + message: Ports must be between 32000-33000 + diff --git a/other-cel/restrict-storageclass/.chainsaw-test/chainsaw-test.yaml b/other-cel/restrict-storageclass/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..27c1d0430 --- /dev/null +++ b/other-cel/restrict-storageclass/.chainsaw-test/chainsaw-test.yaml @@ -0,0 +1,32 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: restrict-storageclass +spec: + steps: + - name: step-01 + try: + - apply: + file: ../restrict-storageclass.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: restrict-storageclass + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: sc-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: sc-bad.yaml + diff --git a/other-cel/restrict-storageclass/.chainsaw-test/policy-ready.yaml b/other-cel/restrict-storageclass/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..1d3572a1d --- /dev/null +++ b/other-cel/restrict-storageclass/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-storageclass +status: + ready: true + diff --git a/other-cel/restrict-storageclass/.chainsaw-test/sc-bad.yaml b/other-cel/restrict-storageclass/.chainsaw-test/sc-bad.yaml new file mode 100644 index 000000000..981083d05 --- /dev/null +++ b/other-cel/restrict-storageclass/.chainsaw-test/sc-bad.yaml @@ -0,0 +1,13 @@ +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: badsc01 +provisioner: kubernetes.io/aws-ebs +parameters: + type: gp2 +reclaimPolicy: Retain +allowVolumeExpansion: true +mountOptions: + - debug +volumeBindingMode: Immediate + diff --git a/other-cel/restrict-storageclass/.chainsaw-test/sc-good.yaml b/other-cel/restrict-storageclass/.chainsaw-test/sc-good.yaml new file mode 100644 index 000000000..c4061a322 --- /dev/null +++ b/other-cel/restrict-storageclass/.chainsaw-test/sc-good.yaml @@ -0,0 +1,25 @@ +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: goodsc01 +provisioner: kubernetes.io/aws-ebs +parameters: + type: gp2 +reclaimPolicy: Delete +allowVolumeExpansion: true +mountOptions: + - debug +volumeBindingMode: Immediate +--- +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: goodsc02 +provisioner: kubernetes.io/aws-ebs +parameters: + type: gp2 +allowVolumeExpansion: true +mountOptions: + - debug +volumeBindingMode: Immediate + diff --git a/other-cel/restrict-storageclass/.kyverno-test/kyverno-test.yaml b/other-cel/restrict-storageclass/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..fa7967a6d --- /dev/null +++ b/other-cel/restrict-storageclass/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,22 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: restrict-storageclass +policies: +- ../restrict-storageclass.yaml +resources: +- resource.yaml +results: +- kind: StorageClass + policy: restrict-storageclass + resources: + - badstorageclass + result: fail + rule: storageclass-delete +- kind: StorageClass + policy: restrict-storageclass + resources: + - goodstorageclass + result: pass + rule: storageclass-delete + diff --git a/other-cel/restrict-storageclass/.kyverno-test/resource.yaml b/other-cel/restrict-storageclass/.kyverno-test/resource.yaml new file mode 100644 index 000000000..a58d4427f --- /dev/null +++ b/other-cel/restrict-storageclass/.kyverno-test/resource.yaml @@ -0,0 +1,26 @@ +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: badstorageclass +provisioner: kubernetes.io/aws-ebs +parameters: + type: gp2 +reclaimPolicy: Retain +allowVolumeExpansion: true +mountOptions: + - debug +volumeBindingMode: Immediate +--- +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: goodstorageclass +provisioner: kubernetes.io/aws-ebs +parameters: + type: gp2 +reclaimPolicy: Delete +allowVolumeExpansion: true +mountOptions: + - debug +volumeBindingMode: Immediate + diff --git a/other-cel/restrict-storageclass/artifacthub-pkg.yml b/other-cel/restrict-storageclass/artifacthub-pkg.yml new file mode 100644 index 000000000..425918b25 --- /dev/null +++ b/other-cel/restrict-storageclass/artifacthub-pkg.yml @@ -0,0 +1,25 @@ +name: restrict-storageclass-cel +version: 1.0.0 +displayName: Restrict StorageClass in CEL expressions +description: >- + StorageClasses allow description of custom "classes" of storage offered by the cluster, based on quality-of-service levels, backup policies, or custom policies determined by the cluster administrators. For shared StorageClasses in a multi-tenancy environment, a reclaimPolicy of `Delete` should be used to ensure a PersistentVolume cannot be reused across Namespaces. This policy requires StorageClasses set a reclaimPolicy of `Delete`. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/other-cel/restrict-storageclass/restrict-storageclass.yaml + ``` +keywords: + - kyverno + - Other + - Multi-Tenancy + - CEL Expressions +readme: | + StorageClasses allow description of custom "classes" of storage offered by the cluster, based on quality-of-service levels, backup policies, or custom policies determined by the cluster administrators. For shared StorageClasses in a multi-tenancy environment, a reclaimPolicy of `Delete` should be used to ensure a PersistentVolume cannot be reused across Namespaces. This policy requires StorageClasses set a reclaimPolicy of `Delete`. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Other, Multi-Tenancy in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "StorageClass" +digest: d210e624e126e2174723ce0b5d7426c641afe8dd45bd79e0380b98714bbb2633 +createdAt: "2024-04-20T16:43:16Z" + diff --git a/other-cel/restrict-storageclass/restrict-storageclass.yaml b/other-cel/restrict-storageclass/restrict-storageclass.yaml new file mode 100644 index 000000000..59acee934 --- /dev/null +++ b/other-cel/restrict-storageclass/restrict-storageclass.yaml @@ -0,0 +1,34 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-storageclass + annotations: + policies.kyverno.io/title: Restrict StorageClass in CEL expressions + policies.kyverno.io/category: Other, Multi-Tenancy in CEL + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: StorageClass + kyverno.io/kyverno-version: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/description: >- + StorageClasses allow description of custom "classes" of storage offered + by the cluster, based on quality-of-service levels, backup policies, or + custom policies determined by the cluster administrators. For shared StorageClasses + in a multi-tenancy environment, a reclaimPolicy of `Delete` should be used to ensure + a PersistentVolume cannot be reused across Namespaces. This policy requires + StorageClasses set a reclaimPolicy of `Delete`. +spec: + validationFailureAction: Audit + background: true + rules: + - name: storageclass-delete + match: + any: + - resources: + kinds: + - StorageClass + validate: + cel: + expressions: + - expression: "object.reclaimPolicy == 'Delete'" + message: "StorageClass must define a reclaimPolicy of Delete." + diff --git a/other-cel/restrict-usergroup-fsgroup-id/.chainsaw-test/chainsaw-test.yaml b/other-cel/restrict-usergroup-fsgroup-id/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..8c0dcfec6 --- /dev/null +++ b/other-cel/restrict-usergroup-fsgroup-id/.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: restrict-usergroup-fsgroup-id +spec: + steps: + - name: step-01 + try: + - apply: + file: ../restrict-usergroup-fsgroup-id.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: validate-userid-groupid-fsgroup + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: pod-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: pod-bad.yaml + - apply: + file: podcontroller-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: podcontroller-bad.yaml + diff --git a/other-cel/restrict-usergroup-fsgroup-id/.chainsaw-test/pod-bad.yaml b/other-cel/restrict-usergroup-fsgroup-id/.chainsaw-test/pod-bad.yaml new file mode 100644 index 000000000..c8a79df26 --- /dev/null +++ b/other-cel/restrict-usergroup-fsgroup-id/.chainsaw-test/pod-bad.yaml @@ -0,0 +1,64 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 +spec: + securityContext: + runAsUser: 2000 + runAsGroup: 1000 + fsGroup: 3000 + containers: + - name: busybox + image: busybox:1.35 + - name: busybox02 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod02 +spec: + securityContext: + fsGroup: 2000 + containers: + - name: busybox + image: busybox:1.35 + - name: busybox02 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod03 +spec: + securityContext: + runAsUser: 1000 + containers: + - name: busybox + image: busybox:1.35 + - name: busybox02 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod04 +spec: + securityContext: + runAsGroup: 4000 + containers: + - name: busybox + image: busybox:1.35 + - name: busybox02 + image: busybox:1.35 +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod05 +spec: + containers: + - name: busybox + image: busybox:1.35 + - name: busybox02 + image: busybox:1.35 diff --git a/other-cel/restrict-usergroup-fsgroup-id/.chainsaw-test/pod-good.yaml b/other-cel/restrict-usergroup-fsgroup-id/.chainsaw-test/pod-good.yaml new file mode 100644 index 000000000..1e87aba91 --- /dev/null +++ b/other-cel/restrict-usergroup-fsgroup-id/.chainsaw-test/pod-good.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 +spec: + securityContext: + runAsUser: 1000 + runAsGroup: 3000 + fsGroup: 2000 + containers: + - name: busybox + image: busybox:1.35 + - name: busybox02 + image: busybox:1.35 + diff --git a/other-cel/restrict-usergroup-fsgroup-id/.chainsaw-test/podcontroller-bad.yaml b/other-cel/restrict-usergroup-fsgroup-id/.chainsaw-test/podcontroller-bad.yaml new file mode 100644 index 000000000..54e8b38a0 --- /dev/null +++ b/other-cel/restrict-usergroup-fsgroup-id/.chainsaw-test/podcontroller-bad.yaml @@ -0,0 +1,88 @@ +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: + securityContext: + runAsUser: 2000 + runAsGroup: 1000 + fsGroup: 3000 + containers: + - name: busybox + image: busybox:1.35 + - name: busybox02 + 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: + labels: + app: busybox + spec: + containers: + - name: busybox + image: busybox:1.35 + - name: busybox02 + image: busybox:1.35 +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob01 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + spec: + securityContext: + runAsUser: 2000 + runAsGroup: 1000 + fsGroup: 3000 + containers: + - name: busybox + image: busybox:1.35 + - name: busybox02 + image: busybox:1.35 + restartPolicy: OnFailure +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: badcronjob02 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + spec: + containers: + - name: busybox + image: busybox:1.35 + - name: busybox02 + image: busybox:1.35 + restartPolicy: OnFailure + diff --git a/other-cel/restrict-usergroup-fsgroup-id/.chainsaw-test/podcontroller-good.yaml b/other-cel/restrict-usergroup-fsgroup-id/.chainsaw-test/podcontroller-good.yaml new file mode 100644 index 000000000..499298727 --- /dev/null +++ b/other-cel/restrict-usergroup-fsgroup-id/.chainsaw-test/podcontroller-good.yaml @@ -0,0 +1,48 @@ +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: + securityContext: + runAsUser: 1000 + runAsGroup: 3000 + fsGroup: 2000 + containers: + - name: busybox + image: busybox:1.35 + - name: busybox02 + image: busybox:1.35 +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: goodcronjob01 +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + spec: + securityContext: + runAsUser: 1000 + runAsGroup: 3000 + fsGroup: 2000 + containers: + - name: busybox + image: busybox:1.35 + - name: busybox02 + image: busybox:1.35 + restartPolicy: OnFailure + diff --git a/other-cel/restrict-usergroup-fsgroup-id/.chainsaw-test/policy-ready.yaml b/other-cel/restrict-usergroup-fsgroup-id/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..1e451f6c3 --- /dev/null +++ b/other-cel/restrict-usergroup-fsgroup-id/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: validate-userid-groupid-fsgroup +status: + ready: true + diff --git a/other-cel/restrict-usergroup-fsgroup-id/.kyverno-test/kyverno-test.yaml b/other-cel/restrict-usergroup-fsgroup-id/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..2405d4be0 --- /dev/null +++ b/other-cel/restrict-usergroup-fsgroup-id/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,25 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: validate-userid-groupid-fsgroup +policies: +- ../restrict-usergroup-fsgroup-id.yaml +resources: +- resource.yaml +results: +- kind: Pod + policy: validate-userid-groupid-fsgroup + resources: + - goodpod + result: pass + rule: validate-userid-groupid-fsgroup +- kind: Pod + policy: validate-userid-groupid-fsgroup + resources: + - badpod01 + - badpod02 + - badpod03 + - badpod04 + result: fail + rule: validate-userid-groupid-fsgroup + diff --git a/other-cel/restrict-usergroup-fsgroup-id/.kyverno-test/resource.yaml b/other-cel/restrict-usergroup-fsgroup-id/.kyverno-test/resource.yaml new file mode 100644 index 000000000..e8753cec7 --- /dev/null +++ b/other-cel/restrict-usergroup-fsgroup-id/.kyverno-test/resource.yaml @@ -0,0 +1,72 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod + labels: + app: myapp +spec: + securityContext: + runAsUser: 1000 + runAsGroup: 3000 + fsGroup: 2000 + containers: + - name: busy + image: busybox +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 + labels: + app: myapp +spec: + securityContext: + runAsUser: 2000 + runAsGroup: 3000 + fsGroup: 2000 + containers: + - name: busy + image: busybox +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod02 + labels: + app: myapp +spec: + securityContext: + runAsUser: 1000 + runAsGroup: 3000 + fsGroup: 1000 + containers: + - name: busy + image: busybox +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod03 + labels: + app: myapp +spec: + securityContext: + runAsUser: 1000 + runAsGroup: 4000 + fsGroup: 1000 + containers: + - name: busy + image: busybox +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod04 + labels: + app: myapp +spec: + securityContext: {} + containers: + - name: busy + image: busybox + diff --git a/other-cel/restrict-usergroup-fsgroup-id/artifacthub-pkg.yml b/other-cel/restrict-usergroup-fsgroup-id/artifacthub-pkg.yml new file mode 100644 index 000000000..86f07618d --- /dev/null +++ b/other-cel/restrict-usergroup-fsgroup-id/artifacthub-pkg.yml @@ -0,0 +1,24 @@ +name: restrict-usergroup-fsgroup-id-cel +version: 1.0.0 +displayName: Validate User ID, Group ID, and FS Group in CEL expressions +description: >- + All processes inside a Pod can be made to run with specific user and groupID by setting `runAsUser` and `runAsGroup` respectively. `fsGroup` can be specified to make sure any file created in the volume will have the specified groupID. This policy validates that these fields are set to the defined values. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/other-cel/restrict-usergroup-fsgroup-id/restrict-usergroup-fsgroup-id.yaml + ``` +keywords: + - kyverno + - Sample + - CEL Expressions +readme: | + All processes inside a Pod can be made to run with specific user and groupID by setting `runAsUser` and `runAsGroup` respectively. `fsGroup` can be specified to make sure any file created in the volume will have the specified groupID. This policy validates that these fields are set to the defined values. + + 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: 4bc42c97f4d88453876a46d9988365409012bf1d4c864edd90cb11b3779ba2c1 +createdAt: "2024-04-20T16:57:00Z" + diff --git a/other-cel/restrict-usergroup-fsgroup-id/restrict-usergroup-fsgroup-id.yaml b/other-cel/restrict-usergroup-fsgroup-id/restrict-usergroup-fsgroup-id.yaml new file mode 100644 index 000000000..bedfdc433 --- /dev/null +++ b/other-cel/restrict-usergroup-fsgroup-id/restrict-usergroup-fsgroup-id.yaml @@ -0,0 +1,37 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: validate-userid-groupid-fsgroup + annotations: + policies.kyverno.io/title: Validate User ID, Group ID, and FS Group in CEL expressions + policies.kyverno.io/category: Sample in CEL + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kyverno-version: 1.11.0 + kyverno.io/kubernetes-version: "1.26-1.27" + policies.kyverno.io/description: >- + All processes inside a Pod can be made to run with specific user and groupID + by setting `runAsUser` and `runAsGroup` respectively. `fsGroup` can be specified + to make sure any file created in the volume will have the specified groupID. + This policy validates that these fields are set to the defined values. +spec: + validationFailureAction: Audit + background: true + rules: + - name: validate-userid-groupid-fsgroup + match: + any: + - resources: + kinds: + - Pod + validate: + cel: + expressions: + - expression: "has(object.spec.securityContext.runAsUser) && object.spec.securityContext.runAsUser == 1000" + message: "User ID should be 1000." + - expression: "has(object.spec.securityContext.runAsGroup) && object.spec.securityContext.runAsGroup == 3000" + message: "Group ID should be 3000." + - expression: "has(object.spec.securityContext.fsGroup) && object.spec.securityContext.fsGroup == 2000" + message: "fs Group should be 2000." + diff --git a/other-cel/restrict-wildcard-resources/.chainsaw-test/chainsaw-test.yaml b/other-cel/restrict-wildcard-resources/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..d2ec23858 --- /dev/null +++ b/other-cel/restrict-wildcard-resources/.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: restrict-wildcard-resources +spec: + steps: + - name: step-01 + try: + - apply: + file: ../restrict-wildcard-resources.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: restrict-wildcard-resources + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: cr-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: cr-bad.yaml + - apply: + file: role-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: role-bad.yaml + diff --git a/other-cel/restrict-wildcard-resources/.chainsaw-test/cr-bad.yaml b/other-cel/restrict-wildcard-resources/.chainsaw-test/cr-bad.yaml new file mode 100644 index 000000000..f0e35e1f6 --- /dev/null +++ b/other-cel/restrict-wildcard-resources/.chainsaw-test/cr-bad.yaml @@ -0,0 +1,33 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: badcr01 +rules: +- apiGroups: [""] + resources: ["namespaces", "*", "pods"] + verbs: ["get", "create"] +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: badcr02 +rules: +- apiGroups: ["apps"] + resources: ["*"] + verbs: ["get", "watch", "list"] +- apiGroups: [""] + resources: ["namespaces", "secrets", "pods"] + verbs: ["create", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: badcr03 +rules: +- apiGroups: [""] + resources: ["*"] + verbs: ["update", "list", "create"] + diff --git a/other-cel/restrict-wildcard-resources/.chainsaw-test/cr-good.yaml b/other-cel/restrict-wildcard-resources/.chainsaw-test/cr-good.yaml new file mode 100644 index 000000000..6c87a785a --- /dev/null +++ b/other-cel/restrict-wildcard-resources/.chainsaw-test/cr-good.yaml @@ -0,0 +1,59 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: goodcr01 +rules: +- apiGroups: [""] + resources: ["pods", "namespaces"] + verbs: ["get", "watch", "list"] +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: goodcr02 +rules: +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "create", "update"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: goodcr03 +rules: +- apiGroups: ["batch"] + resources: ["secrets"] + verbs: ["create", "update", "patch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: goodcr04 +rules: +- apiGroups: [""] + resources: ["secrets"] + verbs: ["*"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: goodcr05 +rules: +- apiGroups: ["*"] + resources: ["secrets"] + verbs: ["create", "update", "patch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: empty-rules +rules: +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: omitted-rules +--- diff --git a/other-cel/restrict-wildcard-resources/.chainsaw-test/policy-ready.yaml b/other-cel/restrict-wildcard-resources/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..8c8bc69c9 --- /dev/null +++ b/other-cel/restrict-wildcard-resources/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-wildcard-resources +status: + ready: true + diff --git a/other-cel/restrict-wildcard-resources/.chainsaw-test/role-bad.yaml b/other-cel/restrict-wildcard-resources/.chainsaw-test/role-bad.yaml new file mode 100644 index 000000000..88d7bdd0d --- /dev/null +++ b/other-cel/restrict-wildcard-resources/.chainsaw-test/role-bad.yaml @@ -0,0 +1,33 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: badcr01 +rules: +- apiGroups: [""] + resources: ["namespaces", "*", "pods"] + verbs: ["get", "create"] +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: badcr02 +rules: +- apiGroups: ["apps"] + resources: ["*"] + verbs: ["get", "watch", "list"] +- apiGroups: [""] + resources: ["namespaces", "secrets", "pods"] + verbs: ["create", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: badcr03 +rules: +- apiGroups: [""] + resources: ["*"] + verbs: ["update", "list", "create"] + diff --git a/other-cel/restrict-wildcard-resources/.chainsaw-test/role-good.yaml b/other-cel/restrict-wildcard-resources/.chainsaw-test/role-good.yaml new file mode 100644 index 000000000..0310612f0 --- /dev/null +++ b/other-cel/restrict-wildcard-resources/.chainsaw-test/role-good.yaml @@ -0,0 +1,59 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: goodcr01 +rules: +- apiGroups: [""] + resources: ["pods", "namespaces"] + verbs: ["get", "watch", "list"] +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: goodcr02 +rules: +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "create", "update"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: goodcr03 +rules: +- apiGroups: ["batch"] + resources: ["secrets"] + verbs: ["create", "update", "patch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: goodcr04 +rules: +- apiGroups: [""] + resources: ["secrets"] + verbs: ["*"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: goodcr05 +rules: +- apiGroups: ["*"] + resources: ["secrets"] + verbs: ["create", "update", "patch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: omitted-rules +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: empty-rules +rules: +--- diff --git a/other-cel/restrict-wildcard-resources/.kyverno-test/kyverno-test.yaml b/other-cel/restrict-wildcard-resources/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..810f8497d --- /dev/null +++ b/other-cel/restrict-wildcard-resources/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,48 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: restrict-wildcard-resources +policies: +- ../restrict-wildcard-resources.yaml +resources: +- resource.yaml +results: +- policy: restrict-wildcard-resources + rule: wildcard-resources + kind: ClusterRole + resources: + - badcr01 + - badcr02 + - badcr03 + result: fail +- policy: restrict-wildcard-resources + rule: wildcard-resources + kind: ClusterRole + resources: + - goodcr01 + - goodcr02 + - goodcr03 + - goodcr04 + - goodcr05 + - default-rules + result: pass +- policy: restrict-wildcard-resources + rule: wildcard-resources + kind: Role + resources: + - badrole01 + - badrole02 + - badrole03 + result: fail +- policy: restrict-wildcard-resources + rule: wildcard-resources + kind: Role + resources: + - goodrole01 + - goodrole02 + - goodrole03 + - goodrole04 + - goodrole05 + - default-rules + result: pass + diff --git a/other-cel/restrict-wildcard-resources/.kyverno-test/resource.yaml b/other-cel/restrict-wildcard-resources/.kyverno-test/resource.yaml new file mode 100644 index 000000000..142b51625 --- /dev/null +++ b/other-cel/restrict-wildcard-resources/.kyverno-test/resource.yaml @@ -0,0 +1,179 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: badcr01 +rules: +- apiGroups: [""] + resources: ["namespaces", "*", "pods"] + verbs: ["get", "create"] +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: badcr02 +rules: +- apiGroups: ["apps"] + resources: ["*"] + verbs: ["get", "watch", "list"] +- apiGroups: [""] + resources: ["namespaces", "secrets", "pods"] + verbs: ["create", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: badcr03 +rules: +- apiGroups: [""] + resources: ["*"] + verbs: ["update", "list", "create"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: goodcr01 +rules: +- apiGroups: [""] + resources: ["pods", "namespaces"] + verbs: ["get", "watch", "list"] +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: goodcr02 +rules: +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "create", "update"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: goodcr03 +rules: +- apiGroups: ["batch"] + resources: ["secrets"] + verbs: ["create", "update", "patch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: goodcr04 +rules: +- apiGroups: [""] + resources: ["secrets"] + verbs: ["*"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: goodcr05 +rules: +- apiGroups: ["*"] + resources: ["secrets"] + verbs: ["create", "update", "patch"] +--- +# In the manifest, if the 'rules' field is not specified or is specified as 'rules: ' without a value, +# it will be set to null by default when created in the cluster +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: default-rules +rules: null +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: badrole01 +rules: +- apiGroups: [""] + resources: ["namespaces", "*", "pods"] + verbs: ["get", "create"] +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: badrole02 +rules: +- apiGroups: ["apps"] + resources: ["*"] + verbs: ["get", "watch", "list"] +- apiGroups: [""] + resources: ["namespaces", "secrets", "pods"] + verbs: ["create", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: badrole03 +rules: +- apiGroups: [""] + resources: ["*"] + verbs: ["update", "list", "create"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: goodrole01 +rules: +- apiGroups: [""] + resources: ["pods", "namespaces"] + verbs: ["get", "watch", "list"] +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: goodrole02 +rules: +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "create", "update"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: goodrole03 +rules: +- apiGroups: ["batch"] + resources: ["secrets"] + verbs: ["create", "update", "patch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: goodrole04 +rules: +- apiGroups: [""] + resources: ["secrets"] + verbs: ["*"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: goodrole05 +rules: +- apiGroups: ["*"] + resources: ["secrets"] + verbs: ["create", "update", "patch"] +--- +# In the manifest, if the 'rules' field is not specified or is specified as 'rules: ' without a value, +# it will be set to null by default when created in the cluster +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: default-rules +rules: null +--- + diff --git a/other-cel/restrict-wildcard-resources/artifacthub-pkg.yml b/other-cel/restrict-wildcard-resources/artifacthub-pkg.yml new file mode 100644 index 000000000..3cb768843 --- /dev/null +++ b/other-cel/restrict-wildcard-resources/artifacthub-pkg.yml @@ -0,0 +1,25 @@ +name: restrict-wildcard-resources-cel +version: 1.0.0 +displayName: Restrict Wildcards in Resources in CEL expressions +description: >- + Wildcards ('*') in resources grants access to all of the resources referenced by the given API group and does not follow the principal of least privilege. As much as possible, avoid such open resources unless scoped to perhaps a custom API group. This policy blocks any Role or ClusterRole that contains a wildcard entry in the resources list found in any rule. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/other-cel/restrict-wildcard-resources/restrict-wildcard-resources.yaml + ``` +keywords: + - kyverno + - Security + - EKS Best Practices + - CEL Expressions +readme: | + Wildcards ('*') in resources grants access to all of the resources referenced by the given API group and does not follow the principal of least privilege. As much as possible, avoid such open resources unless scoped to perhaps a custom API group. This policy blocks any Role or ClusterRole that contains a wildcard entry in the resources list found in any rule. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Security, EKS Best Practices in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "ClusterRole, Role, RBAC" +digest: 23a66b076b1ec1a18888c8eefd740e2fcbffd910a0621c0ec5bb99b056c95d6f +createdAt: "2024-04-21T15:05:39Z" + diff --git a/other-cel/restrict-wildcard-resources/restrict-wildcard-resources.yaml b/other-cel/restrict-wildcard-resources/restrict-wildcard-resources.yaml new file mode 100644 index 000000000..49949d931 --- /dev/null +++ b/other-cel/restrict-wildcard-resources/restrict-wildcard-resources.yaml @@ -0,0 +1,35 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-wildcard-resources + annotations: + policies.kyverno.io/title: Restrict Wildcards in Resources in CEL expressions + policies.kyverno.io/category: Security, EKS Best Practices in CEL + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: ClusterRole, Role, RBAC + 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: >- + Wildcards ('*') in resources grants access to all of the resources referenced by + the given API group and does not follow the principal of least privilege. As much as possible, + avoid such open resources unless scoped to perhaps a custom API group. + This policy blocks any Role or ClusterRole that contains a wildcard entry in + the resources list found in any rule. +spec: + validationFailureAction: Audit + background: true + rules: + - name: wildcard-resources + match: + any: + - resources: + kinds: + - Role + - ClusterRole + validate: + cel: + expressions: + - expression: "object.rules == null || !object.rules.exists(rule, '*' in rule.resources)" + message: "Use of a wildcard ('*') in any resources is forbidden." + diff --git a/other-cel/restrict-wildcard-verbs/.chainsaw-test/chainsaw-test.yaml b/other-cel/restrict-wildcard-verbs/.chainsaw-test/chainsaw-test.yaml new file mode 100755 index 000000000..02e9b4de5 --- /dev/null +++ b/other-cel/restrict-wildcard-verbs/.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: restrict-wildcard-verbs +spec: + steps: + - name: step-01 + try: + - apply: + file: ../restrict-wildcard-verbs.yaml + - patch: + resource: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + metadata: + name: restrict-wildcard-verbs + spec: + validationFailureAction: Enforce + - assert: + file: policy-ready.yaml + - name: step-02 + try: + - apply: + file: cr-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: cr-bad.yaml + - apply: + file: role-good.yaml + - apply: + expect: + - check: + ($error != null): true + file: role-bad.yaml + diff --git a/other-cel/restrict-wildcard-verbs/.chainsaw-test/cr-bad.yaml b/other-cel/restrict-wildcard-verbs/.chainsaw-test/cr-bad.yaml new file mode 100644 index 000000000..f94df1931 --- /dev/null +++ b/other-cel/restrict-wildcard-verbs/.chainsaw-test/cr-bad.yaml @@ -0,0 +1,33 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: badcr01 +rules: +- apiGroups: [""] + resources: ["namespaces","pods"] + verbs: ["*"] +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: badcr02 +rules: +- apiGroups: ["apps"] + resources: ["*"] + verbs: ["get", "watch", "*"] +- apiGroups: [""] + resources: ["namespaces", "secrets", "pods"] + verbs: ["create", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: badcr03 +rules: +- apiGroups: [""] + resources: ["pods"] + verbs: ["update", "*", "create"] + diff --git a/other-cel/restrict-wildcard-verbs/.chainsaw-test/cr-good.yaml b/other-cel/restrict-wildcard-verbs/.chainsaw-test/cr-good.yaml new file mode 100644 index 000000000..40d9e341e --- /dev/null +++ b/other-cel/restrict-wildcard-verbs/.chainsaw-test/cr-good.yaml @@ -0,0 +1,51 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: goodcr01 +rules: +- apiGroups: [""] + resources: ["pods", "namespaces"] + verbs: ["get", "watch", "list"] +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: goodcr02 +rules: +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "create", "update"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: goodcr03 +rules: +- apiGroups: ["batch"] + resources: ["secrets"] + verbs: ["create", "update", "patch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: goodcr04 +rules: +- apiGroups: ["apps"] + resources: ["*"] + verbs: ["create", "update", "patch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: empty-rules +rules: +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: omitted-rules +--- + diff --git a/other-cel/restrict-wildcard-verbs/.chainsaw-test/policy-ready.yaml b/other-cel/restrict-wildcard-verbs/.chainsaw-test/policy-ready.yaml new file mode 100755 index 000000000..a831c631b --- /dev/null +++ b/other-cel/restrict-wildcard-verbs/.chainsaw-test/policy-ready.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-wildcard-verbs +status: + ready: true + diff --git a/other-cel/restrict-wildcard-verbs/.chainsaw-test/role-bad.yaml b/other-cel/restrict-wildcard-verbs/.chainsaw-test/role-bad.yaml new file mode 100644 index 000000000..f385dcbc8 --- /dev/null +++ b/other-cel/restrict-wildcard-verbs/.chainsaw-test/role-bad.yaml @@ -0,0 +1,33 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: badcr01 +rules: +- apiGroups: [""] + resources: ["namespaces","pods"] + verbs: ["*"] +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: badcr02 +rules: +- apiGroups: ["apps"] + resources: ["*"] + verbs: ["get", "watch", "*"] +- apiGroups: [""] + resources: ["namespaces", "secrets", "pods"] + verbs: ["create", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: badcr03 +rules: +- apiGroups: [""] + resources: ["pods"] + verbs: ["update", "*", "create"] + diff --git a/other-cel/restrict-wildcard-verbs/.chainsaw-test/role-good.yaml b/other-cel/restrict-wildcard-verbs/.chainsaw-test/role-good.yaml new file mode 100644 index 000000000..9c1992421 --- /dev/null +++ b/other-cel/restrict-wildcard-verbs/.chainsaw-test/role-good.yaml @@ -0,0 +1,50 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: goodcr01 +rules: +- apiGroups: [""] + resources: ["pods", "namespaces"] + verbs: ["get", "watch", "list"] +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: goodcr02 +rules: +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "create", "update"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: goodcr03 +rules: +- apiGroups: ["batch"] + resources: ["secrets"] + verbs: ["create", "update", "patch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: goodcr04 +rules: +- apiGroups: ["apps"] + resources: ["*"] + verbs: ["create", "update", "patch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: omitted-rules +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: empty-rules +rules: +--- diff --git a/other-cel/restrict-wildcard-verbs/.kyverno-test/kyverno-test.yaml b/other-cel/restrict-wildcard-verbs/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..c2d9246a5 --- /dev/null +++ b/other-cel/restrict-wildcard-verbs/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,46 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: restrict-wildcard-verbs +policies: +- ../restrict-wildcard-verbs.yaml +resources: +- resource.yaml +results: +- policy: restrict-wildcard-verbs + rule: wildcard-verbs + kind: ClusterRole + resources: + - badcr01 + - badcr02 + - badcr03 + result: fail +- policy: restrict-wildcard-verbs + rule: wildcard-verbs + kind: ClusterRole + resources: + - goodcr01 + - goodcr02 + - goodcr03 + - goodcr04 + - default-rules + result: pass +- policy: restrict-wildcard-verbs + rule: wildcard-verbs + kind: Role + resources: + - badrole01 + - badrole02 + - badrole03 + result: fail +- policy: restrict-wildcard-verbs + rule: wildcard-verbs + kind: Role + resources: + - goodrole01 + - goodrole02 + - goodrole03 + - goodrole04 + - default-rules + result: pass + diff --git a/other-cel/restrict-wildcard-verbs/.kyverno-test/resource.yaml b/other-cel/restrict-wildcard-verbs/.kyverno-test/resource.yaml new file mode 100644 index 000000000..980f3de97 --- /dev/null +++ b/other-cel/restrict-wildcard-verbs/.kyverno-test/resource.yaml @@ -0,0 +1,160 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: badcr01 +rules: +- apiGroups: [""] + resources: ["namespaces","pods"] + verbs: ["*"] +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: badcr02 +rules: +- apiGroups: ["apps"] + resources: ["*"] + verbs: ["get", "watch", "*"] +- apiGroups: [""] + resources: ["namespaces", "secrets", "pods"] + verbs: ["create", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: badcr03 +rules: +- apiGroups: [""] + resources: ["pods"] + verbs: ["update", "*", "create"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: goodcr01 +rules: +- apiGroups: [""] + resources: ["pods", "namespaces"] + verbs: ["get", "watch", "list"] +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: goodcr02 +rules: +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "create", "update"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: goodcr03 +rules: +- apiGroups: ["batch"] + resources: ["secrets"] + verbs: ["create", "update", "patch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: goodcr04 +rules: +- apiGroups: ["apps"] + resources: ["*"] + verbs: ["create", "update", "patch"] +--- +# In the manifest, if the 'rules' field is not specified or is specified as 'rules: ' without a value, +# it will be set to null by default when created in the cluster +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: default-rules +rules: null +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: badrole01 +rules: +- apiGroups: [""] + resources: ["namespaces","pods"] + verbs: ["*"] +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: badrole02 +rules: +- apiGroups: ["apps"] + resources: ["*"] + verbs: ["get", "watch", "*"] +- apiGroups: [""] + resources: ["namespaces", "secrets", "pods"] + verbs: ["create", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: badrole03 +rules: +- apiGroups: [""] + resources: ["pods"] + verbs: ["update", "*", "create"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: goodrole01 +rules: +- apiGroups: [""] + resources: ["pods", "namespaces"] + verbs: ["get", "watch", "list"] +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: goodrole02 +rules: +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "create", "update"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: goodrole03 +rules: +- apiGroups: ["batch"] + resources: ["secrets"] + verbs: ["create", "update", "patch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: goodrole04 +rules: +- apiGroups: ["apps"] + resources: ["*"] + verbs: ["create", "update", "patch"] +--- +# In the manifest, if the 'rules' field is not specified or is specified as 'rules: ' without a value, +# it will be set to null by default when created in the cluster +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: default-rules +rules: null +--- diff --git a/other-cel/restrict-wildcard-verbs/artifacthub-pkg.yml b/other-cel/restrict-wildcard-verbs/artifacthub-pkg.yml new file mode 100644 index 000000000..4a867733a --- /dev/null +++ b/other-cel/restrict-wildcard-verbs/artifacthub-pkg.yml @@ -0,0 +1,25 @@ +name: restrict-wildcard-verbs-cel +version: 1.0.0 +displayName: Restrict Wildcard in Verbs in CEL expressions +description: >- + Wildcards ('*') in verbs grants all access to the resources referenced by it and does not follow the principal of least privilege. As much as possible, avoid such open verbs unless scoped to perhaps a custom API group. This policy blocks any Role or ClusterRole that contains a wildcard entry in the verbs list found in any rule. +install: |- + ```shell + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/other-cel/restrict-wildcard-verbs/restrict-wildcard-verbs.yaml + ``` +keywords: + - kyverno + - Security + - EKS Best Practices + - CEL Expressions +readme: | + Wildcards ('*') in verbs grants all access to the resources referenced by it and does not follow the principal of least privilege. As much as possible, avoid such open verbs unless scoped to perhaps a custom API group. This policy blocks any Role or ClusterRole that contains a wildcard entry in the verbs list found in any rule. + + Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/ +annotations: + kyverno/category: "Security, EKS Best Practices in CEL" + kyverno/kubernetesVersion: "1.26-1.27" + kyverno/subject: "Role, ClusterRole, RBAC" +digest: 6d79620ea475c5c6568760c38ce2803679fe0cb0792a5be4acfe9cdc9c2f45bd +createdAt: "2024-04-21T15:09:55Z" + diff --git a/other-cel/restrict-wildcard-verbs/restrict-wildcard-verbs.yaml b/other-cel/restrict-wildcard-verbs/restrict-wildcard-verbs.yaml new file mode 100644 index 000000000..1a073022a --- /dev/null +++ b/other-cel/restrict-wildcard-verbs/restrict-wildcard-verbs.yaml @@ -0,0 +1,35 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-wildcard-verbs + annotations: + policies.kyverno.io/title: Restrict Wildcard in Verbs in CEL expressions + policies.kyverno.io/category: Security, EKS Best Practices in CEL + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Role, ClusterRole, RBAC + 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: >- + Wildcards ('*') in verbs grants all access to the resources referenced by it and + does not follow the principal of least privilege. As much as possible, + avoid such open verbs unless scoped to perhaps a custom API group. + This policy blocks any Role or ClusterRole that contains a wildcard entry in + the verbs list found in any rule. +spec: + validationFailureAction: Audit + background: true + rules: + - name: wildcard-verbs + match: + any: + - resources: + kinds: + - Role + - ClusterRole + validate: + cel: + expressions: + - expression: "object.rules == null || !object.rules.exists(rule, '*' in rule.verbs)" + message: "Use of a wildcard ('*') in any verbs is forbidden." + diff --git a/other/restrict-secret-role-verbs/.kyverno-test/kyverno-test.yaml b/other/restrict-secret-role-verbs/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..e4106c939 --- /dev/null +++ b/other/restrict-secret-role-verbs/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,45 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: restrict-secret-role-verbs +policies: +- ../restrict-secret-role-verbs.yaml +resources: +- ../.chainsaw-test/cr-bad.yaml +- ../.chainsaw-test/cr-good.yaml +- ../.chainsaw-test/role-bad.yaml +- ../.chainsaw-test/role-good.yaml +results: +- kind: ClusterRole + policy: restrict-secret-role-verbs + resources: + - badcr01 + - badcr02 + - badcr03 + result: fail + rule: secret-verbs +- kind: ClusterRole + policy: restrict-secret-role-verbs + resources: + - goodcr01 + - goodcr02 + - goodcr03 + result: pass + rule: secret-verbs +- kind: Role + policy: restrict-secret-role-verbs + resources: + - badcr01 + - badcr02 + - badcr03 + result: fail + rule: secret-verbs +- kind: Role + policy: restrict-secret-role-verbs + resources: + - goodcr01 + - goodcr02 + - goodcr03 + result: pass + rule: secret-verbs + diff --git a/other/restrict-usergroup-fsgroup-id/.kyverno-test/kyverno-test.yaml b/other/restrict-usergroup-fsgroup-id/.kyverno-test/kyverno-test.yaml index 20704827f..dbd6dbcdb 100644 --- a/other/restrict-usergroup-fsgroup-id/.kyverno-test/kyverno-test.yaml +++ b/other/restrict-usergroup-fsgroup-id/.kyverno-test/kyverno-test.yaml @@ -10,18 +10,37 @@ results: - kind: Pod policy: validate-userid-groupid-fsgroup resources: - - default/myapp-pod + - goodpod result: pass - rule: validate-fsgroup + rule: validate-userid - kind: Pod policy: validate-userid-groupid-fsgroup resources: - - default/myapp-pod + - goodpod result: pass rule: validate-groupid - kind: Pod policy: validate-userid-groupid-fsgroup resources: - - default/myapp-pod + - goodpod result: pass + rule: validate-fsgroup +- kind: Pod + policy: validate-userid-groupid-fsgroup + resources: + - badpod + result: fail rule: validate-userid +- kind: Pod + policy: validate-userid-groupid-fsgroup + resources: + - badpod + result: fail + rule: validate-groupid +- kind: Pod + policy: validate-userid-groupid-fsgroup + resources: + - badpod + result: fail + rule: validate-fsgroup + diff --git a/other/restrict-usergroup-fsgroup-id/.kyverno-test/resource.yaml b/other/restrict-usergroup-fsgroup-id/.kyverno-test/resource.yaml index c9a02ddfd..7e1ce1d5e 100644 --- a/other/restrict-usergroup-fsgroup-id/.kyverno-test/resource.yaml +++ b/other/restrict-usergroup-fsgroup-id/.kyverno-test/resource.yaml @@ -1,7 +1,7 @@ apiVersion: v1 kind: Pod metadata: - name: myapp-pod + name: goodpod labels: app: myapp spec: @@ -11,4 +11,20 @@ spec: fsGroup: 2000 containers: - name: busy - image: busybox \ No newline at end of file + image: busybox +--- +apiVersion: v1 +kind: Pod +metadata: + name: badpod + labels: + app: myapp +spec: + securityContext: + runAsUser: 3000 + runAsGroup: 1000 + fsGroup: 3000 + containers: + - name: busy + image: busybox + diff --git a/other/restrict-wildcard-resources/.kyverno-test/kyverno-test.yaml b/other/restrict-wildcard-resources/.kyverno-test/kyverno-test.yaml new file mode 100644 index 000000000..497b788f3 --- /dev/null +++ b/other/restrict-wildcard-resources/.kyverno-test/kyverno-test.yaml @@ -0,0 +1,48 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: restrict-wildcard-resources +policies: +- ../restrict-wildcard-resources.yaml +resources: +- ../.chainsaw-test/cr-bad.yaml +- ../.chainsaw-test/cr-good.yaml +- ../.chainsaw-test/role-bad.yaml +- ../.chainsaw-test/role-good.yaml +results: +- policy: restrict-wildcard-resources + rule: wildcard-resources + kind: ClusterRole + resources: + - badcr01 + - badcr02 + - badcr03 + result: fail +- policy: restrict-wildcard-resources + rule: wildcard-resources + kind: ClusterRole + resources: + - goodcr01 + - goodcr02 + - goodcr03 + - goodcr04 + - goodcr05 + result: pass +- policy: restrict-wildcard-resources + rule: wildcard-resources + kind: Role + resources: + - badcr01 + - badcr02 + - badcr03 + result: fail +- policy: restrict-wildcard-resources + rule: wildcard-resources + kind: Role + resources: + - goodcr01 + - goodcr02 + - goodcr03 + - goodcr04 + - goodcr05 + result: pass