diff --git a/artifacthub/library/pod-security-policy/flexvolume-drivers/1.1.0/artifacthub-pkg.yml b/artifacthub/library/pod-security-policy/flexvolume-drivers/1.1.0/artifacthub-pkg.yml new file mode 100644 index 000000000..478ad8ad3 --- /dev/null +++ b/artifacthub/library/pod-security-policy/flexvolume-drivers/1.1.0/artifacthub-pkg.yml @@ -0,0 +1,22 @@ +version: 1.1.0 +name: k8spspflexvolumes +displayName: FlexVolumes +createdAt: "2024-05-29T23:34:09Z" +description: Controls the allowlist of FlexVolume drivers. Corresponds to the `allowedFlexVolumes` field in PodSecurityPolicy. For more information, see https://kubernetes.io/docs/concepts/policy/pod-security-policy/#flexvolume-drivers +digest: d76c22a6c2f63b7421fe7b14da4668dbc27d93a0337884ddad79492802ce4e0f +license: Apache-2.0 +homeURL: https://open-policy-agent.github.io/gatekeeper-library/website/flexvolume-drivers +keywords: + - gatekeeper + - open-policy-agent + - policies +readme: |- + # FlexVolumes + Controls the allowlist of FlexVolume drivers. Corresponds to the `allowedFlexVolumes` field in PodSecurityPolicy. For more information, see https://kubernetes.io/docs/concepts/policy/pod-security-policy/#flexvolume-drivers +install: |- + ### Usage + ```shell + kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/artifacthub/library/pod-security-policy/flexvolume-drivers/1.1.0/template.yaml + ``` +provider: + name: Gatekeeper Library diff --git a/artifacthub/library/pod-security-policy/flexvolume-drivers/1.1.0/kustomization.yaml b/artifacthub/library/pod-security-policy/flexvolume-drivers/1.1.0/kustomization.yaml new file mode 100644 index 000000000..7d70d11b7 --- /dev/null +++ b/artifacthub/library/pod-security-policy/flexvolume-drivers/1.1.0/kustomization.yaml @@ -0,0 +1,2 @@ +resources: + - template.yaml diff --git a/artifacthub/library/pod-security-policy/flexvolume-drivers/1.1.0/samples/psp-flexvolume-drivers/constraint.yaml b/artifacthub/library/pod-security-policy/flexvolume-drivers/1.1.0/samples/psp-flexvolume-drivers/constraint.yaml new file mode 100644 index 000000000..8fc65f2de --- /dev/null +++ b/artifacthub/library/pod-security-policy/flexvolume-drivers/1.1.0/samples/psp-flexvolume-drivers/constraint.yaml @@ -0,0 +1,13 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sPSPFlexVolumes +metadata: + name: psp-flexvolume-drivers +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] + parameters: + allowedFlexVolumes: #[] + - driver: "example/lvm" + - driver: "example/cifs" diff --git a/artifacthub/library/pod-security-policy/flexvolume-drivers/1.1.0/samples/psp-flexvolume-drivers/example_allowed.yaml b/artifacthub/library/pod-security-policy/flexvolume-drivers/1.1.0/samples/psp-flexvolume-drivers/example_allowed.yaml new file mode 100644 index 000000000..22b2e949c --- /dev/null +++ b/artifacthub/library/pod-security-policy/flexvolume-drivers/1.1.0/samples/psp-flexvolume-drivers/example_allowed.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx-flexvolume-driver-allowed + labels: + app: nginx-flexvolume-driver +spec: + containers: + - name: nginx + image: nginx + volumeMounts: + - mountPath: /test + name: test-volume + readOnly: true + volumes: + - name: test-volume + flexVolume: + driver: "example/lvm" diff --git a/artifacthub/library/pod-security-policy/flexvolume-drivers/1.1.0/samples/psp-flexvolume-drivers/example_disallowed.yaml b/artifacthub/library/pod-security-policy/flexvolume-drivers/1.1.0/samples/psp-flexvolume-drivers/example_disallowed.yaml new file mode 100644 index 000000000..9a8f27d67 --- /dev/null +++ b/artifacthub/library/pod-security-policy/flexvolume-drivers/1.1.0/samples/psp-flexvolume-drivers/example_disallowed.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx-flexvolume-driver-disallowed + labels: + app: nginx-flexvolume-driver +spec: + containers: + - name: nginx + image: nginx + volumeMounts: + - mountPath: /test + name: test-volume + readOnly: true + volumes: + - name: test-volume + flexVolume: + driver: "example/testdriver" #"example/lvm" diff --git a/artifacthub/library/pod-security-policy/flexvolume-drivers/1.1.0/samples/psp-flexvolume-drivers/update.yaml b/artifacthub/library/pod-security-policy/flexvolume-drivers/1.1.0/samples/psp-flexvolume-drivers/update.yaml new file mode 100644 index 000000000..9358c6c5c --- /dev/null +++ b/artifacthub/library/pod-security-policy/flexvolume-drivers/1.1.0/samples/psp-flexvolume-drivers/update.yaml @@ -0,0 +1,23 @@ +kind: AdmissionReview +apiVersion: admission.k8s.io/v1beta1 +request: + operation: "UPDATE" + object: + apiVersion: v1 + kind: Pod + metadata: + name: nginx-flexvolume-driver-disallowed + labels: + app: nginx-flexvolume-driver + spec: + containers: + - name: nginx + image: nginx + volumeMounts: + - mountPath: /test + name: test-volume + readOnly: true + volumes: + - name: test-volume + flexVolume: + driver: "example/testdriver" #"example/lvm" diff --git a/artifacthub/library/pod-security-policy/flexvolume-drivers/1.1.0/suite.yaml b/artifacthub/library/pod-security-policy/flexvolume-drivers/1.1.0/suite.yaml new file mode 100644 index 000000000..fe69966bd --- /dev/null +++ b/artifacthub/library/pod-security-policy/flexvolume-drivers/1.1.0/suite.yaml @@ -0,0 +1,21 @@ +kind: Suite +apiVersion: test.gatekeeper.sh/v1alpha1 +metadata: + name: flexvolume-drivers +tests: + - name: flexvolume-drivers + template: template.yaml + constraint: samples/psp-flexvolume-drivers/constraint.yaml + cases: + - name: example-allowed + object: samples/psp-flexvolume-drivers/example_allowed.yaml + assertions: + - violations: no + - name: example-disallowed + object: samples/psp-flexvolume-drivers/example_disallowed.yaml + assertions: + - violations: yes + - name: update + object: samples/psp-flexvolume-drivers/update.yaml + assertions: + - violations: no diff --git a/artifacthub/library/pod-security-policy/flexvolume-drivers/1.1.0/template.yaml b/artifacthub/library/pod-security-policy/flexvolume-drivers/1.1.0/template.yaml new file mode 100644 index 000000000..e6f9e4f29 --- /dev/null +++ b/artifacthub/library/pod-security-policy/flexvolume-drivers/1.1.0/template.yaml @@ -0,0 +1,94 @@ +apiVersion: templates.gatekeeper.sh/v1 +kind: ConstraintTemplate +metadata: + name: k8spspflexvolumes + annotations: + metadata.gatekeeper.sh/title: "FlexVolumes" + metadata.gatekeeper.sh/version: 1.1.0 + description: >- + Controls the allowlist of FlexVolume drivers. Corresponds to the + `allowedFlexVolumes` field in PodSecurityPolicy. For more information, + see + https://kubernetes.io/docs/concepts/policy/pod-security-policy/#flexvolume-drivers +spec: + crd: + spec: + names: + kind: K8sPSPFlexVolumes + validation: + # Schema for the `parameters` field + openAPIV3Schema: + type: object + description: >- + Controls the allowlist of FlexVolume drivers. Corresponds to the + `allowedFlexVolumes` field in PodSecurityPolicy. For more information, + see + https://kubernetes.io/docs/concepts/policy/pod-security-policy/#flexvolume-drivers + properties: + allowedFlexVolumes: + type: array + description: "An array of AllowedFlexVolume objects." + items: + type: object + properties: + driver: + description: "The name of the FlexVolume driver." + type: string + targets: + - target: admission.k8s.gatekeeper.sh + code: + - engine: K8sNativeValidation + source: + variables: + - name: flexVolumes + expression: | + !has(variables.anyObject.spec.volumes) ? [] : + variables.anyObject.spec.volumes.filter(volume, has(volume.flexVolume)) + - name: allowedFlexVolumeDrivers + expression: variables.params.allowedFlexVolumes.map(volume, volume.driver) + - name: badFlexVolumeNames + expression: | + variables.flexVolumes.map(volume, + !has(volume.flexVolume.driver) || !(volume.flexVolume.driver in variables.allowedFlexVolumeDrivers), + volume.name + ) + validations: + - expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.badFlexVolumeNames) == 0' + messageExpression: | + "FlexVolumes [" + variables.badFlexVolumeNames.join(", ") + "] not allowed, pod: " + variables.anyObject.metadata.name + ". Allowed drivers: [" + variables.allowedFlexVolumeDrivers.join(", ") + "]" + - engine: Rego + source: + rego: | + package k8spspflexvolumes + + import data.lib.exclude_update.is_update + + violation[{"msg": msg, "details": {}}] { + # spec.volumes field is immutable. + not is_update(input.review) + + volume := input_flexvolumes[_] + not input_flexvolumes_allowed(volume) + msg := sprintf("FlexVolume %v is not allowed, pod: %v. Allowed drivers: %v", [volume, input.review.object.metadata.name, input.parameters.allowedFlexVolumes]) + } + + input_flexvolumes_allowed(volume) { + input.parameters.allowedFlexVolumes[_].driver == volume.flexVolume.driver + } + + input_flexvolumes[v] { + v := input.review.object.spec.volumes[_] + has_field(v, "flexVolume") + } + + # has_field returns whether an object has a field + has_field(object, field) = true { + object[field] + } + libs: + - | + package lib.exclude_update + + is_update(review) { + review.operation == "UPDATE" + } diff --git a/library/pod-security-policy/flexvolume-drivers/template.yaml b/library/pod-security-policy/flexvolume-drivers/template.yaml index c059681c9..e6f9e4f29 100644 --- a/library/pod-security-policy/flexvolume-drivers/template.yaml +++ b/library/pod-security-policy/flexvolume-drivers/template.yaml @@ -4,7 +4,7 @@ metadata: name: k8spspflexvolumes annotations: metadata.gatekeeper.sh/title: "FlexVolumes" - metadata.gatekeeper.sh/version: 1.0.1 + metadata.gatekeeper.sh/version: 1.1.0 description: >- Controls the allowlist of FlexVolume drivers. Corresponds to the `allowedFlexVolumes` field in PodSecurityPolicy. For more information, @@ -36,37 +36,59 @@ spec: type: string targets: - target: admission.k8s.gatekeeper.sh - rego: | - package k8spspflexvolumes + code: + - engine: K8sNativeValidation + source: + variables: + - name: flexVolumes + expression: | + !has(variables.anyObject.spec.volumes) ? [] : + variables.anyObject.spec.volumes.filter(volume, has(volume.flexVolume)) + - name: allowedFlexVolumeDrivers + expression: variables.params.allowedFlexVolumes.map(volume, volume.driver) + - name: badFlexVolumeNames + expression: | + variables.flexVolumes.map(volume, + !has(volume.flexVolume.driver) || !(volume.flexVolume.driver in variables.allowedFlexVolumeDrivers), + volume.name + ) + validations: + - expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.badFlexVolumeNames) == 0' + messageExpression: | + "FlexVolumes [" + variables.badFlexVolumeNames.join(", ") + "] not allowed, pod: " + variables.anyObject.metadata.name + ". Allowed drivers: [" + variables.allowedFlexVolumeDrivers.join(", ") + "]" + - engine: Rego + source: + rego: | + package k8spspflexvolumes - import data.lib.exclude_update.is_update + import data.lib.exclude_update.is_update - violation[{"msg": msg, "details": {}}] { - # spec.volumes field is immutable. - not is_update(input.review) + violation[{"msg": msg, "details": {}}] { + # spec.volumes field is immutable. + not is_update(input.review) - volume := input_flexvolumes[_] - not input_flexvolumes_allowed(volume) - msg := sprintf("FlexVolume %v is not allowed, pod: %v. Allowed drivers: %v", [volume, input.review.object.metadata.name, input.parameters.allowedFlexVolumes]) - } + volume := input_flexvolumes[_] + not input_flexvolumes_allowed(volume) + msg := sprintf("FlexVolume %v is not allowed, pod: %v. Allowed drivers: %v", [volume, input.review.object.metadata.name, input.parameters.allowedFlexVolumes]) + } - input_flexvolumes_allowed(volume) { - input.parameters.allowedFlexVolumes[_].driver == volume.flexVolume.driver - } + input_flexvolumes_allowed(volume) { + input.parameters.allowedFlexVolumes[_].driver == volume.flexVolume.driver + } - input_flexvolumes[v] { - v := input.review.object.spec.volumes[_] - has_field(v, "flexVolume") - } + input_flexvolumes[v] { + v := input.review.object.spec.volumes[_] + has_field(v, "flexVolume") + } - # has_field returns whether an object has a field - has_field(object, field) = true { - object[field] - } - libs: - - | - package lib.exclude_update + # has_field returns whether an object has a field + has_field(object, field) = true { + object[field] + } + libs: + - | + package lib.exclude_update - is_update(review) { - review.operation == "UPDATE" - } + is_update(review) { + review.operation == "UPDATE" + } diff --git a/src/pod-security-policy/flexvolume-drivers/constraint.tmpl b/src/pod-security-policy/flexvolume-drivers/constraint.tmpl index e0a7b51df..95757bf57 100644 --- a/src/pod-security-policy/flexvolume-drivers/constraint.tmpl +++ b/src/pod-security-policy/flexvolume-drivers/constraint.tmpl @@ -4,7 +4,7 @@ metadata: name: k8spspflexvolumes annotations: metadata.gatekeeper.sh/title: "FlexVolumes" - metadata.gatekeeper.sh/version: 1.0.1 + metadata.gatekeeper.sh/version: 1.1.0 description: >- Controls the allowlist of FlexVolume drivers. Corresponds to the `allowedFlexVolumes` field in PodSecurityPolicy. For more information, @@ -36,8 +36,14 @@ spec: type: string targets: - target: admission.k8s.gatekeeper.sh - rego: | -{{ file.Read "src/pod-security-policy/flexvolume-drivers/src.rego" | strings.Indent 8 | strings.TrimSuffix "\n" }} - libs: - - | -{{ file.Read "src/pod-security-policy/flexvolume-drivers/lib_exclude_update.rego" | strings.Indent 10 | strings.TrimSuffix "\n" }} + code: + - engine: K8sNativeValidation + source: +{{ file.Read "src/pod-security-policy/flexvolume-drivers/src.cel" | strings.Indent 10 | strings.TrimSuffix "\n" }} + - engine: Rego + source: + rego: | +{{ file.Read "src/pod-security-policy/flexvolume-drivers/src.rego" | strings.Indent 12 | strings.TrimSuffix "\n" }} + libs: + - | +{{ file.Read "src/pod-security-policy/flexvolume-drivers/lib_exclude_update.rego" | strings.Indent 12 | strings.TrimSuffix "\n" }} diff --git a/src/pod-security-policy/flexvolume-drivers/src.cel b/src/pod-security-policy/flexvolume-drivers/src.cel new file mode 100644 index 000000000..d42b15335 --- /dev/null +++ b/src/pod-security-policy/flexvolume-drivers/src.cel @@ -0,0 +1,17 @@ +variables: +- name: flexVolumes + expression: | + !has(variables.anyObject.spec.volumes) ? [] : + variables.anyObject.spec.volumes.filter(volume, has(volume.flexVolume)) +- name: allowedFlexVolumeDrivers + expression: variables.params.allowedFlexVolumes.map(volume, volume.driver) +- name: badFlexVolumeNames + expression: | + variables.flexVolumes.map(volume, + !has(volume.flexVolume.driver) || !(volume.flexVolume.driver in variables.allowedFlexVolumeDrivers), + volume.name + ) +validations: +- expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.badFlexVolumeNames) == 0' + messageExpression: | + "FlexVolumes [" + variables.badFlexVolumeNames.join(", ") + "] not allowed, pod: " + variables.anyObject.metadata.name + ". Allowed drivers: [" + variables.allowedFlexVolumeDrivers.join(", ") + "]" \ No newline at end of file diff --git a/website/docs/validation/flexvolume-drivers.md b/website/docs/validation/flexvolume-drivers.md index 349cabfa9..1ba170f59 100644 --- a/website/docs/validation/flexvolume-drivers.md +++ b/website/docs/validation/flexvolume-drivers.md @@ -16,7 +16,7 @@ metadata: name: k8spspflexvolumes annotations: metadata.gatekeeper.sh/title: "FlexVolumes" - metadata.gatekeeper.sh/version: 1.0.1 + metadata.gatekeeper.sh/version: 1.1.0 description: >- Controls the allowlist of FlexVolume drivers. Corresponds to the `allowedFlexVolumes` field in PodSecurityPolicy. For more information, @@ -48,40 +48,62 @@ spec: type: string targets: - target: admission.k8s.gatekeeper.sh - rego: | - package k8spspflexvolumes - - import data.lib.exclude_update.is_update - - violation[{"msg": msg, "details": {}}] { - # spec.volumes field is immutable. - not is_update(input.review) - - volume := input_flexvolumes[_] - not input_flexvolumes_allowed(volume) - msg := sprintf("FlexVolume %v is not allowed, pod: %v. Allowed drivers: %v", [volume, input.review.object.metadata.name, input.parameters.allowedFlexVolumes]) - } - - input_flexvolumes_allowed(volume) { - input.parameters.allowedFlexVolumes[_].driver == volume.flexVolume.driver - } - - input_flexvolumes[v] { - v := input.review.object.spec.volumes[_] - has_field(v, "flexVolume") - } - - # has_field returns whether an object has a field - has_field(object, field) = true { - object[field] - } - libs: - - | - package lib.exclude_update - - is_update(review) { - review.operation == "UPDATE" - } + code: + - engine: K8sNativeValidation + source: + variables: + - name: flexVolumes + expression: | + !has(variables.anyObject.spec.volumes) ? [] : + variables.anyObject.spec.volumes.filter(volume, has(volume.flexVolume)) + - name: allowedFlexVolumeDrivers + expression: variables.params.allowedFlexVolumes.map(volume, volume.driver) + - name: badFlexVolumeNames + expression: | + variables.flexVolumes.map(volume, + !has(volume.flexVolume.driver) || !(volume.flexVolume.driver in variables.allowedFlexVolumeDrivers), + volume.name + ) + validations: + - expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.badFlexVolumeNames) == 0' + messageExpression: | + "FlexVolumes [" + variables.badFlexVolumeNames.join(", ") + "] not allowed, pod: " + variables.anyObject.metadata.name + ". Allowed drivers: [" + variables.allowedFlexVolumeDrivers.join(", ") + "]" + - engine: Rego + source: + rego: | + package k8spspflexvolumes + + import data.lib.exclude_update.is_update + + violation[{"msg": msg, "details": {}}] { + # spec.volumes field is immutable. + not is_update(input.review) + + volume := input_flexvolumes[_] + not input_flexvolumes_allowed(volume) + msg := sprintf("FlexVolume %v is not allowed, pod: %v. Allowed drivers: %v", [volume, input.review.object.metadata.name, input.parameters.allowedFlexVolumes]) + } + + input_flexvolumes_allowed(volume) { + input.parameters.allowedFlexVolumes[_].driver == volume.flexVolume.driver + } + + input_flexvolumes[v] { + v := input.review.object.spec.volumes[_] + has_field(v, "flexVolume") + } + + # has_field returns whether an object has a field + has_field(object, field) = true { + object[field] + } + libs: + - | + package lib.exclude_update + + is_update(review) { + review.operation == "UPDATE" + } ```