From 386428f9ff6ca3421c21f93a5adaefb61cc82372 Mon Sep 17 00:00:00 2001 From: Rita Zhang Date: Fri, 5 Jul 2024 17:07:38 -0700 Subject: [PATCH 1/3] Add cel for forbidden-sysctls Signed-off-by: Rita Zhang --- .../forbidden-sysctls/1.2.0/README.md | 36 ++ .../1.2.0/artifacthub-pkg.yml | 22 ++ .../1.2.0/kustomization.yaml | 2 + .../psp-forbidden-sysctls/constraint.yaml | 15 + .../psp-forbidden-sysctls/constraint2.yaml | 14 + .../psp-forbidden-sysctls/constraint3.yaml | 15 + .../example_allowed.yaml | 14 + .../example_disallowed.yaml | 16 + .../samples/psp-forbidden-sysctls/update.yaml | 21 ++ .../forbidden-sysctls/1.2.0/suite.yaml | 53 +++ .../forbidden-sysctls/1.2.0/template.yaml | 135 +++++++ .../psp-forbidden-sysctls/constraint2.yaml | 14 + .../psp-forbidden-sysctls/constraint3.yaml | 15 + .../forbidden-sysctls/suite.yaml | 32 ++ .../forbidden-sysctls/template.yaml | 133 ++++--- .../forbidden-sysctls/constraint.tmpl | 18 +- .../forbidden-sysctls/src.cel | 30 ++ website/docs/validation/forbidden-sysctls.md | 340 ++++++++++++++---- 18 files changed, 810 insertions(+), 115 deletions(-) create mode 100644 artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/README.md create mode 100644 artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/artifacthub-pkg.yml create mode 100644 artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/kustomization.yaml create mode 100644 artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/constraint.yaml create mode 100644 artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/constraint2.yaml create mode 100644 artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/constraint3.yaml create mode 100644 artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/example_allowed.yaml create mode 100644 artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/example_disallowed.yaml create mode 100644 artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/update.yaml create mode 100644 artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/suite.yaml create mode 100644 artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/template.yaml create mode 100644 library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/constraint2.yaml create mode 100644 library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/constraint3.yaml create mode 100644 src/pod-security-policy/forbidden-sysctls/src.cel diff --git a/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/README.md b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/README.md new file mode 100644 index 000000000..d8a40937d --- /dev/null +++ b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/README.md @@ -0,0 +1,36 @@ +# Forbidden Sysctls security context policy + +The forbidden sysctls constraint allows one to limit the set of kernel parameters that can be modified by pods. This is accomplished by specifying a combination of allowed and forbidden sysctls using either of two parameters: `allowedSysctls` and `forbiddenSysctls`. + +## Parameters + +`allowedSysctls`: A list of explicitly allowed sysctls. Any sysctl not in this list will be considered forbidden. '*' and trailing wildcards are supported. If unspecified, no limitations are made by this parameter. + +`forbiddenSysctls`: A list of explicitly denied sysctls. Any sysctl in this list will be considered forbidden. '*' and trailing wildcards are supported. If unspecified, no limitations are made by this parameter. + +## Examples + +```yaml +parameters: + allowedSysctls: ['*'] + forbiddenSysctls: + - kernel.msg* + - net.core.somaxconn +``` + +```yaml +parameters: + allowedSysctls: + - kernel.shm_rmid_forced + - net.ipv4.ip_local_port_range + - net.ipv4.tcp_syncookies + - net.ipv4.ping_group_range + forbiddenSysctls: [] +``` + +*Note*: `forbiddenSysctls` takes precedence, such that an explicitly forbidden sysctl is still forbidden even if it appears in `allowedSysctls` as well. However in practice, such overlap between the rules should be avoided. + +## References + +* [Using sysctls in a Kubernetes Cluster](https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/) +* [Kubernetes API Reference - Sysctl](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#sysctl-v1-core) \ No newline at end of file diff --git a/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/artifacthub-pkg.yml b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/artifacthub-pkg.yml new file mode 100644 index 000000000..aae5e46c3 --- /dev/null +++ b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/artifacthub-pkg.yml @@ -0,0 +1,22 @@ +version: 1.2.0 +name: k8spspforbiddensysctls +displayName: Forbidden Sysctls +createdAt: "2024-07-05T17:47:31Z" +description: Controls the `sysctl` profile used by containers. Corresponds to the `allowedUnsafeSysctls` and `forbiddenSysctls` fields in a PodSecurityPolicy. When specified, any sysctl not in the `allowedSysctls` parameter is considered to be forbidden. The `forbiddenSysctls` parameter takes precedence over the `allowedSysctls` parameter. For more information, see https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/ +digest: c34167b32bcd5b55b48a68614ad4b20cd26294d17be559738f01735ab719f621 +license: Apache-2.0 +homeURL: https://open-policy-agent.github.io/gatekeeper-library/website/forbidden-sysctls +keywords: + - gatekeeper + - open-policy-agent + - policies +readme: |- + # Forbidden Sysctls + Controls the `sysctl` profile used by containers. Corresponds to the `allowedUnsafeSysctls` and `forbiddenSysctls` fields in a PodSecurityPolicy. When specified, any sysctl not in the `allowedSysctls` parameter is considered to be forbidden. The `forbiddenSysctls` parameter takes precedence over the `allowedSysctls` parameter. For more information, see https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/ +install: |- + ### Usage + ```shell + kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/template.yaml + ``` +provider: + name: Gatekeeper Library diff --git a/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/kustomization.yaml b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/kustomization.yaml new file mode 100644 index 000000000..7d70d11b7 --- /dev/null +++ b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/kustomization.yaml @@ -0,0 +1,2 @@ +resources: + - template.yaml diff --git a/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/constraint.yaml b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/constraint.yaml new file mode 100644 index 000000000..39abf4b23 --- /dev/null +++ b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/constraint.yaml @@ -0,0 +1,15 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sPSPForbiddenSysctls +metadata: + name: psp-forbidden-sysctls +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] + parameters: + forbiddenSysctls: + # - "*" # * may be used to forbid all sysctls + - kernel.* + allowedSysctls: + - "*" # allows all sysctls. allowedSysctls is optional. diff --git a/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/constraint2.yaml b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/constraint2.yaml new file mode 100644 index 000000000..4306dff41 --- /dev/null +++ b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/constraint2.yaml @@ -0,0 +1,14 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sPSPForbiddenSysctls +metadata: + name: psp-forbidden-sysctls +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] + parameters: + forbiddenSysctls: + - "*" # * forbid all sysctls + allowedSysctls: + - "*" # allows all sysctls. allowedSysctls is optional. diff --git a/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/constraint3.yaml b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/constraint3.yaml new file mode 100644 index 000000000..24f0d3905 --- /dev/null +++ b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/constraint3.yaml @@ -0,0 +1,15 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sPSPForbiddenSysctls +metadata: + name: psp-forbidden-sysctls +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] + parameters: + forbiddenSysctls: + # - "*" # * may be used to forbid all sysctls + - kernel.* + allowedSysctls: + - "net.*" # allows all sysctls. allowedSysctls is optional. diff --git a/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/example_allowed.yaml b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/example_allowed.yaml new file mode 100644 index 000000000..4b6cc4b66 --- /dev/null +++ b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/example_allowed.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx-forbidden-sysctls-disallowed + labels: + app: nginx-forbidden-sysctls +spec: + containers: + - name: nginx + image: nginx + securityContext: + sysctls: + - name: net.core.somaxconn + value: "1024" diff --git a/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/example_disallowed.yaml b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/example_disallowed.yaml new file mode 100644 index 000000000..34ab8f344 --- /dev/null +++ b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/example_disallowed.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx-forbidden-sysctls-disallowed + labels: + app: nginx-forbidden-sysctls +spec: + containers: + - name: nginx + image: nginx + securityContext: + sysctls: + - name: kernel.msgmax + value: "65536" + - name: net.core.somaxconn + value: "1024" diff --git a/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/update.yaml b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/update.yaml new file mode 100644 index 000000000..e4e732be9 --- /dev/null +++ b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/update.yaml @@ -0,0 +1,21 @@ +kind: AdmissionReview +apiVersion: admission.k8s.io/v1beta1 +request: + operation: "UPDATE" + object: + apiVersion: v1 + kind: Pod + metadata: + name: nginx-forbidden-sysctls-disallowed + labels: + app: nginx-forbidden-sysctls + spec: + containers: + - name: nginx + image: nginx + securityContext: + sysctls: + - name: kernel.msgmax + value: "65536" + - name: net.core.somaxconn + value: "1024" diff --git a/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/suite.yaml b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/suite.yaml new file mode 100644 index 000000000..fe394ddd8 --- /dev/null +++ b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/suite.yaml @@ -0,0 +1,53 @@ +kind: Suite +apiVersion: test.gatekeeper.sh/v1alpha1 +metadata: + name: forbidden-sysctls +tests: + - name: forbidden-sysctls + template: template.yaml + constraint: samples/psp-forbidden-sysctls/constraint.yaml + cases: + - name: example-disallowed + object: samples/psp-forbidden-sysctls/example_disallowed.yaml + assertions: + - violations: yes + - name: example-allowed + object: samples/psp-forbidden-sysctls/example_allowed.yaml + assertions: + - violations: no + - name: update + object: samples/psp-forbidden-sysctls/update.yaml + assertions: + - violations: no + - name: forbidden-sysctls2 + template: template.yaml + constraint: samples/psp-forbidden-sysctls/constraint2.yaml + cases: + - name: example-disallowed + object: samples/psp-forbidden-sysctls/example_disallowed.yaml + assertions: + - violations: yes + - name: example-allowed + object: samples/psp-forbidden-sysctls/example_allowed.yaml + assertions: + - violations: yes + - name: update + object: samples/psp-forbidden-sysctls/update.yaml + assertions: + - violations: no + - name: forbidden-sysctls3 + template: template.yaml + constraint: samples/psp-forbidden-sysctls/constraint3.yaml + cases: + - name: example-disallowed + object: samples/psp-forbidden-sysctls/example_disallowed.yaml + assertions: + - violations: yes + - name: example-allowed + object: samples/psp-forbidden-sysctls/example_allowed.yaml + assertions: + - violations: no + - name: update + object: samples/psp-forbidden-sysctls/update.yaml + assertions: + - violations: no diff --git a/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/template.yaml b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/template.yaml new file mode 100644 index 000000000..db4ea623a --- /dev/null +++ b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/template.yaml @@ -0,0 +1,135 @@ +apiVersion: templates.gatekeeper.sh/v1 +kind: ConstraintTemplate +metadata: + name: k8spspforbiddensysctls + annotations: + metadata.gatekeeper.sh/title: "Forbidden Sysctls" + metadata.gatekeeper.sh/version: 1.2.0 + description: >- + Controls the `sysctl` profile used by containers. Corresponds to the + `allowedUnsafeSysctls` and `forbiddenSysctls` fields in a PodSecurityPolicy. + When specified, any sysctl not in the `allowedSysctls` parameter is considered to be forbidden. + The `forbiddenSysctls` parameter takes precedence over the `allowedSysctls` parameter. + For more information, see https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/ +spec: + crd: + spec: + names: + kind: K8sPSPForbiddenSysctls + validation: + # Schema for the `parameters` field + openAPIV3Schema: + type: object + description: >- + Controls the `sysctl` profile used by containers. Corresponds to the + `allowedUnsafeSysctls` and `forbiddenSysctls` fields in a PodSecurityPolicy. + When specified, any sysctl not in the `allowedSysctls` parameter is considered to be forbidden. + The `forbiddenSysctls` parameter takes precedence over the `allowedSysctls` parameter. + For more information, see https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/ + properties: + allowedSysctls: + type: array + description: "An allow-list of sysctls. `*` allows all sysctls not listed in the `forbiddenSysctls` parameter." + items: + type: string + forbiddenSysctls: + type: array + description: "A disallow-list of sysctls. `*` forbids all sysctls." + items: + type: string + targets: + - target: admission.k8s.gatekeeper.sh + code: + - engine: K8sNativeValidation + source: + variables: + - name: sysctls + expression: '!has(variables.anyObject.spec.securityContext) ? [] : !has(variables.anyObject.spec.securityContext.sysctls) ? [] : variables.anyObject.spec.securityContext.sysctls' + - name: allowedSysctlPrefixes + expression: | + !has(variables.params.allowedSysctls) ? [] : variables.params.allowedSysctls.filter(sysctl, sysctl.endsWith("*")).map(sysctl, string(sysctl).replace("*", "")) + - name: allowedSysctlExplicit + expression: | + !has(variables.params.allowedSysctls) ? [] : + variables.params.allowedSysctls.filter(sysctl, !sysctl.endsWith("*")) + - name: forbiddenSysctlPrefixes + expression: | + !has(variables.params.forbiddenSysctls) ? [] : variables.params.forbiddenSysctls.filter(sysctl, sysctl.endsWith("*")).map(sysctl, string(sysctl).replace("*", "")) + - name: forbiddenSysctlExplicit + expression: | + !has(variables.params.forbiddenSysctls) ? [] : + variables.params.forbiddenSysctls.filter(sysctl, !sysctl.endsWith("*")) + - name: allAllowed + expression: '!has(variables.params.allowedSysctls) ? true : false' + - name: violatingSysctls + expression: | + (variables.sysctls.filter(sysctl, + (sysctl.name in variables.forbiddenSysctlExplicit || + variables.forbiddenSysctlPrefixes.exists(fsp, string(sysctl.name).startsWith(fsp))) || + (!variables.allAllowed && + !(sysctl.name in variables.allowedSysctlExplicit) && + !variables.allowedSysctlPrefixes.exists(asp, string(sysctl.name).startsWith(asp))))) + validations: + - expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.violatingSysctls) == 0' + messageExpression: '"The sysctl is not allowed for pod: " + variables.anyObject.metadata.name + ", forbidden: " + variables.forbiddenSysctls.map(c, c).join(", ") + ", allowed: " + variables.allowedSysctls.map(c, c).join(", ")' + - engine: Rego + source: + rego: | + package k8spspforbiddensysctls + + import data.lib.exclude_update.is_update + + # Block if forbidden + violation[{"msg": msg, "details": {}}] { + # spec.securityContext.sysctls field is immutable. + not is_update(input.review) + + sysctl := input.review.object.spec.securityContext.sysctls[_].name + forbidden_sysctl(sysctl) + msg := sprintf("The sysctl %v is not allowed, pod: %v. Forbidden sysctls: %v", [sysctl, input.review.object.metadata.name, input.parameters.forbiddenSysctls]) + } + + # Block if not explicitly allowed + violation[{"msg": msg, "details": {}}] { + not is_update(input.review) + sysctl := input.review.object.spec.securityContext.sysctls[_].name + not allowed_sysctl(sysctl) + msg := sprintf("The sysctl %v is not explicitly allowed, pod: %v. Allowed sysctls: %v", [sysctl, input.review.object.metadata.name, input.parameters.allowedSysctls]) + } + + # * may be used to forbid all sysctls + forbidden_sysctl(_) { + input.parameters.forbiddenSysctls[_] == "*" + } + + forbidden_sysctl(sysctl) { + input.parameters.forbiddenSysctls[_] == sysctl + } + + forbidden_sysctl(sysctl) { + forbidden := input.parameters.forbiddenSysctls[_] + endswith(forbidden, "*") + startswith(sysctl, trim_suffix(forbidden, "*")) + } + + # * may be used to allow all sysctls + allowed_sysctl(_) { + input.parameters.allowedSysctls[_] == "*" + } + + allowed_sysctl(sysctl) { + input.parameters.allowedSysctls[_] == sysctl + } + + allowed_sysctl(sysctl) { + allowed := input.parameters.allowedSysctls[_] + endswith(allowed, "*") + startswith(sysctl, trim_suffix(allowed, "*")) + } + libs: + - | + package lib.exclude_update + + is_update(review) { + review.operation == "UPDATE" + } diff --git a/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/constraint2.yaml b/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/constraint2.yaml new file mode 100644 index 000000000..4306dff41 --- /dev/null +++ b/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/constraint2.yaml @@ -0,0 +1,14 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sPSPForbiddenSysctls +metadata: + name: psp-forbidden-sysctls +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] + parameters: + forbiddenSysctls: + - "*" # * forbid all sysctls + allowedSysctls: + - "*" # allows all sysctls. allowedSysctls is optional. diff --git a/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/constraint3.yaml b/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/constraint3.yaml new file mode 100644 index 000000000..24f0d3905 --- /dev/null +++ b/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/constraint3.yaml @@ -0,0 +1,15 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sPSPForbiddenSysctls +metadata: + name: psp-forbidden-sysctls +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] + parameters: + forbiddenSysctls: + # - "*" # * may be used to forbid all sysctls + - kernel.* + allowedSysctls: + - "net.*" # allows all sysctls. allowedSysctls is optional. diff --git a/library/pod-security-policy/forbidden-sysctls/suite.yaml b/library/pod-security-policy/forbidden-sysctls/suite.yaml index d00f85b8b..fe394ddd8 100644 --- a/library/pod-security-policy/forbidden-sysctls/suite.yaml +++ b/library/pod-security-policy/forbidden-sysctls/suite.yaml @@ -19,3 +19,35 @@ tests: object: samples/psp-forbidden-sysctls/update.yaml assertions: - violations: no + - name: forbidden-sysctls2 + template: template.yaml + constraint: samples/psp-forbidden-sysctls/constraint2.yaml + cases: + - name: example-disallowed + object: samples/psp-forbidden-sysctls/example_disallowed.yaml + assertions: + - violations: yes + - name: example-allowed + object: samples/psp-forbidden-sysctls/example_allowed.yaml + assertions: + - violations: yes + - name: update + object: samples/psp-forbidden-sysctls/update.yaml + assertions: + - violations: no + - name: forbidden-sysctls3 + template: template.yaml + constraint: samples/psp-forbidden-sysctls/constraint3.yaml + cases: + - name: example-disallowed + object: samples/psp-forbidden-sysctls/example_disallowed.yaml + assertions: + - violations: yes + - name: example-allowed + object: samples/psp-forbidden-sysctls/example_allowed.yaml + assertions: + - violations: no + - name: update + object: samples/psp-forbidden-sysctls/update.yaml + assertions: + - violations: no diff --git a/library/pod-security-policy/forbidden-sysctls/template.yaml b/library/pod-security-policy/forbidden-sysctls/template.yaml index 053c0eae5..db4ea623a 100644 --- a/library/pod-security-policy/forbidden-sysctls/template.yaml +++ b/library/pod-security-policy/forbidden-sysctls/template.yaml @@ -4,7 +4,7 @@ metadata: name: k8spspforbiddensysctls annotations: metadata.gatekeeper.sh/title: "Forbidden Sysctls" - metadata.gatekeeper.sh/version: 1.1.3 + metadata.gatekeeper.sh/version: 1.2.0 description: >- Controls the `sysctl` profile used by containers. Corresponds to the `allowedUnsafeSysctls` and `forbiddenSysctls` fields in a PodSecurityPolicy. @@ -39,62 +39,97 @@ spec: type: string targets: - target: admission.k8s.gatekeeper.sh - rego: | - package k8spspforbiddensysctls + code: + - engine: K8sNativeValidation + source: + variables: + - name: sysctls + expression: '!has(variables.anyObject.spec.securityContext) ? [] : !has(variables.anyObject.spec.securityContext.sysctls) ? [] : variables.anyObject.spec.securityContext.sysctls' + - name: allowedSysctlPrefixes + expression: | + !has(variables.params.allowedSysctls) ? [] : variables.params.allowedSysctls.filter(sysctl, sysctl.endsWith("*")).map(sysctl, string(sysctl).replace("*", "")) + - name: allowedSysctlExplicit + expression: | + !has(variables.params.allowedSysctls) ? [] : + variables.params.allowedSysctls.filter(sysctl, !sysctl.endsWith("*")) + - name: forbiddenSysctlPrefixes + expression: | + !has(variables.params.forbiddenSysctls) ? [] : variables.params.forbiddenSysctls.filter(sysctl, sysctl.endsWith("*")).map(sysctl, string(sysctl).replace("*", "")) + - name: forbiddenSysctlExplicit + expression: | + !has(variables.params.forbiddenSysctls) ? [] : + variables.params.forbiddenSysctls.filter(sysctl, !sysctl.endsWith("*")) + - name: allAllowed + expression: '!has(variables.params.allowedSysctls) ? true : false' + - name: violatingSysctls + expression: | + (variables.sysctls.filter(sysctl, + (sysctl.name in variables.forbiddenSysctlExplicit || + variables.forbiddenSysctlPrefixes.exists(fsp, string(sysctl.name).startsWith(fsp))) || + (!variables.allAllowed && + !(sysctl.name in variables.allowedSysctlExplicit) && + !variables.allowedSysctlPrefixes.exists(asp, string(sysctl.name).startsWith(asp))))) + validations: + - expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.violatingSysctls) == 0' + messageExpression: '"The sysctl is not allowed for pod: " + variables.anyObject.metadata.name + ", forbidden: " + variables.forbiddenSysctls.map(c, c).join(", ") + ", allowed: " + variables.allowedSysctls.map(c, c).join(", ")' + - engine: Rego + source: + rego: | + package k8spspforbiddensysctls - import data.lib.exclude_update.is_update + import data.lib.exclude_update.is_update - # Block if forbidden - violation[{"msg": msg, "details": {}}] { - # spec.securityContext.sysctls field is immutable. - not is_update(input.review) + # Block if forbidden + violation[{"msg": msg, "details": {}}] { + # spec.securityContext.sysctls field is immutable. + not is_update(input.review) - sysctl := input.review.object.spec.securityContext.sysctls[_].name - forbidden_sysctl(sysctl) - msg := sprintf("The sysctl %v is not allowed, pod: %v. Forbidden sysctls: %v", [sysctl, input.review.object.metadata.name, input.parameters.forbiddenSysctls]) - } + sysctl := input.review.object.spec.securityContext.sysctls[_].name + forbidden_sysctl(sysctl) + msg := sprintf("The sysctl %v is not allowed, pod: %v. Forbidden sysctls: %v", [sysctl, input.review.object.metadata.name, input.parameters.forbiddenSysctls]) + } - # Block if not explicitly allowed - violation[{"msg": msg, "details": {}}] { - not is_update(input.review) - sysctl := input.review.object.spec.securityContext.sysctls[_].name - not allowed_sysctl(sysctl) - msg := sprintf("The sysctl %v is not explicitly allowed, pod: %v. Allowed sysctls: %v", [sysctl, input.review.object.metadata.name, input.parameters.allowedSysctls]) - } + # Block if not explicitly allowed + violation[{"msg": msg, "details": {}}] { + not is_update(input.review) + sysctl := input.review.object.spec.securityContext.sysctls[_].name + not allowed_sysctl(sysctl) + msg := sprintf("The sysctl %v is not explicitly allowed, pod: %v. Allowed sysctls: %v", [sysctl, input.review.object.metadata.name, input.parameters.allowedSysctls]) + } - # * may be used to forbid all sysctls - forbidden_sysctl(_) { - input.parameters.forbiddenSysctls[_] == "*" - } + # * may be used to forbid all sysctls + forbidden_sysctl(_) { + input.parameters.forbiddenSysctls[_] == "*" + } - forbidden_sysctl(sysctl) { - input.parameters.forbiddenSysctls[_] == sysctl - } + forbidden_sysctl(sysctl) { + input.parameters.forbiddenSysctls[_] == sysctl + } - forbidden_sysctl(sysctl) { - forbidden := input.parameters.forbiddenSysctls[_] - endswith(forbidden, "*") - startswith(sysctl, trim_suffix(forbidden, "*")) - } + forbidden_sysctl(sysctl) { + forbidden := input.parameters.forbiddenSysctls[_] + endswith(forbidden, "*") + startswith(sysctl, trim_suffix(forbidden, "*")) + } - # * may be used to allow all sysctls - allowed_sysctl(_) { - input.parameters.allowedSysctls[_] == "*" - } + # * may be used to allow all sysctls + allowed_sysctl(_) { + input.parameters.allowedSysctls[_] == "*" + } - allowed_sysctl(sysctl) { - input.parameters.allowedSysctls[_] == sysctl - } + allowed_sysctl(sysctl) { + input.parameters.allowedSysctls[_] == sysctl + } - allowed_sysctl(sysctl) { - allowed := input.parameters.allowedSysctls[_] - endswith(allowed, "*") - startswith(sysctl, trim_suffix(allowed, "*")) - } - libs: - - | - package lib.exclude_update + allowed_sysctl(sysctl) { + allowed := input.parameters.allowedSysctls[_] + endswith(allowed, "*") + startswith(sysctl, trim_suffix(allowed, "*")) + } + libs: + - | + package lib.exclude_update - is_update(review) { - review.operation == "UPDATE" - } + is_update(review) { + review.operation == "UPDATE" + } diff --git a/src/pod-security-policy/forbidden-sysctls/constraint.tmpl b/src/pod-security-policy/forbidden-sysctls/constraint.tmpl index 87e4d23a9..28444f130 100644 --- a/src/pod-security-policy/forbidden-sysctls/constraint.tmpl +++ b/src/pod-security-policy/forbidden-sysctls/constraint.tmpl @@ -4,7 +4,7 @@ metadata: name: k8spspforbiddensysctls annotations: metadata.gatekeeper.sh/title: "Forbidden Sysctls" - metadata.gatekeeper.sh/version: 1.1.3 + metadata.gatekeeper.sh/version: 1.2.0 description: >- Controls the `sysctl` profile used by containers. Corresponds to the `allowedUnsafeSysctls` and `forbiddenSysctls` fields in a PodSecurityPolicy. @@ -39,8 +39,14 @@ spec: type: string targets: - target: admission.k8s.gatekeeper.sh - rego: | -{{ file.Read "src/pod-security-policy/forbidden-sysctls/src.rego" | strings.Indent 8 | strings.TrimSuffix "\n" }} - libs: - - | -{{ file.Read "src/pod-security-policy/forbidden-sysctls/lib_exclude_update.rego" | strings.Indent 10 | strings.TrimSuffix "\n" }} + code: + - engine: K8sNativeValidation + source: +{{ file.Read "src/pod-security-policy/forbidden-sysctls/src.cel" | strings.Indent 10 | strings.TrimSuffix "\n" }} + - engine: Rego + source: + rego: | +{{ file.Read "src/pod-security-policy/forbidden-sysctls/src.rego" | strings.Indent 12 | strings.TrimSuffix "\n" }} + libs: + - | +{{ file.Read "src/pod-security-policy/forbidden-sysctls/lib_exclude_update.rego" | strings.Indent 14 | strings.TrimSuffix "\n" }} diff --git a/src/pod-security-policy/forbidden-sysctls/src.cel b/src/pod-security-policy/forbidden-sysctls/src.cel new file mode 100644 index 000000000..17f2a52fc --- /dev/null +++ b/src/pod-security-policy/forbidden-sysctls/src.cel @@ -0,0 +1,30 @@ +variables: +- name: sysctls + expression: '!has(variables.anyObject.spec.securityContext) ? [] : !has(variables.anyObject.spec.securityContext.sysctls) ? [] : variables.anyObject.spec.securityContext.sysctls' +- name: allowedSysctlPrefixes + expression: | + !has(variables.params.allowedSysctls) ? [] : variables.params.allowedSysctls.filter(sysctl, sysctl.endsWith("*")).map(sysctl, string(sysctl).replace("*", "")) +- name: allowedSysctlExplicit + expression: | + !has(variables.params.allowedSysctls) ? [] : + variables.params.allowedSysctls.filter(sysctl, !sysctl.endsWith("*")) +- name: forbiddenSysctlPrefixes + expression: | + !has(variables.params.forbiddenSysctls) ? [] : variables.params.forbiddenSysctls.filter(sysctl, sysctl.endsWith("*")).map(sysctl, string(sysctl).replace("*", "")) +- name: forbiddenSysctlExplicit + expression: | + !has(variables.params.forbiddenSysctls) ? [] : + variables.params.forbiddenSysctls.filter(sysctl, !sysctl.endsWith("*")) +- name: allAllowed + expression: '!has(variables.params.allowedSysctls) ? true : false' +- name: violatingSysctls + expression: | + (variables.sysctls.filter(sysctl, + (sysctl.name in variables.forbiddenSysctlExplicit || + variables.forbiddenSysctlPrefixes.exists(fsp, string(sysctl.name).startsWith(fsp))) || + (!variables.allAllowed && + !(sysctl.name in variables.allowedSysctlExplicit) && + !variables.allowedSysctlPrefixes.exists(asp, string(sysctl.name).startsWith(asp))))) +validations: +- expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.violatingSysctls) == 0' + messageExpression: '"The sysctl is not allowed for pod: " + variables.anyObject.metadata.name + ", forbidden: " + variables.forbiddenSysctls.map(c, c).join(", ") + ", allowed: " + variables.allowedSysctls.map(c, c).join(", ")' diff --git a/website/docs/validation/forbidden-sysctls.md b/website/docs/validation/forbidden-sysctls.md index 279b406a8..63ef43610 100644 --- a/website/docs/validation/forbidden-sysctls.md +++ b/website/docs/validation/forbidden-sysctls.md @@ -16,7 +16,7 @@ metadata: name: k8spspforbiddensysctls annotations: metadata.gatekeeper.sh/title: "Forbidden Sysctls" - metadata.gatekeeper.sh/version: 1.1.3 + metadata.gatekeeper.sh/version: 1.2.0 description: >- Controls the `sysctl` profile used by containers. Corresponds to the `allowedUnsafeSysctls` and `forbiddenSysctls` fields in a PodSecurityPolicy. @@ -51,65 +51,100 @@ spec: type: string targets: - target: admission.k8s.gatekeeper.sh - rego: | - package k8spspforbiddensysctls - - import data.lib.exclude_update.is_update - - # Block if forbidden - violation[{"msg": msg, "details": {}}] { - # spec.securityContext.sysctls field is immutable. - not is_update(input.review) - - sysctl := input.review.object.spec.securityContext.sysctls[_].name - forbidden_sysctl(sysctl) - msg := sprintf("The sysctl %v is not allowed, pod: %v. Forbidden sysctls: %v", [sysctl, input.review.object.metadata.name, input.parameters.forbiddenSysctls]) - } - - # Block if not explicitly allowed - violation[{"msg": msg, "details": {}}] { - not is_update(input.review) - sysctl := input.review.object.spec.securityContext.sysctls[_].name - not allowed_sysctl(sysctl) - msg := sprintf("The sysctl %v is not explicitly allowed, pod: %v. Allowed sysctls: %v", [sysctl, input.review.object.metadata.name, input.parameters.allowedSysctls]) - } - - # * may be used to forbid all sysctls - forbidden_sysctl(_) { - input.parameters.forbiddenSysctls[_] == "*" - } - - forbidden_sysctl(sysctl) { - input.parameters.forbiddenSysctls[_] == sysctl - } - - forbidden_sysctl(sysctl) { - forbidden := input.parameters.forbiddenSysctls[_] - endswith(forbidden, "*") - startswith(sysctl, trim_suffix(forbidden, "*")) - } - - # * may be used to allow all sysctls - allowed_sysctl(_) { - input.parameters.allowedSysctls[_] == "*" - } - - allowed_sysctl(sysctl) { - input.parameters.allowedSysctls[_] == sysctl - } - - allowed_sysctl(sysctl) { - allowed := input.parameters.allowedSysctls[_] - endswith(allowed, "*") - startswith(sysctl, trim_suffix(allowed, "*")) - } - libs: - - | - package lib.exclude_update - - is_update(review) { - review.operation == "UPDATE" - } + code: + - engine: K8sNativeValidation + source: + variables: + - name: sysctls + expression: '!has(variables.anyObject.spec.securityContext) ? [] : !has(variables.anyObject.spec.securityContext.sysctls) ? [] : variables.anyObject.spec.securityContext.sysctls' + - name: allowedSysctlPrefixes + expression: | + !has(variables.params.allowedSysctls) ? [] : variables.params.allowedSysctls.filter(sysctl, sysctl.endsWith("*")).map(sysctl, string(sysctl).replace("*", "")) + - name: allowedSysctlExplicit + expression: | + !has(variables.params.allowedSysctls) ? [] : + variables.params.allowedSysctls.filter(sysctl, !sysctl.endsWith("*")) + - name: forbiddenSysctlPrefixes + expression: | + !has(variables.params.forbiddenSysctls) ? [] : variables.params.forbiddenSysctls.filter(sysctl, sysctl.endsWith("*")).map(sysctl, string(sysctl).replace("*", "")) + - name: forbiddenSysctlExplicit + expression: | + !has(variables.params.forbiddenSysctls) ? [] : + variables.params.forbiddenSysctls.filter(sysctl, !sysctl.endsWith("*")) + - name: allAllowed + expression: '!has(variables.params.allowedSysctls) ? true : false' + - name: violatingSysctls + expression: | + (variables.sysctls.filter(sysctl, + (sysctl.name in variables.forbiddenSysctlExplicit || + variables.forbiddenSysctlPrefixes.exists(fsp, string(sysctl.name).startsWith(fsp))) || + (!variables.allAllowed && + !(sysctl.name in variables.allowedSysctlExplicit) && + !variables.allowedSysctlPrefixes.exists(asp, string(sysctl.name).startsWith(asp))))) + validations: + - expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.violatingSysctls) == 0' + messageExpression: '"The sysctl is not allowed for pod: " + variables.anyObject.metadata.name + ", forbidden: " + variables.forbiddenSysctls.map(c, c).join(", ") + ", allowed: " + variables.allowedSysctls.map(c, c).join(", ")' + - engine: Rego + source: + rego: | + package k8spspforbiddensysctls + + import data.lib.exclude_update.is_update + + # Block if forbidden + violation[{"msg": msg, "details": {}}] { + # spec.securityContext.sysctls field is immutable. + not is_update(input.review) + + sysctl := input.review.object.spec.securityContext.sysctls[_].name + forbidden_sysctl(sysctl) + msg := sprintf("The sysctl %v is not allowed, pod: %v. Forbidden sysctls: %v", [sysctl, input.review.object.metadata.name, input.parameters.forbiddenSysctls]) + } + + # Block if not explicitly allowed + violation[{"msg": msg, "details": {}}] { + not is_update(input.review) + sysctl := input.review.object.spec.securityContext.sysctls[_].name + not allowed_sysctl(sysctl) + msg := sprintf("The sysctl %v is not explicitly allowed, pod: %v. Allowed sysctls: %v", [sysctl, input.review.object.metadata.name, input.parameters.allowedSysctls]) + } + + # * may be used to forbid all sysctls + forbidden_sysctl(_) { + input.parameters.forbiddenSysctls[_] == "*" + } + + forbidden_sysctl(sysctl) { + input.parameters.forbiddenSysctls[_] == sysctl + } + + forbidden_sysctl(sysctl) { + forbidden := input.parameters.forbiddenSysctls[_] + endswith(forbidden, "*") + startswith(sysctl, trim_suffix(forbidden, "*")) + } + + # * may be used to allow all sysctls + allowed_sysctl(_) { + input.parameters.allowedSysctls[_] == "*" + } + + allowed_sysctl(sysctl) { + input.parameters.allowedSysctls[_] == sysctl + } + + allowed_sysctl(sysctl) { + allowed := input.parameters.allowedSysctls[_] + endswith(allowed, "*") + startswith(sysctl, trim_suffix(allowed, "*")) + } + libs: + - | + package lib.exclude_update + + is_update(review) { + review.operation == "UPDATE" + } ``` @@ -211,4 +246,189 @@ kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper- +
+forbidden-sysctls2 + +
+constraint + +```yaml +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sPSPForbiddenSysctls +metadata: + name: psp-forbidden-sysctls +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] + parameters: + forbiddenSysctls: + - "*" # * forbid all sysctls + allowedSysctls: + - "*" # allows all sysctls. allowedSysctls is optional. + +``` + +Usage + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/constraint2.yaml +``` + +
+ +
+example-disallowed + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: nginx-forbidden-sysctls-disallowed + labels: + app: nginx-forbidden-sysctls +spec: + containers: + - name: nginx + image: nginx + securityContext: + sysctls: + - name: kernel.msgmax + value: "65536" + - name: net.core.somaxconn + value: "1024" + +``` + +Usage + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/example_disallowed.yaml +``` + +
+
+example-allowed + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: nginx-forbidden-sysctls-disallowed + labels: + app: nginx-forbidden-sysctls +spec: + containers: + - name: nginx + image: nginx + securityContext: + sysctls: + - name: net.core.somaxconn + value: "1024" + +``` + +Usage + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/example_allowed.yaml +``` + +
+ + +
+forbidden-sysctls3 + +
+constraint + +```yaml +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sPSPForbiddenSysctls +metadata: + name: psp-forbidden-sysctls +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] + parameters: + forbiddenSysctls: + # - "*" # * may be used to forbid all sysctls + - kernel.* + allowedSysctls: + - "net.*" # allows all sysctls. allowedSysctls is optional. + +``` + +Usage + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/constraint3.yaml +``` + +
+ +
+example-disallowed + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: nginx-forbidden-sysctls-disallowed + labels: + app: nginx-forbidden-sysctls +spec: + containers: + - name: nginx + image: nginx + securityContext: + sysctls: + - name: kernel.msgmax + value: "65536" + - name: net.core.somaxconn + value: "1024" + +``` + +Usage + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/example_disallowed.yaml +``` + +
+
+example-allowed + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: nginx-forbidden-sysctls-disallowed + labels: + app: nginx-forbidden-sysctls +spec: + containers: + - name: nginx + image: nginx + securityContext: + sysctls: + - name: net.core.somaxconn + value: "1024" + +``` + +Usage + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/example_allowed.yaml +``` + +
+ +
\ No newline at end of file From 9ac982be5a0c9dee6948f0da89b970c44a664272 Mon Sep 17 00:00:00 2001 From: Rita Zhang Date: Wed, 11 Sep 2024 13:58:26 -0700 Subject: [PATCH 2/3] add tests and update messageExpression Signed-off-by: Rita Zhang --- .../1.2.0/artifacthub-pkg.yml | 2 +- .../psp-forbidden-sysctls/constraint3.yaml | 2 +- .../psp-forbidden-sysctls/constraint4.yaml | 14 ++ .../psp-forbidden-sysctls/constraint5.yaml | 14 ++ .../forbidden-sysctls/1.2.0/suite.yaml | 36 +++- .../forbidden-sysctls/1.2.0/template.yaml | 13 +- .../psp-forbidden-sysctls/constraint3.yaml | 2 +- .../psp-forbidden-sysctls/constraint4.yaml | 14 ++ .../psp-forbidden-sysctls/constraint5.yaml | 14 ++ .../forbidden-sysctls/suite.yaml | 36 +++- .../forbidden-sysctls/template.yaml | 13 +- .../forbidden-sysctls/src.cel | 13 +- website/docs/validation/forbidden-sysctls.md | 203 +++++++++++++++++- 13 files changed, 346 insertions(+), 30 deletions(-) create mode 100644 artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/constraint4.yaml create mode 100644 artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/constraint5.yaml create mode 100644 library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/constraint4.yaml create mode 100644 library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/constraint5.yaml diff --git a/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/artifacthub-pkg.yml b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/artifacthub-pkg.yml index aae5e46c3..70229c760 100644 --- a/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/artifacthub-pkg.yml +++ b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/artifacthub-pkg.yml @@ -3,7 +3,7 @@ name: k8spspforbiddensysctls displayName: Forbidden Sysctls createdAt: "2024-07-05T17:47:31Z" description: Controls the `sysctl` profile used by containers. Corresponds to the `allowedUnsafeSysctls` and `forbiddenSysctls` fields in a PodSecurityPolicy. When specified, any sysctl not in the `allowedSysctls` parameter is considered to be forbidden. The `forbiddenSysctls` parameter takes precedence over the `allowedSysctls` parameter. For more information, see https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/ -digest: c34167b32bcd5b55b48a68614ad4b20cd26294d17be559738f01735ab719f621 +digest: 6e64cb0e325f6894b153216cc2f1b30f2ea4de6d62dced4f7b59209207394ce3 license: Apache-2.0 homeURL: https://open-policy-agent.github.io/gatekeeper-library/website/forbidden-sysctls keywords: diff --git a/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/constraint3.yaml b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/constraint3.yaml index 24f0d3905..87c4e405a 100644 --- a/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/constraint3.yaml +++ b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/constraint3.yaml @@ -12,4 +12,4 @@ spec: # - "*" # * may be used to forbid all sysctls - kernel.* allowedSysctls: - - "net.*" # allows all sysctls. allowedSysctls is optional. + - "net.*" diff --git a/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/constraint4.yaml b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/constraint4.yaml new file mode 100644 index 000000000..2a9c0dcb5 --- /dev/null +++ b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/constraint4.yaml @@ -0,0 +1,14 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sPSPForbiddenSysctls +metadata: + name: psp-forbidden-sysctls +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] + parameters: + forbiddenSysctls: + # - "*" # * may be used to forbid all sysctls + - kernel.* + allowedSysctls: [] # empty allowedSysctls means all sysctls are forbidden diff --git a/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/constraint5.yaml b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/constraint5.yaml new file mode 100644 index 000000000..13e8677d8 --- /dev/null +++ b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/constraint5.yaml @@ -0,0 +1,14 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sPSPForbiddenSysctls +metadata: + name: psp-forbidden-sysctls +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] + parameters: + forbiddenSysctls: + # - "*" # * may be used to forbid all sysctls + - kernel.* + # unspecified allowedSysctls will not place any restrictions diff --git a/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/suite.yaml b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/suite.yaml index fe394ddd8..7ed8a1d02 100644 --- a/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/suite.yaml +++ b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/suite.yaml @@ -19,7 +19,7 @@ tests: object: samples/psp-forbidden-sysctls/update.yaml assertions: - violations: no - - name: forbidden-sysctls2 + - name: forbidden-sysctls-wildcard template: template.yaml constraint: samples/psp-forbidden-sysctls/constraint2.yaml cases: @@ -27,7 +27,7 @@ tests: object: samples/psp-forbidden-sysctls/example_disallowed.yaml assertions: - violations: yes - - name: example-allowed + - name: example-disallowed object: samples/psp-forbidden-sysctls/example_allowed.yaml assertions: - violations: yes @@ -51,3 +51,35 @@ tests: object: samples/psp-forbidden-sysctls/update.yaml assertions: - violations: no + - name: forbidden-sysctls4-empty-allowedSysctls + template: template.yaml + constraint: samples/psp-forbidden-sysctls/constraint4.yaml + cases: + - name: example-disallowed + object: samples/psp-forbidden-sysctls/example_disallowed.yaml + assertions: + - violations: yes + - name: example-disallowed + object: samples/psp-forbidden-sysctls/example_allowed.yaml + assertions: + - violations: yes + - name: update + object: samples/psp-forbidden-sysctls/update.yaml + assertions: + - violations: no + - name: forbidden-sysctls5-unspecified-allowedSysctls + template: template.yaml + constraint: samples/psp-forbidden-sysctls/constraint5.yaml + cases: + - name: example-disallowed + object: samples/psp-forbidden-sysctls/example_disallowed.yaml + assertions: + - violations: yes + - name: example-allowed + object: samples/psp-forbidden-sysctls/example_allowed.yaml + assertions: + - violations: no + - name: update + object: samples/psp-forbidden-sysctls/update.yaml + assertions: + - violations: no diff --git a/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/template.yaml b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/template.yaml index db4ea623a..6c9ea66bd 100644 --- a/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/template.yaml +++ b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/template.yaml @@ -43,6 +43,8 @@ spec: - engine: K8sNativeValidation source: variables: + - name: isUpdate + expression: has(request.operation) && request.operation == "UPDATE" - name: sysctls expression: '!has(variables.anyObject.spec.securityContext) ? [] : !has(variables.anyObject.spec.securityContext.sysctls) ? [] : variables.anyObject.spec.securityContext.sysctls' - name: allowedSysctlPrefixes @@ -59,19 +61,20 @@ spec: expression: | !has(variables.params.forbiddenSysctls) ? [] : variables.params.forbiddenSysctls.filter(sysctl, !sysctl.endsWith("*")) - - name: allAllowed - expression: '!has(variables.params.allowedSysctls) ? true : false' + - name: allowedSysctlsString + expression: | + !has(variables.params.allowedSysctls) ? "unspecified" : size(variables.params.allowedSysctls) == 0 ? "empty" : variables.params.allowedSysctls.join(", ") - name: violatingSysctls expression: | (variables.sysctls.filter(sysctl, (sysctl.name in variables.forbiddenSysctlExplicit || variables.forbiddenSysctlPrefixes.exists(fsp, string(sysctl.name).startsWith(fsp))) || - (!variables.allAllowed && + (has(variables.params.allowedSysctls) && !(sysctl.name in variables.allowedSysctlExplicit) && !variables.allowedSysctlPrefixes.exists(asp, string(sysctl.name).startsWith(asp))))) validations: - - expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.violatingSysctls) == 0' - messageExpression: '"The sysctl is not allowed for pod: " + variables.anyObject.metadata.name + ", forbidden: " + variables.forbiddenSysctls.map(c, c).join(", ") + ", allowed: " + variables.allowedSysctls.map(c, c).join(", ")' + - expression: 'variables.isUpdate || size(variables.violatingSysctls) == 0' + messageExpression: '"The sysctl is not allowed for pod: " + variables.anyObject.metadata.name + ", forbidden: " + variables.params.forbiddenSysctls.join(", ") + ", allowed: " + variables.allowedSysctlsString' - engine: Rego source: rego: | diff --git a/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/constraint3.yaml b/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/constraint3.yaml index 24f0d3905..87c4e405a 100644 --- a/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/constraint3.yaml +++ b/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/constraint3.yaml @@ -12,4 +12,4 @@ spec: # - "*" # * may be used to forbid all sysctls - kernel.* allowedSysctls: - - "net.*" # allows all sysctls. allowedSysctls is optional. + - "net.*" diff --git a/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/constraint4.yaml b/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/constraint4.yaml new file mode 100644 index 000000000..2a9c0dcb5 --- /dev/null +++ b/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/constraint4.yaml @@ -0,0 +1,14 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sPSPForbiddenSysctls +metadata: + name: psp-forbidden-sysctls +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] + parameters: + forbiddenSysctls: + # - "*" # * may be used to forbid all sysctls + - kernel.* + allowedSysctls: [] # empty allowedSysctls means all sysctls are forbidden diff --git a/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/constraint5.yaml b/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/constraint5.yaml new file mode 100644 index 000000000..13e8677d8 --- /dev/null +++ b/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/constraint5.yaml @@ -0,0 +1,14 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sPSPForbiddenSysctls +metadata: + name: psp-forbidden-sysctls +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] + parameters: + forbiddenSysctls: + # - "*" # * may be used to forbid all sysctls + - kernel.* + # unspecified allowedSysctls will not place any restrictions diff --git a/library/pod-security-policy/forbidden-sysctls/suite.yaml b/library/pod-security-policy/forbidden-sysctls/suite.yaml index fe394ddd8..7ed8a1d02 100644 --- a/library/pod-security-policy/forbidden-sysctls/suite.yaml +++ b/library/pod-security-policy/forbidden-sysctls/suite.yaml @@ -19,7 +19,7 @@ tests: object: samples/psp-forbidden-sysctls/update.yaml assertions: - violations: no - - name: forbidden-sysctls2 + - name: forbidden-sysctls-wildcard template: template.yaml constraint: samples/psp-forbidden-sysctls/constraint2.yaml cases: @@ -27,7 +27,7 @@ tests: object: samples/psp-forbidden-sysctls/example_disallowed.yaml assertions: - violations: yes - - name: example-allowed + - name: example-disallowed object: samples/psp-forbidden-sysctls/example_allowed.yaml assertions: - violations: yes @@ -51,3 +51,35 @@ tests: object: samples/psp-forbidden-sysctls/update.yaml assertions: - violations: no + - name: forbidden-sysctls4-empty-allowedSysctls + template: template.yaml + constraint: samples/psp-forbidden-sysctls/constraint4.yaml + cases: + - name: example-disallowed + object: samples/psp-forbidden-sysctls/example_disallowed.yaml + assertions: + - violations: yes + - name: example-disallowed + object: samples/psp-forbidden-sysctls/example_allowed.yaml + assertions: + - violations: yes + - name: update + object: samples/psp-forbidden-sysctls/update.yaml + assertions: + - violations: no + - name: forbidden-sysctls5-unspecified-allowedSysctls + template: template.yaml + constraint: samples/psp-forbidden-sysctls/constraint5.yaml + cases: + - name: example-disallowed + object: samples/psp-forbidden-sysctls/example_disallowed.yaml + assertions: + - violations: yes + - name: example-allowed + object: samples/psp-forbidden-sysctls/example_allowed.yaml + assertions: + - violations: no + - name: update + object: samples/psp-forbidden-sysctls/update.yaml + assertions: + - violations: no diff --git a/library/pod-security-policy/forbidden-sysctls/template.yaml b/library/pod-security-policy/forbidden-sysctls/template.yaml index db4ea623a..6c9ea66bd 100644 --- a/library/pod-security-policy/forbidden-sysctls/template.yaml +++ b/library/pod-security-policy/forbidden-sysctls/template.yaml @@ -43,6 +43,8 @@ spec: - engine: K8sNativeValidation source: variables: + - name: isUpdate + expression: has(request.operation) && request.operation == "UPDATE" - name: sysctls expression: '!has(variables.anyObject.spec.securityContext) ? [] : !has(variables.anyObject.spec.securityContext.sysctls) ? [] : variables.anyObject.spec.securityContext.sysctls' - name: allowedSysctlPrefixes @@ -59,19 +61,20 @@ spec: expression: | !has(variables.params.forbiddenSysctls) ? [] : variables.params.forbiddenSysctls.filter(sysctl, !sysctl.endsWith("*")) - - name: allAllowed - expression: '!has(variables.params.allowedSysctls) ? true : false' + - name: allowedSysctlsString + expression: | + !has(variables.params.allowedSysctls) ? "unspecified" : size(variables.params.allowedSysctls) == 0 ? "empty" : variables.params.allowedSysctls.join(", ") - name: violatingSysctls expression: | (variables.sysctls.filter(sysctl, (sysctl.name in variables.forbiddenSysctlExplicit || variables.forbiddenSysctlPrefixes.exists(fsp, string(sysctl.name).startsWith(fsp))) || - (!variables.allAllowed && + (has(variables.params.allowedSysctls) && !(sysctl.name in variables.allowedSysctlExplicit) && !variables.allowedSysctlPrefixes.exists(asp, string(sysctl.name).startsWith(asp))))) validations: - - expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.violatingSysctls) == 0' - messageExpression: '"The sysctl is not allowed for pod: " + variables.anyObject.metadata.name + ", forbidden: " + variables.forbiddenSysctls.map(c, c).join(", ") + ", allowed: " + variables.allowedSysctls.map(c, c).join(", ")' + - expression: 'variables.isUpdate || size(variables.violatingSysctls) == 0' + messageExpression: '"The sysctl is not allowed for pod: " + variables.anyObject.metadata.name + ", forbidden: " + variables.params.forbiddenSysctls.join(", ") + ", allowed: " + variables.allowedSysctlsString' - engine: Rego source: rego: | diff --git a/src/pod-security-policy/forbidden-sysctls/src.cel b/src/pod-security-policy/forbidden-sysctls/src.cel index 17f2a52fc..d90e6253a 100644 --- a/src/pod-security-policy/forbidden-sysctls/src.cel +++ b/src/pod-security-policy/forbidden-sysctls/src.cel @@ -1,4 +1,6 @@ variables: +- name: isUpdate + expression: has(request.operation) && request.operation == "UPDATE" - name: sysctls expression: '!has(variables.anyObject.spec.securityContext) ? [] : !has(variables.anyObject.spec.securityContext.sysctls) ? [] : variables.anyObject.spec.securityContext.sysctls' - name: allowedSysctlPrefixes @@ -15,16 +17,17 @@ variables: expression: | !has(variables.params.forbiddenSysctls) ? [] : variables.params.forbiddenSysctls.filter(sysctl, !sysctl.endsWith("*")) -- name: allAllowed - expression: '!has(variables.params.allowedSysctls) ? true : false' +- name: allowedSysctlsString + expression: | + !has(variables.params.allowedSysctls) ? "unspecified" : size(variables.params.allowedSysctls) == 0 ? "empty" : variables.params.allowedSysctls.join(", ") - name: violatingSysctls expression: | (variables.sysctls.filter(sysctl, (sysctl.name in variables.forbiddenSysctlExplicit || variables.forbiddenSysctlPrefixes.exists(fsp, string(sysctl.name).startsWith(fsp))) || - (!variables.allAllowed && + (has(variables.params.allowedSysctls) && !(sysctl.name in variables.allowedSysctlExplicit) && !variables.allowedSysctlPrefixes.exists(asp, string(sysctl.name).startsWith(asp))))) validations: -- expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.violatingSysctls) == 0' - messageExpression: '"The sysctl is not allowed for pod: " + variables.anyObject.metadata.name + ", forbidden: " + variables.forbiddenSysctls.map(c, c).join(", ") + ", allowed: " + variables.allowedSysctls.map(c, c).join(", ")' +- expression: 'variables.isUpdate || size(variables.violatingSysctls) == 0' + messageExpression: '"The sysctl is not allowed for pod: " + variables.anyObject.metadata.name + ", forbidden: " + variables.params.forbiddenSysctls.join(", ") + ", allowed: " + variables.allowedSysctlsString' diff --git a/website/docs/validation/forbidden-sysctls.md b/website/docs/validation/forbidden-sysctls.md index 63ef43610..c85ad40d3 100644 --- a/website/docs/validation/forbidden-sysctls.md +++ b/website/docs/validation/forbidden-sysctls.md @@ -55,6 +55,8 @@ spec: - engine: K8sNativeValidation source: variables: + - name: isUpdate + expression: has(request.operation) && request.operation == "UPDATE" - name: sysctls expression: '!has(variables.anyObject.spec.securityContext) ? [] : !has(variables.anyObject.spec.securityContext.sysctls) ? [] : variables.anyObject.spec.securityContext.sysctls' - name: allowedSysctlPrefixes @@ -71,19 +73,20 @@ spec: expression: | !has(variables.params.forbiddenSysctls) ? [] : variables.params.forbiddenSysctls.filter(sysctl, !sysctl.endsWith("*")) - - name: allAllowed - expression: '!has(variables.params.allowedSysctls) ? true : false' + - name: allowedSysctlsString + expression: | + !has(variables.params.allowedSysctls) ? "unspecified" : size(variables.params.allowedSysctls) == 0 ? "empty" : variables.params.allowedSysctls.join(", ") - name: violatingSysctls expression: | (variables.sysctls.filter(sysctl, (sysctl.name in variables.forbiddenSysctlExplicit || variables.forbiddenSysctlPrefixes.exists(fsp, string(sysctl.name).startsWith(fsp))) || - (!variables.allAllowed && + (has(variables.params.allowedSysctls) && !(sysctl.name in variables.allowedSysctlExplicit) && !variables.allowedSysctlPrefixes.exists(asp, string(sysctl.name).startsWith(asp))))) validations: - - expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.violatingSysctls) == 0' - messageExpression: '"The sysctl is not allowed for pod: " + variables.anyObject.metadata.name + ", forbidden: " + variables.forbiddenSysctls.map(c, c).join(", ") + ", allowed: " + variables.allowedSysctls.map(c, c).join(", ")' + - expression: 'variables.isUpdate || size(variables.violatingSysctls) == 0' + messageExpression: '"The sysctl is not allowed for pod: " + variables.anyObject.metadata.name + ", forbidden: " + variables.params.forbiddenSysctls.join(", ") + ", allowed: " + variables.allowedSysctlsString' - engine: Rego source: rego: | @@ -247,7 +250,7 @@ kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-
-forbidden-sysctls2 +forbidden-sysctls-wildcard
constraint @@ -309,7 +312,7 @@ kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-
-example-allowed +example-disallowed ```yaml apiVersion: v1 @@ -359,7 +362,7 @@ spec: # - "*" # * may be used to forbid all sysctls - kernel.* allowedSysctls: - - "net.*" # allows all sysctls. allowedSysctls is optional. + - "net.*" ``` @@ -431,4 +434,188 @@ kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-
+
+forbidden-sysctls4-empty-allowedSysctls + +
+constraint + +```yaml +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sPSPForbiddenSysctls +metadata: + name: psp-forbidden-sysctls +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] + parameters: + forbiddenSysctls: + # - "*" # * may be used to forbid all sysctls + - kernel.* + allowedSysctls: [] # empty allowedSysctls means all sysctls are forbidden + +``` + +Usage + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/constraint4.yaml +``` + +
+ +
+example-disallowed + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: nginx-forbidden-sysctls-disallowed + labels: + app: nginx-forbidden-sysctls +spec: + containers: + - name: nginx + image: nginx + securityContext: + sysctls: + - name: kernel.msgmax + value: "65536" + - name: net.core.somaxconn + value: "1024" + +``` + +Usage + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/example_disallowed.yaml +``` + +
+
+example-disallowed + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: nginx-forbidden-sysctls-disallowed + labels: + app: nginx-forbidden-sysctls +spec: + containers: + - name: nginx + image: nginx + securityContext: + sysctls: + - name: net.core.somaxconn + value: "1024" + +``` + +Usage + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/example_allowed.yaml +``` + +
+ + +
+forbidden-sysctls5-unspecified-allowedSysctls + +
+constraint + +```yaml +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sPSPForbiddenSysctls +metadata: + name: psp-forbidden-sysctls +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] + parameters: + forbiddenSysctls: + # - "*" # * may be used to forbid all sysctls + - kernel.* + # unspecified allowedSysctls will not place any restrictions + +``` + +Usage + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/constraint5.yaml +``` + +
+ +
+example-disallowed + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: nginx-forbidden-sysctls-disallowed + labels: + app: nginx-forbidden-sysctls +spec: + containers: + - name: nginx + image: nginx + securityContext: + sysctls: + - name: kernel.msgmax + value: "65536" + - name: net.core.somaxconn + value: "1024" + +``` + +Usage + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/example_disallowed.yaml +``` + +
+
+example-allowed + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: nginx-forbidden-sysctls-disallowed + labels: + app: nginx-forbidden-sysctls +spec: + containers: + - name: nginx + image: nginx + securityContext: + sysctls: + - name: net.core.somaxconn + value: "1024" + +``` + +Usage + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/example_allowed.yaml +``` + +
+ +
\ No newline at end of file From 8f9a027ebf586e2d1c2d669f7347fa5d1264632e Mon Sep 17 00:00:00 2001 From: Rita Zhang Date: Fri, 13 Dec 2024 17:31:39 -0800 Subject: [PATCH 3/3] update rego for unspecified allowedSysctls Signed-off-by: Rita Zhang --- .../1.2.0/artifacthub-pkg.yml | 2 +- .../example_allowed.yaml | 2 +- .../forbidden-sysctls/1.2.0/template.yaml | 14 ++++++++++- .../example_allowed.yaml | 2 +- .../forbidden-sysctls/template.yaml | 14 ++++++++++- .../forbidden-sysctls/src.rego | 14 ++++++++++- website/docs/validation/forbidden-sysctls.md | 24 ++++++++++++++----- 7 files changed, 60 insertions(+), 12 deletions(-) diff --git a/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/artifacthub-pkg.yml b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/artifacthub-pkg.yml index 70229c760..6ecb28c2c 100644 --- a/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/artifacthub-pkg.yml +++ b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/artifacthub-pkg.yml @@ -3,7 +3,7 @@ name: k8spspforbiddensysctls displayName: Forbidden Sysctls createdAt: "2024-07-05T17:47:31Z" description: Controls the `sysctl` profile used by containers. Corresponds to the `allowedUnsafeSysctls` and `forbiddenSysctls` fields in a PodSecurityPolicy. When specified, any sysctl not in the `allowedSysctls` parameter is considered to be forbidden. The `forbiddenSysctls` parameter takes precedence over the `allowedSysctls` parameter. For more information, see https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/ -digest: 6e64cb0e325f6894b153216cc2f1b30f2ea4de6d62dced4f7b59209207394ce3 +digest: f17aa53b0129445cc5899d534c3c3904f8843c517cc401a13b5f07aaa6e0cca8 license: Apache-2.0 homeURL: https://open-policy-agent.github.io/gatekeeper-library/website/forbidden-sysctls keywords: diff --git a/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/example_allowed.yaml b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/example_allowed.yaml index 4b6cc4b66..5cb66a42c 100644 --- a/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/example_allowed.yaml +++ b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/samples/psp-forbidden-sysctls/example_allowed.yaml @@ -1,7 +1,7 @@ apiVersion: v1 kind: Pod metadata: - name: nginx-forbidden-sysctls-disallowed + name: nginx-forbidden-sysctls-allowed labels: app: nginx-forbidden-sysctls spec: diff --git a/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/template.yaml b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/template.yaml index 6c9ea66bd..3fc2bda73 100644 --- a/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/template.yaml +++ b/artifacthub/library/pod-security-policy/forbidden-sysctls/1.2.0/template.yaml @@ -97,7 +97,8 @@ spec: not is_update(input.review) sysctl := input.review.object.spec.securityContext.sysctls[_].name not allowed_sysctl(sysctl) - msg := sprintf("The sysctl %v is not explicitly allowed, pod: %v. Allowed sysctls: %v", [sysctl, input.review.object.metadata.name, input.parameters.allowedSysctls]) + allowmsg := allowed_sysctl_string() + msg := sprintf("The sysctl %v is not explicitly allowed, pod: %v. Allowed sysctls: %v", [sysctl, input.review.object.metadata.name, allowmsg]) } # * may be used to forbid all sysctls @@ -129,6 +130,17 @@ spec: endswith(allowed, "*") startswith(sysctl, trim_suffix(allowed, "*")) } + + allowed_sysctl(_) { + not input.parameters.allowedSysctls + } + allowed_sysctl_string() = out { + not input.parameters.allowedSysctls + out = "unspecified" + } + allowed_sysctl_string() = out { + out = input.parameters.allowedSysctls + } libs: - | package lib.exclude_update diff --git a/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/example_allowed.yaml b/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/example_allowed.yaml index 4b6cc4b66..5cb66a42c 100644 --- a/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/example_allowed.yaml +++ b/library/pod-security-policy/forbidden-sysctls/samples/psp-forbidden-sysctls/example_allowed.yaml @@ -1,7 +1,7 @@ apiVersion: v1 kind: Pod metadata: - name: nginx-forbidden-sysctls-disallowed + name: nginx-forbidden-sysctls-allowed labels: app: nginx-forbidden-sysctls spec: diff --git a/library/pod-security-policy/forbidden-sysctls/template.yaml b/library/pod-security-policy/forbidden-sysctls/template.yaml index 6c9ea66bd..3fc2bda73 100644 --- a/library/pod-security-policy/forbidden-sysctls/template.yaml +++ b/library/pod-security-policy/forbidden-sysctls/template.yaml @@ -97,7 +97,8 @@ spec: not is_update(input.review) sysctl := input.review.object.spec.securityContext.sysctls[_].name not allowed_sysctl(sysctl) - msg := sprintf("The sysctl %v is not explicitly allowed, pod: %v. Allowed sysctls: %v", [sysctl, input.review.object.metadata.name, input.parameters.allowedSysctls]) + allowmsg := allowed_sysctl_string() + msg := sprintf("The sysctl %v is not explicitly allowed, pod: %v. Allowed sysctls: %v", [sysctl, input.review.object.metadata.name, allowmsg]) } # * may be used to forbid all sysctls @@ -129,6 +130,17 @@ spec: endswith(allowed, "*") startswith(sysctl, trim_suffix(allowed, "*")) } + + allowed_sysctl(_) { + not input.parameters.allowedSysctls + } + allowed_sysctl_string() = out { + not input.parameters.allowedSysctls + out = "unspecified" + } + allowed_sysctl_string() = out { + out = input.parameters.allowedSysctls + } libs: - | package lib.exclude_update diff --git a/src/pod-security-policy/forbidden-sysctls/src.rego b/src/pod-security-policy/forbidden-sysctls/src.rego index 135603aa1..6c0e8e086 100644 --- a/src/pod-security-policy/forbidden-sysctls/src.rego +++ b/src/pod-security-policy/forbidden-sysctls/src.rego @@ -17,7 +17,8 @@ violation[{"msg": msg, "details": {}}] { not is_update(input.review) sysctl := input.review.object.spec.securityContext.sysctls[_].name not allowed_sysctl(sysctl) - msg := sprintf("The sysctl %v is not explicitly allowed, pod: %v. Allowed sysctls: %v", [sysctl, input.review.object.metadata.name, input.parameters.allowedSysctls]) + allowmsg := allowed_sysctl_string() + msg := sprintf("The sysctl %v is not explicitly allowed, pod: %v. Allowed sysctls: %v", [sysctl, input.review.object.metadata.name, allowmsg]) } # * may be used to forbid all sysctls @@ -49,3 +50,14 @@ allowed_sysctl(sysctl) { endswith(allowed, "*") startswith(sysctl, trim_suffix(allowed, "*")) } + +allowed_sysctl(_) { + not input.parameters.allowedSysctls +} +allowed_sysctl_string() = out { + not input.parameters.allowedSysctls + out = "unspecified" +} +allowed_sysctl_string() = out { + out = input.parameters.allowedSysctls +} diff --git a/website/docs/validation/forbidden-sysctls.md b/website/docs/validation/forbidden-sysctls.md index c85ad40d3..cbbdd36b6 100644 --- a/website/docs/validation/forbidden-sysctls.md +++ b/website/docs/validation/forbidden-sysctls.md @@ -109,7 +109,8 @@ spec: not is_update(input.review) sysctl := input.review.object.spec.securityContext.sysctls[_].name not allowed_sysctl(sysctl) - msg := sprintf("The sysctl %v is not explicitly allowed, pod: %v. Allowed sysctls: %v", [sysctl, input.review.object.metadata.name, input.parameters.allowedSysctls]) + allowmsg := allowed_sysctl_string() + msg := sprintf("The sysctl %v is not explicitly allowed, pod: %v. Allowed sysctls: %v", [sysctl, input.review.object.metadata.name, allowmsg]) } # * may be used to forbid all sysctls @@ -141,6 +142,17 @@ spec: endswith(allowed, "*") startswith(sysctl, trim_suffix(allowed, "*")) } + + allowed_sysctl(_) { + not input.parameters.allowedSysctls + } + allowed_sysctl_string() = out { + not input.parameters.allowedSysctls + out = "unspecified" + } + allowed_sysctl_string() = out { + out = input.parameters.allowedSysctls + } libs: - | package lib.exclude_update @@ -226,7 +238,7 @@ kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper- apiVersion: v1 kind: Pod metadata: - name: nginx-forbidden-sysctls-disallowed + name: nginx-forbidden-sysctls-allowed labels: app: nginx-forbidden-sysctls spec: @@ -318,7 +330,7 @@ kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper- apiVersion: v1 kind: Pod metadata: - name: nginx-forbidden-sysctls-disallowed + name: nginx-forbidden-sysctls-allowed labels: app: nginx-forbidden-sysctls spec: @@ -411,7 +423,7 @@ kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper- apiVersion: v1 kind: Pod metadata: - name: nginx-forbidden-sysctls-disallowed + name: nginx-forbidden-sysctls-allowed labels: app: nginx-forbidden-sysctls spec: @@ -503,7 +515,7 @@ kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper- apiVersion: v1 kind: Pod metadata: - name: nginx-forbidden-sysctls-disallowed + name: nginx-forbidden-sysctls-allowed labels: app: nginx-forbidden-sysctls spec: @@ -595,7 +607,7 @@ kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper- apiVersion: v1 kind: Pod metadata: - name: nginx-forbidden-sysctls-disallowed + name: nginx-forbidden-sysctls-allowed labels: app: nginx-forbidden-sysctls spec: