From c1b9241c132610a48d1f236a1519b8fdd92a4456 Mon Sep 17 00:00:00 2001 From: Jaydip Gabani Date: Thu, 2 May 2024 19:02:01 +0000 Subject: [PATCH 01/23] testing with cel policies Signed-off-by: Jaydip Gabani --- .github/workflows/workflow.yaml | 12 +- Makefile | 22 ++- .../requiredlabels/1.0.2/artifacthub-pkg.yml | 22 +++ .../requiredlabels/1.0.2/kustomization.yaml | 2 + .../all-must-have-owner/constraint.yaml | 14 ++ .../all-must-have-owner/example_allowed.yaml | 6 + .../example_disallowed.yaml | 4 + .../general/requiredlabels/1.0.2/suite.yaml | 17 +++ .../requiredlabels/1.0.2/template.yaml | 77 +++++++++++ .../1.0.2/artifacthub-pkg.yml | 22 +++ .../1.0.2/kustomization.yaml | 2 + .../constraint.yaml | 9 ++ .../disallowed_ephemeral.yaml | 12 ++ .../example_allowed.yaml | 12 ++ .../example_disallowed.yaml | 12 ++ .../update.yaml | 17 +++ .../1.0.2/suite.yaml | 25 ++++ .../1.0.2/template.yaml | 129 ++++++++++++++++++ library/general/requiredlabels/template.yaml | 11 +- .../allow-privilege-escalation/template.yaml | 31 ++++- src/general/requiredlabels/constraint.tmpl | 6 +- src/general/requiredlabels/src.cel | 6 + .../constraint.tmpl | 6 +- .../allow-privilege-escalation/src.cel | 26 ++++ .../validation/allow-privilege-escalation.md | 31 ++++- website/docs/validation/requiredlabels.md | 11 +- 26 files changed, 530 insertions(+), 14 deletions(-) create mode 100644 artifacthub/library/general/requiredlabels/1.0.2/artifacthub-pkg.yml create mode 100644 artifacthub/library/general/requiredlabels/1.0.2/kustomization.yaml create mode 100644 artifacthub/library/general/requiredlabels/1.0.2/samples/all-must-have-owner/constraint.yaml create mode 100644 artifacthub/library/general/requiredlabels/1.0.2/samples/all-must-have-owner/example_allowed.yaml create mode 100644 artifacthub/library/general/requiredlabels/1.0.2/samples/all-must-have-owner/example_disallowed.yaml create mode 100644 artifacthub/library/general/requiredlabels/1.0.2/suite.yaml create mode 100644 artifacthub/library/general/requiredlabels/1.0.2/template.yaml create mode 100644 artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/artifacthub-pkg.yml create mode 100644 artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/kustomization.yaml create mode 100644 artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/constraint.yaml create mode 100644 artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/disallowed_ephemeral.yaml create mode 100644 artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/example_allowed.yaml create mode 100644 artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/example_disallowed.yaml create mode 100644 artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/update.yaml create mode 100644 artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/suite.yaml create mode 100644 artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/template.yaml create mode 100644 src/general/requiredlabels/src.cel create mode 100644 src/pod-security-policy/allow-privilege-escalation/src.cel diff --git a/.github/workflows/workflow.yaml b/.github/workflows/workflow.yaml index d63d9f2b0..70c18f7b0 100644 --- a/.github/workflows/workflow.yaml +++ b/.github/workflows/workflow.yaml @@ -65,7 +65,8 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - gatekeeper: [ "release-3.13", "release-3.14" ] + gatekeeper: [ "3.14.2", "3.15.1" ] + engine: [ "cel", "rego" ] name: "Integration test on Gatekeeper ${{ matrix.gatekeeper }}" steps: - name: Harden Runner @@ -81,7 +82,7 @@ jobs: mkdir -p $GITHUB_WORKSPACE/bin echo "$GITHUB_WORKSPACE/bin" >> $GITHUB_PATH make integration-bootstrap - make deploy GATEKEEPER_VERSION=${{ matrix.gatekeeper }} + make deploy GATEKEEPER_VERSION=${{ matrix.gatekeeper }} POLICY_ENGINE=${{ matrix.engine }} - name: Run integration test run: | @@ -127,7 +128,10 @@ jobs: make require-sync gator-verify: runs-on: ubuntu-latest - name: "Verify assertions in suite.yaml files" + strategy: + matrix: + engine: [ "cel", "rego" ] + name: "Verify assertions in suite.yaml files for ${{ matrix.engine }} policies" steps: - name: Harden Runner uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 @@ -136,4 +140,4 @@ jobs: - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - run: | - make verify-gator-dockerized + make verify-gator-dockerized POLICY_ENGINE=${{ matrix.engine }} diff --git a/Makefile b/Makefile index 144ea4ec1..0d9c7cd13 100644 --- a/Makefile +++ b/Makefile @@ -3,10 +3,11 @@ KIND_VERSION ?= 0.17.0 # note: k8s version pinned since KIND image availability lags k8s releases KUBERNETES_VERSION ?= 1.26.0 KUSTOMIZE_VERSION ?= 4.5.5 -GATEKEEPER_VERSION ?= release-3.11 +GATEKEEPER_VERSION ?= 3.15.1 BATS_VERSION ?= 1.8.2 -GATOR_VERSION ?= 3.11.0 +GATOR_VERSION ?= 3.15.1 GOMPLATE_VERSION ?= 3.11.6 +POLICY_ENGINE ?= rego REPO_ROOT := $(shell git rev-parse --show-toplevel) WEBSITE_SCRIPT_DIR := $(REPO_ROOT)/scripts/website @@ -31,21 +32,34 @@ integration-bootstrap: TERM=dumb ${GITHUB_WORKSPACE}/bin/kind create cluster --image kindest/node:v${KUBERNETES_VERSION} --wait 5m --config=test/kind_config.yaml deploy: - kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/${GATEKEEPER_VERSION}/deploy/gatekeeper.yaml + helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts +ifeq ($(POLICY_ENGINE), rego) + helm install gatekeeper/gatekeeper --name-template=gatekeeper --namespace gatekeeper-system --create-namespace --version=${GATEKEEPER_VERSION} +else ifeq ($(POLICY_ENGINE), cel) + helm install gatekeeper/gatekeeper --name-template=gatekeeper --namespace gatekeeper-system --create-namespace --version=${GATEKEEPER_VERSION} --set enableK8sNativeValidation=true +endif uninstall: - kubectl delete -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/${GATEKEEPER_VERSION}/deploy/gatekeeper.yaml + helm delete gatekeeper --namespace gatekeeper-system test-integration: bats -t test/bats/test.bats .PHONY: verify-gator verify-gator: +ifeq ($(POLICY_ENGINE), rego) gator verify ./... +else ifeq ($(POLICY_ENGINE), cel) + gator verify ./... --experimental-enable-k8s-native-validation=true +endif .PHONY: verify-gator-dockerized verify-gator-dockerized: __build-gator +ifeq ($(POLICY_ENGINE), rego) $(docker) run -i -v $(shell pwd):/gatekeeper-library gator-container verify ./... +else ifeq ($(POLICY_ENGINE), cel) + $(docker) run -i -v $(shell pwd):/gatekeeper-library gator-container verify ./... --experimental-enable-k8s-native-validation=true +endif .PHONY: build-gator __build-gator: diff --git a/artifacthub/library/general/requiredlabels/1.0.2/artifacthub-pkg.yml b/artifacthub/library/general/requiredlabels/1.0.2/artifacthub-pkg.yml new file mode 100644 index 000000000..1d68967ee --- /dev/null +++ b/artifacthub/library/general/requiredlabels/1.0.2/artifacthub-pkg.yml @@ -0,0 +1,22 @@ +version: 1.0.2 +name: k8srequiredlabels +displayName: Required Labels +createdAt: "2024-05-02T19:01:02Z" +description: Requires resources to contain specified labels, with values matching provided regular expressions. +digest: e41978589a21f07237a098331543f99ede07098acac8d80a4d44cc050a1ad618 +license: Apache-2.0 +homeURL: https://open-policy-agent.github.io/gatekeeper-library/website/requiredlabels +keywords: + - gatekeeper + - open-policy-agent + - policies +readme: |- + # Required Labels + Requires resources to contain specified labels, with values matching provided regular expressions. +install: |- + ### Usage + ```shell + kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/artifacthub/library/general/requiredlabels/1.0.2/template.yaml + ``` +provider: + name: Gatekeeper Library diff --git a/artifacthub/library/general/requiredlabels/1.0.2/kustomization.yaml b/artifacthub/library/general/requiredlabels/1.0.2/kustomization.yaml new file mode 100644 index 000000000..7d70d11b7 --- /dev/null +++ b/artifacthub/library/general/requiredlabels/1.0.2/kustomization.yaml @@ -0,0 +1,2 @@ +resources: + - template.yaml diff --git a/artifacthub/library/general/requiredlabels/1.0.2/samples/all-must-have-owner/constraint.yaml b/artifacthub/library/general/requiredlabels/1.0.2/samples/all-must-have-owner/constraint.yaml new file mode 100644 index 000000000..806e9862f --- /dev/null +++ b/artifacthub/library/general/requiredlabels/1.0.2/samples/all-must-have-owner/constraint.yaml @@ -0,0 +1,14 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sRequiredLabels +metadata: + name: all-must-have-owner +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Namespace"] + parameters: + message: "All namespaces must have an `owner` label that points to your company username" + labels: + - key: owner + allowedRegex: "^[a-zA-Z]+.agilebank.demo$" diff --git a/artifacthub/library/general/requiredlabels/1.0.2/samples/all-must-have-owner/example_allowed.yaml b/artifacthub/library/general/requiredlabels/1.0.2/samples/all-must-have-owner/example_allowed.yaml new file mode 100644 index 000000000..e2d3b9c03 --- /dev/null +++ b/artifacthub/library/general/requiredlabels/1.0.2/samples/all-must-have-owner/example_allowed.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: allowed-namespace + labels: + owner: user.agilebank.demo diff --git a/artifacthub/library/general/requiredlabels/1.0.2/samples/all-must-have-owner/example_disallowed.yaml b/artifacthub/library/general/requiredlabels/1.0.2/samples/all-must-have-owner/example_disallowed.yaml new file mode 100644 index 000000000..a7a53610a --- /dev/null +++ b/artifacthub/library/general/requiredlabels/1.0.2/samples/all-must-have-owner/example_disallowed.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: disallowed-namespace diff --git a/artifacthub/library/general/requiredlabels/1.0.2/suite.yaml b/artifacthub/library/general/requiredlabels/1.0.2/suite.yaml new file mode 100644 index 000000000..64c5b4130 --- /dev/null +++ b/artifacthub/library/general/requiredlabels/1.0.2/suite.yaml @@ -0,0 +1,17 @@ +kind: Suite +apiVersion: test.gatekeeper.sh/v1alpha1 +metadata: + name: requiredlabels +tests: +- name: must-have-owner + template: template.yaml + constraint: samples/all-must-have-owner/constraint.yaml + cases: + - name: example-allowed + object: samples/all-must-have-owner/example_allowed.yaml + assertions: + - violations: no + - name: example-disallowed + object: samples/all-must-have-owner/example_disallowed.yaml + assertions: + - violations: yes diff --git a/artifacthub/library/general/requiredlabels/1.0.2/template.yaml b/artifacthub/library/general/requiredlabels/1.0.2/template.yaml new file mode 100644 index 000000000..1d6d23512 --- /dev/null +++ b/artifacthub/library/general/requiredlabels/1.0.2/template.yaml @@ -0,0 +1,77 @@ +apiVersion: templates.gatekeeper.sh/v1 +kind: ConstraintTemplate +metadata: + name: k8srequiredlabels + annotations: + metadata.gatekeeper.sh/title: "Required Labels" + metadata.gatekeeper.sh/version: 1.0.2 + description: >- + Requires resources to contain specified labels, with values matching + provided regular expressions. +spec: + crd: + spec: + names: + kind: K8sRequiredLabels + validation: + openAPIV3Schema: + type: object + properties: + message: + type: string + labels: + type: array + description: >- + A list of labels and values the object must specify. + items: + type: object + properties: + key: + type: string + description: >- + The required label. + allowedRegex: + type: string + description: >- + If specified, a regular expression the annotation's value + must match. The value must contain at least one match for + the regular expression. + targets: + - target: admission.k8s.gatekeeper.sh + code: + - engine: K8sNativeValidation + source: + + validations: + - expression: '[object, oldObject].exists(obj, obj != null && has(obj.metadata) && variables.params.labels.all(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels))' + messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' + - expression: '[object, oldObject].exists(obj, obj != null && !variables.params.labels.exists(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels && !string(obj.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' + message: "regex mismatch" + rego: | + package k8srequiredlabels + + get_message(parameters, _default) := _default { + not parameters.message + } + + get_message(parameters, _) := parameters.message + + violation[{"msg": msg, "details": {"missing_labels": missing}}] { + provided := {label | input.review.object.metadata.labels[label]} + required := {label | label := input.parameters.labels[_].key} + missing := required - provided + count(missing) > 0 + def_msg := sprintf("you must provide labels: %v", [missing]) + msg := get_message(input.parameters, def_msg) + } + + violation[{"msg": msg}] { + value := input.review.object.metadata.labels[key] + expected := input.parameters.labels[_] + expected.key == key + # do not match if allowedRegex is not defined, or is an empty string + expected.allowedRegex != "" + not regex.match(expected.allowedRegex, value) + def_msg := sprintf("Label <%v: %v> does not satisfy allowed regex: %v", [key, value, expected.allowedRegex]) + msg := get_message(input.parameters, def_msg) + } diff --git a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/artifacthub-pkg.yml b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/artifacthub-pkg.yml new file mode 100644 index 000000000..b1f227992 --- /dev/null +++ b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/artifacthub-pkg.yml @@ -0,0 +1,22 @@ +version: 1.0.2 +name: k8spspallowprivilegeescalationcontainer +displayName: Allow Privilege Escalation in Container +createdAt: "2024-05-02T19:01:02Z" +description: Controls restricting escalation to root privileges. Corresponds to the `allowPrivilegeEscalation` field in a PodSecurityPolicy. For more information, see https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation +digest: 64107d0d609554fcc6740d2a2c45bd5d221c1eedaaaee3a409aec827aa196a64 +license: Apache-2.0 +homeURL: https://open-policy-agent.github.io/gatekeeper-library/website/allow-privilege-escalation +keywords: + - gatekeeper + - open-policy-agent + - policies +readme: |- + # Allow Privilege Escalation in Container + Controls restricting escalation to root privileges. Corresponds to the `allowPrivilegeEscalation` field in a PodSecurityPolicy. For more information, see https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation +install: |- + ### Usage + ```shell + kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/template.yaml + ``` +provider: + name: Gatekeeper Library diff --git a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/kustomization.yaml b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/kustomization.yaml new file mode 100644 index 000000000..7d70d11b7 --- /dev/null +++ b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/kustomization.yaml @@ -0,0 +1,2 @@ +resources: + - template.yaml diff --git a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/constraint.yaml b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/constraint.yaml new file mode 100644 index 000000000..fdc05a1c0 --- /dev/null +++ b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/constraint.yaml @@ -0,0 +1,9 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sPSPAllowPrivilegeEscalationContainer +metadata: + name: psp-allow-privilege-escalation-container +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] diff --git a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/disallowed_ephemeral.yaml b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/disallowed_ephemeral.yaml new file mode 100644 index 000000000..5992f96b3 --- /dev/null +++ b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/disallowed_ephemeral.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx-privilege-escalation-disallowed + labels: + app: nginx-privilege-escalation +spec: + ephemeralContainers: + - name: nginx + image: nginx + securityContext: + allowPrivilegeEscalation: true diff --git a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/example_allowed.yaml b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/example_allowed.yaml new file mode 100644 index 000000000..26c8dd879 --- /dev/null +++ b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/example_allowed.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx-privilege-escalation-allowed + labels: + app: nginx-privilege-escalation +spec: + containers: + - name: nginx + image: nginx + securityContext: + allowPrivilegeEscalation: false diff --git a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/example_disallowed.yaml b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/example_disallowed.yaml new file mode 100644 index 000000000..d3648d2f2 --- /dev/null +++ b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/example_disallowed.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx-privilege-escalation-disallowed + labels: + app: nginx-privilege-escalation +spec: + containers: + - name: nginx + image: nginx + securityContext: + allowPrivilegeEscalation: true diff --git a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/update.yaml b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/update.yaml new file mode 100644 index 000000000..a79d40a1b --- /dev/null +++ b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/update.yaml @@ -0,0 +1,17 @@ +kind: AdmissionReview +apiVersion: admission.k8s.io/v1beta1 +request: + operation: "UPDATE" + object: + apiVersion: v1 + kind: Pod + metadata: + name: nginx-privilege-escalation-disallowed + labels: + app: nginx-privilege-escalation + spec: + containers: + - name: nginx + image: nginx + securityContext: + allowPrivilegeEscalation: true diff --git a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/suite.yaml b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/suite.yaml new file mode 100644 index 000000000..cd7531cfa --- /dev/null +++ b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/suite.yaml @@ -0,0 +1,25 @@ +kind: Suite +apiVersion: test.gatekeeper.sh/v1alpha1 +metadata: + name: allow-privilege-escalation +tests: + - name: allow-privilege-escalation + template: template.yaml + constraint: samples/psp-allow-privilege-escalation-container/constraint.yaml + cases: + - name: example-allowed + object: samples/psp-allow-privilege-escalation-container/example_allowed.yaml + assertions: + - violations: no + - name: example-disallowed + object: samples/psp-allow-privilege-escalation-container/example_disallowed.yaml + assertions: + - violations: yes + - name: disallowed-ephemeral + object: samples/psp-allow-privilege-escalation-container/disallowed_ephemeral.yaml + assertions: + - violations: yes + - name: update + object: samples/psp-allow-privilege-escalation-container/update.yaml + assertions: + - violations: no diff --git a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/template.yaml b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/template.yaml new file mode 100644 index 000000000..52dd5da2c --- /dev/null +++ b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/template.yaml @@ -0,0 +1,129 @@ +apiVersion: templates.gatekeeper.sh/v1 +kind: ConstraintTemplate +metadata: + name: k8spspallowprivilegeescalationcontainer + annotations: + metadata.gatekeeper.sh/title: "Allow Privilege Escalation in Container" + metadata.gatekeeper.sh/version: 1.0.2 + description: >- + Controls restricting escalation to root privileges. Corresponds to the + `allowPrivilegeEscalation` field in a PodSecurityPolicy. For more + information, see + https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation +spec: + crd: + spec: + names: + kind: K8sPSPAllowPrivilegeEscalationContainer + validation: + openAPIV3Schema: + type: object + description: >- + Controls restricting escalation to root privileges. Corresponds to the + `allowPrivilegeEscalation` field in a PodSecurityPolicy. For more + information, see + https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation + properties: + exemptImages: + description: >- + Any container that uses an image that matches an entry in this list will be excluded + from enforcement. Prefix-matching can be signified with `*`. For example: `my-image-*`. + + It is recommended that users use the fully-qualified Docker image name (e.g. start with a domain name) + in order to avoid unexpectedly exempting images from an untrusted repository. + type: array + items: + type: string + targets: + - target: admission.k8s.gatekeeper.sh + code: + - engine: K8sNativeValidation + source: + variables: + - name: containers + expression: 'has(object.spec.containers) ? object.spec.containers : []' + - name: initContainers + expression: 'has(object.spec.initContainers) ? object.spec.initContainers : []' + - name: ephemeralContainers + expression: 'has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []' + - name: exemptImages + expression: | + !has(variables.params.exemptImages) ? [] : + (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, + // we can use the regex substitution because docker images do not allow "." as a valid character + variables.params.exemptImages.exists(exemption, container.image == exemption || (exemption.endsWith("*") && string(container.image).matches("^" + string(variables.params.exemptImages).replace("*", ".*") + "$"))) + ) + - name: badContainers + expression: | + (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, + !(container.image in variables.exemptImages) && ( + !has(container.securityContext) || + !has(container.securityContext.allowPrivilegeEscalation) || + container.securityContext.allowPrivilegeEscalation != false + ) + ) + validations: + - expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.badContainers) == 0' + messageExpression: '"Privilege escalation container is not allowed: " + variables.badContainers.map(c, c.image).join(", ")' + rego: | + package k8spspallowprivilegeescalationcontainer + + import data.lib.exclude_update.is_update + import data.lib.exempt_container.is_exempt + + violation[{"msg": msg, "details": {}}] { + # spec.containers.securityContext.allowPrivilegeEscalation field is immutable. + not is_update(input.review) + + c := input_containers[_] + not is_exempt(c) + input_allow_privilege_escalation(c) + msg := sprintf("Privilege escalation container is not allowed: %v", [c.name]) + } + + input_allow_privilege_escalation(c) { + not has_field(c, "securityContext") + } + input_allow_privilege_escalation(c) { + not c.securityContext.allowPrivilegeEscalation == false + } + input_containers[c] { + c := input.review.object.spec.containers[_] + } + input_containers[c] { + c := input.review.object.spec.initContainers[_] + } + input_containers[c] { + c := input.review.object.spec.ephemeralContainers[_] + } + # 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" + } + - | + package lib.exempt_container + + is_exempt(container) { + exempt_images := object.get(object.get(input, "parameters", {}), "exemptImages", []) + img := container.image + exemption := exempt_images[_] + _matches_exemption(img, exemption) + } + + _matches_exemption(img, exemption) { + not endswith(exemption, "*") + exemption == img + } + + _matches_exemption(img, exemption) { + endswith(exemption, "*") + prefix := trim_suffix(exemption, "*") + startswith(img, prefix) + } diff --git a/library/general/requiredlabels/template.yaml b/library/general/requiredlabels/template.yaml index aa865394c..1d6d23512 100644 --- a/library/general/requiredlabels/template.yaml +++ b/library/general/requiredlabels/template.yaml @@ -4,7 +4,7 @@ metadata: name: k8srequiredlabels annotations: metadata.gatekeeper.sh/title: "Required Labels" - metadata.gatekeeper.sh/version: 1.0.1 + metadata.gatekeeper.sh/version: 1.0.2 description: >- Requires resources to contain specified labels, with values matching provided regular expressions. @@ -38,6 +38,15 @@ spec: the regular expression. targets: - target: admission.k8s.gatekeeper.sh + code: + - engine: K8sNativeValidation + source: + + validations: + - expression: '[object, oldObject].exists(obj, obj != null && has(obj.metadata) && variables.params.labels.all(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels))' + messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' + - expression: '[object, oldObject].exists(obj, obj != null && !variables.params.labels.exists(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels && !string(obj.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' + message: "regex mismatch" rego: | package k8srequiredlabels diff --git a/library/pod-security-policy/allow-privilege-escalation/template.yaml b/library/pod-security-policy/allow-privilege-escalation/template.yaml index a7f4694a2..52dd5da2c 100644 --- a/library/pod-security-policy/allow-privilege-escalation/template.yaml +++ b/library/pod-security-policy/allow-privilege-escalation/template.yaml @@ -4,7 +4,7 @@ metadata: name: k8spspallowprivilegeescalationcontainer annotations: metadata.gatekeeper.sh/title: "Allow Privilege Escalation in Container" - metadata.gatekeeper.sh/version: 1.0.1 + metadata.gatekeeper.sh/version: 1.0.2 description: >- Controls restricting escalation to root privileges. Corresponds to the `allowPrivilegeEscalation` field in a PodSecurityPolicy. For more @@ -36,6 +36,35 @@ spec: type: string targets: - target: admission.k8s.gatekeeper.sh + code: + - engine: K8sNativeValidation + source: + variables: + - name: containers + expression: 'has(object.spec.containers) ? object.spec.containers : []' + - name: initContainers + expression: 'has(object.spec.initContainers) ? object.spec.initContainers : []' + - name: ephemeralContainers + expression: 'has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []' + - name: exemptImages + expression: | + !has(variables.params.exemptImages) ? [] : + (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, + // we can use the regex substitution because docker images do not allow "." as a valid character + variables.params.exemptImages.exists(exemption, container.image == exemption || (exemption.endsWith("*") && string(container.image).matches("^" + string(variables.params.exemptImages).replace("*", ".*") + "$"))) + ) + - name: badContainers + expression: | + (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, + !(container.image in variables.exemptImages) && ( + !has(container.securityContext) || + !has(container.securityContext.allowPrivilegeEscalation) || + container.securityContext.allowPrivilegeEscalation != false + ) + ) + validations: + - expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.badContainers) == 0' + messageExpression: '"Privilege escalation container is not allowed: " + variables.badContainers.map(c, c.image).join(", ")' rego: | package k8spspallowprivilegeescalationcontainer diff --git a/src/general/requiredlabels/constraint.tmpl b/src/general/requiredlabels/constraint.tmpl index 0e368a4be..2465a3b1a 100644 --- a/src/general/requiredlabels/constraint.tmpl +++ b/src/general/requiredlabels/constraint.tmpl @@ -4,7 +4,7 @@ metadata: name: k8srequiredlabels annotations: metadata.gatekeeper.sh/title: "Required Labels" - metadata.gatekeeper.sh/version: 1.0.1 + metadata.gatekeeper.sh/version: 1.0.2 description: >- Requires resources to contain specified labels, with values matching provided regular expressions. @@ -38,5 +38,9 @@ spec: the regular expression. targets: - target: admission.k8s.gatekeeper.sh + code: + - engine: K8sNativeValidation + source: +{{ file.Read "src/general/requiredlabels/src.cel" | strings.Indent 10 | strings.TrimSuffix "\n" }} rego: | {{ file.Read "src/general/requiredlabels/src.rego" | strings.Indent 8 | strings.TrimSuffix "\n" }} diff --git a/src/general/requiredlabels/src.cel b/src/general/requiredlabels/src.cel new file mode 100644 index 000000000..ae4ace21c --- /dev/null +++ b/src/general/requiredlabels/src.cel @@ -0,0 +1,6 @@ + + validations: + - expression: '[object, oldObject].exists(obj, obj != null && has(obj.metadata) && variables.params.labels.all(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels))' + messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' + - expression: '[object, oldObject].exists(obj, obj != null && !variables.params.labels.exists(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels && !string(obj.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' + message: "regex mismatch" \ No newline at end of file diff --git a/src/pod-security-policy/allow-privilege-escalation/constraint.tmpl b/src/pod-security-policy/allow-privilege-escalation/constraint.tmpl index e5f6f323f..bed6bd992 100644 --- a/src/pod-security-policy/allow-privilege-escalation/constraint.tmpl +++ b/src/pod-security-policy/allow-privilege-escalation/constraint.tmpl @@ -4,7 +4,7 @@ metadata: name: k8spspallowprivilegeescalationcontainer annotations: metadata.gatekeeper.sh/title: "Allow Privilege Escalation in Container" - metadata.gatekeeper.sh/version: 1.0.1 + metadata.gatekeeper.sh/version: 1.0.2 description: >- Controls restricting escalation to root privileges. Corresponds to the `allowPrivilegeEscalation` field in a PodSecurityPolicy. For more @@ -36,6 +36,10 @@ spec: type: string targets: - target: admission.k8s.gatekeeper.sh + code: + - engine: K8sNativeValidation + source: +{{ file.Read "src/pod-security-policy/allow-privilege-escalation/src.cel" | strings.Indent 10 | strings.TrimSuffix "\n" }} rego: | {{ file.Read "src/pod-security-policy/allow-privilege-escalation/src.rego" | strings.Indent 8 | strings.TrimSuffix "\n" }} libs: diff --git a/src/pod-security-policy/allow-privilege-escalation/src.cel b/src/pod-security-policy/allow-privilege-escalation/src.cel new file mode 100644 index 000000000..11c8c6b76 --- /dev/null +++ b/src/pod-security-policy/allow-privilege-escalation/src.cel @@ -0,0 +1,26 @@ +variables: +- name: containers + expression: 'has(object.spec.containers) ? object.spec.containers : []' +- name: initContainers + expression: 'has(object.spec.initContainers) ? object.spec.initContainers : []' +- name: ephemeralContainers + expression: 'has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []' +- name: exemptImages + expression: | + !has(variables.params.exemptImages) ? [] : + (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, + // we can use the regex substitution because docker images do not allow "." as a valid character + variables.params.exemptImages.exists(exemption, container.image == exemption || (exemption.endsWith("*") && string(container.image).matches("^" + string(variables.params.exemptImages).replace("*", ".*") + "$"))) + ) +- name: badContainers + expression: | + (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, + !(container.image in variables.exemptImages) && ( + !has(container.securityContext) || + !has(container.securityContext.allowPrivilegeEscalation) || + container.securityContext.allowPrivilegeEscalation != false + ) + ) +validations: +- expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.badContainers) == 0' + messageExpression: '"Privilege escalation container is not allowed: " + variables.badContainers.map(c, c.image).join(", ")' diff --git a/website/docs/validation/allow-privilege-escalation.md b/website/docs/validation/allow-privilege-escalation.md index fbb56a6b2..e19dfb7b9 100644 --- a/website/docs/validation/allow-privilege-escalation.md +++ b/website/docs/validation/allow-privilege-escalation.md @@ -16,7 +16,7 @@ metadata: name: k8spspallowprivilegeescalationcontainer annotations: metadata.gatekeeper.sh/title: "Allow Privilege Escalation in Container" - metadata.gatekeeper.sh/version: 1.0.1 + metadata.gatekeeper.sh/version: 1.0.2 description: >- Controls restricting escalation to root privileges. Corresponds to the `allowPrivilegeEscalation` field in a PodSecurityPolicy. For more @@ -48,6 +48,35 @@ spec: type: string targets: - target: admission.k8s.gatekeeper.sh + code: + - engine: K8sNativeValidation + source: + variables: + - name: containers + expression: 'has(object.spec.containers) ? object.spec.containers : []' + - name: initContainers + expression: 'has(object.spec.initContainers) ? object.spec.initContainers : []' + - name: ephemeralContainers + expression: 'has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []' + - name: exemptImages + expression: | + !has(variables.params.exemptImages) ? [] : + (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, + // we can use the regex substitution because docker images do not allow "." as a valid character + variables.params.exemptImages.exists(exemption, container.image == exemption || (exemption.endsWith("*") && string(container.image).matches("^" + string(variables.params.exemptImages).replace("*", ".*") + "$"))) + ) + - name: badContainers + expression: | + (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, + !(container.image in variables.exemptImages) && ( + !has(container.securityContext) || + !has(container.securityContext.allowPrivilegeEscalation) || + container.securityContext.allowPrivilegeEscalation != false + ) + ) + validations: + - expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.badContainers) == 0' + messageExpression: '"Privilege escalation container is not allowed: " + variables.badContainers.map(c, c.image).join(", ")' rego: | package k8spspallowprivilegeescalationcontainer diff --git a/website/docs/validation/requiredlabels.md b/website/docs/validation/requiredlabels.md index 4f6391aa1..5ef2e7032 100644 --- a/website/docs/validation/requiredlabels.md +++ b/website/docs/validation/requiredlabels.md @@ -16,7 +16,7 @@ metadata: name: k8srequiredlabels annotations: metadata.gatekeeper.sh/title: "Required Labels" - metadata.gatekeeper.sh/version: 1.0.1 + metadata.gatekeeper.sh/version: 1.0.2 description: >- Requires resources to contain specified labels, with values matching provided regular expressions. @@ -50,6 +50,15 @@ spec: the regular expression. targets: - target: admission.k8s.gatekeeper.sh + code: + - engine: K8sNativeValidation + source: + + validations: + - expression: '[object, oldObject].exists(obj, obj != null && has(obj.metadata) && variables.params.labels.all(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels))' + messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' + - expression: '[object, oldObject].exists(obj, obj != null && !variables.params.labels.exists(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels && !string(obj.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' + message: "regex mismatch" rego: | package k8srequiredlabels From aa12045fe390d7b451ab732c7313af92aa9793bb Mon Sep 17 00:00:00 2001 From: Jaydip Gabani Date: Thu, 2 May 2024 20:21:07 +0000 Subject: [PATCH 02/23] --set enableK8sNativeValidation=false for rego engine Signed-off-by: Jaydip Gabani --- Makefile | 6 +++--- .../library/general/requiredlabels/1.0.2/template.yaml | 10 +++++----- library/general/requiredlabels/template.yaml | 10 +++++----- src/general/requiredlabels/src.cel | 10 +++++----- website/docs/validation/requiredlabels.md | 10 +++++----- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/Makefile b/Makefile index 0d9c7cd13..417626eb1 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ integration-bootstrap: deploy: helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts ifeq ($(POLICY_ENGINE), rego) - helm install gatekeeper/gatekeeper --name-template=gatekeeper --namespace gatekeeper-system --create-namespace --version=${GATEKEEPER_VERSION} + helm install gatekeeper/gatekeeper --name-template=gatekeeper --namespace gatekeeper-system --create-namespace --version=${GATEKEEPER_VERSION} --set enableK8sNativeValidation=false else ifeq ($(POLICY_ENGINE), cel) helm install gatekeeper/gatekeeper --name-template=gatekeeper --namespace gatekeeper-system --create-namespace --version=${GATEKEEPER_VERSION} --set enableK8sNativeValidation=true endif @@ -48,7 +48,7 @@ test-integration: .PHONY: verify-gator verify-gator: ifeq ($(POLICY_ENGINE), rego) - gator verify ./... + gator verify ./... --experimental-enable-k8s-native-validation=false else ifeq ($(POLICY_ENGINE), cel) gator verify ./... --experimental-enable-k8s-native-validation=true endif @@ -56,7 +56,7 @@ endif .PHONY: verify-gator-dockerized verify-gator-dockerized: __build-gator ifeq ($(POLICY_ENGINE), rego) - $(docker) run -i -v $(shell pwd):/gatekeeper-library gator-container verify ./... + $(docker) run -i -v $(shell pwd):/gatekeeper-library gator-container verify ./... --experimental-enable-k8s-native-validation=false else ifeq ($(POLICY_ENGINE), cel) $(docker) run -i -v $(shell pwd):/gatekeeper-library gator-container verify ./... --experimental-enable-k8s-native-validation=true endif diff --git a/artifacthub/library/general/requiredlabels/1.0.2/template.yaml b/artifacthub/library/general/requiredlabels/1.0.2/template.yaml index 1d6d23512..93fda191d 100644 --- a/artifacthub/library/general/requiredlabels/1.0.2/template.yaml +++ b/artifacthub/library/general/requiredlabels/1.0.2/template.yaml @@ -42,11 +42,11 @@ spec: - engine: K8sNativeValidation source: - validations: - - expression: '[object, oldObject].exists(obj, obj != null && has(obj.metadata) && variables.params.labels.all(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels))' - messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' - - expression: '[object, oldObject].exists(obj, obj != null && !variables.params.labels.exists(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels && !string(obj.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' - message: "regex mismatch" + validations: + - expression: '[object, oldObject].exists(obj, obj != null && has(obj.metadata) && variables.params.labels.all(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels))' + messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' + - expression: '[object, oldObject].exists(obj, obj != null && !variables.params.labels.exists(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels && !string(obj.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' + message: "regex mismatch" rego: | package k8srequiredlabels diff --git a/library/general/requiredlabels/template.yaml b/library/general/requiredlabels/template.yaml index 1d6d23512..93fda191d 100644 --- a/library/general/requiredlabels/template.yaml +++ b/library/general/requiredlabels/template.yaml @@ -42,11 +42,11 @@ spec: - engine: K8sNativeValidation source: - validations: - - expression: '[object, oldObject].exists(obj, obj != null && has(obj.metadata) && variables.params.labels.all(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels))' - messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' - - expression: '[object, oldObject].exists(obj, obj != null && !variables.params.labels.exists(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels && !string(obj.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' - message: "regex mismatch" + validations: + - expression: '[object, oldObject].exists(obj, obj != null && has(obj.metadata) && variables.params.labels.all(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels))' + messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' + - expression: '[object, oldObject].exists(obj, obj != null && !variables.params.labels.exists(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels && !string(obj.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' + message: "regex mismatch" rego: | package k8srequiredlabels diff --git a/src/general/requiredlabels/src.cel b/src/general/requiredlabels/src.cel index ae4ace21c..c66052f2e 100644 --- a/src/general/requiredlabels/src.cel +++ b/src/general/requiredlabels/src.cel @@ -1,6 +1,6 @@ - validations: - - expression: '[object, oldObject].exists(obj, obj != null && has(obj.metadata) && variables.params.labels.all(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels))' - messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' - - expression: '[object, oldObject].exists(obj, obj != null && !variables.params.labels.exists(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels && !string(obj.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' - message: "regex mismatch" \ No newline at end of file +validations: +- expression: '[object, oldObject].exists(obj, obj != null && has(obj.metadata) && variables.params.labels.all(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels))' + messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' +- expression: '[object, oldObject].exists(obj, obj != null && !variables.params.labels.exists(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels && !string(obj.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' + message: "regex mismatch" \ No newline at end of file diff --git a/website/docs/validation/requiredlabels.md b/website/docs/validation/requiredlabels.md index 5ef2e7032..7aba68a83 100644 --- a/website/docs/validation/requiredlabels.md +++ b/website/docs/validation/requiredlabels.md @@ -54,11 +54,11 @@ spec: - engine: K8sNativeValidation source: - validations: - - expression: '[object, oldObject].exists(obj, obj != null && has(obj.metadata) && variables.params.labels.all(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels))' - messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' - - expression: '[object, oldObject].exists(obj, obj != null && !variables.params.labels.exists(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels && !string(obj.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' - message: "regex mismatch" + validations: + - expression: '[object, oldObject].exists(obj, obj != null && has(obj.metadata) && variables.params.labels.all(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels))' + messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' + - expression: '[object, oldObject].exists(obj, obj != null && !variables.params.labels.exists(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels && !string(obj.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' + message: "regex mismatch" rego: | package k8srequiredlabels From 67b246f66c62d53ac9f1b117d9e71f3389f17e38 Mon Sep 17 00:00:00 2001 From: Jaydip Gabani Date: Thu, 2 May 2024 20:36:11 +0000 Subject: [PATCH 03/23] fixing uploading artifacts in ci Signed-off-by: Jaydip Gabani --- .github/workflows/workflow.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workflow.yaml b/.github/workflows/workflow.yaml index 70c18f7b0..fbc6ac533 100644 --- a/.github/workflows/workflow.yaml +++ b/.github/workflows/workflow.yaml @@ -97,7 +97,7 @@ jobs: uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 if: ${{ always() }} with: - name: logs-int-test-${{ matrix.gatekeeper }} + name: logs-int-test-${{ matrix.gatekeeper }}-${{ matrix.engine }} path: | logs-*.json require_suites: From 1a4e6d1e6df0ca8855f66b46ac5dee47575ad65d Mon Sep 17 00:00:00 2001 From: Jaydip Gabani Date: Thu, 2 May 2024 22:22:30 +0000 Subject: [PATCH 04/23] removing blank line Signed-off-by: Jaydip Gabani --- artifacthub/library/general/requiredlabels/1.0.2/template.yaml | 1 - library/general/requiredlabels/template.yaml | 1 - src/general/requiredlabels/src.cel | 3 +-- website/docs/validation/requiredlabels.md | 1 - 4 files changed, 1 insertion(+), 5 deletions(-) diff --git a/artifacthub/library/general/requiredlabels/1.0.2/template.yaml b/artifacthub/library/general/requiredlabels/1.0.2/template.yaml index 93fda191d..14aa8d9d2 100644 --- a/artifacthub/library/general/requiredlabels/1.0.2/template.yaml +++ b/artifacthub/library/general/requiredlabels/1.0.2/template.yaml @@ -41,7 +41,6 @@ spec: code: - engine: K8sNativeValidation source: - validations: - expression: '[object, oldObject].exists(obj, obj != null && has(obj.metadata) && variables.params.labels.all(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels))' messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' diff --git a/library/general/requiredlabels/template.yaml b/library/general/requiredlabels/template.yaml index 93fda191d..14aa8d9d2 100644 --- a/library/general/requiredlabels/template.yaml +++ b/library/general/requiredlabels/template.yaml @@ -41,7 +41,6 @@ spec: code: - engine: K8sNativeValidation source: - validations: - expression: '[object, oldObject].exists(obj, obj != null && has(obj.metadata) && variables.params.labels.all(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels))' messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' diff --git a/src/general/requiredlabels/src.cel b/src/general/requiredlabels/src.cel index c66052f2e..eefb48361 100644 --- a/src/general/requiredlabels/src.cel +++ b/src/general/requiredlabels/src.cel @@ -1,6 +1,5 @@ - validations: - expression: '[object, oldObject].exists(obj, obj != null && has(obj.metadata) && variables.params.labels.all(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels))' messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' - expression: '[object, oldObject].exists(obj, obj != null && !variables.params.labels.exists(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels && !string(obj.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' - message: "regex mismatch" \ No newline at end of file + message: "regex mismatch" diff --git a/website/docs/validation/requiredlabels.md b/website/docs/validation/requiredlabels.md index 7aba68a83..2b7182f21 100644 --- a/website/docs/validation/requiredlabels.md +++ b/website/docs/validation/requiredlabels.md @@ -53,7 +53,6 @@ spec: code: - engine: K8sNativeValidation source: - validations: - expression: '[object, oldObject].exists(obj, obj != null && has(obj.metadata) && variables.params.labels.all(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels))' messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' From 120407b8716d1c9807125b9adc890ac8b44cf1aa Mon Sep 17 00:00:00 2001 From: Jaydip Gabani Date: Fri, 3 May 2024 19:33:23 +0000 Subject: [PATCH 05/23] adding engine rego Signed-off-by: Jaydip Gabani --- library/general/requiredlabels/template.yaml | 50 ++++---- .../allow-privilege-escalation/template.yaml | 110 +++++++++--------- src/general/requiredlabels/constraint.tmpl | 6 +- .../constraint.tmpl | 16 +-- 4 files changed, 95 insertions(+), 87 deletions(-) diff --git a/library/general/requiredlabels/template.yaml b/library/general/requiredlabels/template.yaml index 14aa8d9d2..aa467438d 100644 --- a/library/general/requiredlabels/template.yaml +++ b/library/general/requiredlabels/template.yaml @@ -46,31 +46,33 @@ spec: messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' - expression: '[object, oldObject].exists(obj, obj != null && !variables.params.labels.exists(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels && !string(obj.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' message: "regex mismatch" - rego: | - package k8srequiredlabels + - engine: Rego + source: + rego: | + package k8srequiredlabels - get_message(parameters, _default) := _default { - not parameters.message - } + get_message(parameters, _default) := _default { + not parameters.message + } - get_message(parameters, _) := parameters.message + get_message(parameters, _) := parameters.message - violation[{"msg": msg, "details": {"missing_labels": missing}}] { - provided := {label | input.review.object.metadata.labels[label]} - required := {label | label := input.parameters.labels[_].key} - missing := required - provided - count(missing) > 0 - def_msg := sprintf("you must provide labels: %v", [missing]) - msg := get_message(input.parameters, def_msg) - } + violation[{"msg": msg, "details": {"missing_labels": missing}}] { + provided := {label | input.review.object.metadata.labels[label]} + required := {label | label := input.parameters.labels[_].key} + missing := required - provided + count(missing) > 0 + def_msg := sprintf("you must provide labels: %v", [missing]) + msg := get_message(input.parameters, def_msg) + } - violation[{"msg": msg}] { - value := input.review.object.metadata.labels[key] - expected := input.parameters.labels[_] - expected.key == key - # do not match if allowedRegex is not defined, or is an empty string - expected.allowedRegex != "" - not regex.match(expected.allowedRegex, value) - def_msg := sprintf("Label <%v: %v> does not satisfy allowed regex: %v", [key, value, expected.allowedRegex]) - msg := get_message(input.parameters, def_msg) - } + violation[{"msg": msg}] { + value := input.review.object.metadata.labels[key] + expected := input.parameters.labels[_] + expected.key == key + # do not match if allowedRegex is not defined, or is an empty string + expected.allowedRegex != "" + not regex.match(expected.allowedRegex, value) + def_msg := sprintf("Label <%v: %v> does not satisfy allowed regex: %v", [key, value, expected.allowedRegex]) + msg := get_message(input.parameters, def_msg) + } diff --git a/library/pod-security-policy/allow-privilege-escalation/template.yaml b/library/pod-security-policy/allow-privilege-escalation/template.yaml index 52dd5da2c..c25cd5e28 100644 --- a/library/pod-security-policy/allow-privilege-escalation/template.yaml +++ b/library/pod-security-policy/allow-privilege-escalation/template.yaml @@ -65,65 +65,67 @@ spec: validations: - expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.badContainers) == 0' messageExpression: '"Privilege escalation container is not allowed: " + variables.badContainers.map(c, c.image).join(", ")' - rego: | - package k8spspallowprivilegeescalationcontainer + - engine: Rego + source: + rego: | + package k8spspallowprivilegeescalationcontainer - import data.lib.exclude_update.is_update - import data.lib.exempt_container.is_exempt + import data.lib.exclude_update.is_update + import data.lib.exempt_container.is_exempt - violation[{"msg": msg, "details": {}}] { - # spec.containers.securityContext.allowPrivilegeEscalation field is immutable. - not is_update(input.review) + violation[{"msg": msg, "details": {}}] { + # spec.containers.securityContext.allowPrivilegeEscalation field is immutable. + not is_update(input.review) - c := input_containers[_] - not is_exempt(c) - input_allow_privilege_escalation(c) - msg := sprintf("Privilege escalation container is not allowed: %v", [c.name]) - } + c := input_containers[_] + not is_exempt(c) + input_allow_privilege_escalation(c) + msg := sprintf("Privilege escalation container is not allowed: %v", [c.name]) + } - input_allow_privilege_escalation(c) { - not has_field(c, "securityContext") - } - input_allow_privilege_escalation(c) { - not c.securityContext.allowPrivilegeEscalation == false - } - input_containers[c] { - c := input.review.object.spec.containers[_] - } - input_containers[c] { - c := input.review.object.spec.initContainers[_] - } - input_containers[c] { - c := input.review.object.spec.ephemeralContainers[_] - } - # has_field returns whether an object has a field - has_field(object, field) = true { - object[field] - } - libs: - - | - package lib.exclude_update + input_allow_privilege_escalation(c) { + not has_field(c, "securityContext") + } + input_allow_privilege_escalation(c) { + not c.securityContext.allowPrivilegeEscalation == false + } + input_containers[c] { + c := input.review.object.spec.containers[_] + } + input_containers[c] { + c := input.review.object.spec.initContainers[_] + } + input_containers[c] { + c := input.review.object.spec.ephemeralContainers[_] + } + # 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" - } - - | - package lib.exempt_container + is_update(review) { + review.operation == "UPDATE" + } + - | + package lib.exempt_container - is_exempt(container) { - exempt_images := object.get(object.get(input, "parameters", {}), "exemptImages", []) - img := container.image - exemption := exempt_images[_] - _matches_exemption(img, exemption) - } + is_exempt(container) { + exempt_images := object.get(object.get(input, "parameters", {}), "exemptImages", []) + img := container.image + exemption := exempt_images[_] + _matches_exemption(img, exemption) + } - _matches_exemption(img, exemption) { - not endswith(exemption, "*") - exemption == img - } + _matches_exemption(img, exemption) { + not endswith(exemption, "*") + exemption == img + } - _matches_exemption(img, exemption) { - endswith(exemption, "*") - prefix := trim_suffix(exemption, "*") - startswith(img, prefix) - } + _matches_exemption(img, exemption) { + endswith(exemption, "*") + prefix := trim_suffix(exemption, "*") + startswith(img, prefix) + } diff --git a/src/general/requiredlabels/constraint.tmpl b/src/general/requiredlabels/constraint.tmpl index 2465a3b1a..34815bbf7 100644 --- a/src/general/requiredlabels/constraint.tmpl +++ b/src/general/requiredlabels/constraint.tmpl @@ -42,5 +42,7 @@ spec: - engine: K8sNativeValidation source: {{ file.Read "src/general/requiredlabels/src.cel" | strings.Indent 10 | strings.TrimSuffix "\n" }} - rego: | -{{ file.Read "src/general/requiredlabels/src.rego" | strings.Indent 8 | strings.TrimSuffix "\n" }} + - engine: Rego + source: + rego: | +{{ file.Read "src/general/requiredlabels/src.rego" | strings.Indent 12 | strings.TrimSuffix "\n" }} diff --git a/src/pod-security-policy/allow-privilege-escalation/constraint.tmpl b/src/pod-security-policy/allow-privilege-escalation/constraint.tmpl index bed6bd992..f18c91bd4 100644 --- a/src/pod-security-policy/allow-privilege-escalation/constraint.tmpl +++ b/src/pod-security-policy/allow-privilege-escalation/constraint.tmpl @@ -40,10 +40,12 @@ spec: - engine: K8sNativeValidation source: {{ file.Read "src/pod-security-policy/allow-privilege-escalation/src.cel" | strings.Indent 10 | strings.TrimSuffix "\n" }} - rego: | -{{ file.Read "src/pod-security-policy/allow-privilege-escalation/src.rego" | strings.Indent 8 | strings.TrimSuffix "\n" }} - libs: - - | -{{ file.Read "src/pod-security-policy/allow-privilege-escalation/lib_exclude_update.rego" | strings.Indent 10 | strings.TrimSuffix "\n" }} - - | -{{ file.Read "src/pod-security-policy/allow-privilege-escalation/lib_exempt_container.rego" | strings.Indent 10 | strings.TrimSuffix "\n" }} + - engine: Rego + source: + rego: | +{{ file.Read "src/pod-security-policy/allow-privilege-escalation/src.rego" | strings.Indent 12 | strings.TrimSuffix "\n" }} + libs: + - | +{{ file.Read "src/pod-security-policy/allow-privilege-escalation/lib_exclude_update.rego" | strings.Indent 14 | strings.TrimSuffix "\n" }} + - | +{{ file.Read "src/pod-security-policy/allow-privilege-escalation/lib_exempt_container.rego" | strings.Indent 14 | strings.TrimSuffix "\n" }} From be18548d704259850f363ac9620ad659b4162fb6 Mon Sep 17 00:00:00 2001 From: Jaydip Gabani Date: Fri, 3 May 2024 19:36:11 +0000 Subject: [PATCH 06/23] adding engine rego Signed-off-by: Jaydip Gabani --- .../requiredlabels/1.0.2/artifacthub-pkg.yml | 2 +- .../requiredlabels/1.0.2/template.yaml | 50 +++---- .../1.0.2/artifacthub-pkg.yml | 2 +- .../1.0.2/template.yaml | 110 +++++++-------- .../validation/allow-privilege-escalation.md | 126 +++++++++--------- website/docs/validation/requiredlabels.md | 58 ++++---- 6 files changed, 178 insertions(+), 170 deletions(-) diff --git a/artifacthub/library/general/requiredlabels/1.0.2/artifacthub-pkg.yml b/artifacthub/library/general/requiredlabels/1.0.2/artifacthub-pkg.yml index 1d68967ee..20e43726c 100644 --- a/artifacthub/library/general/requiredlabels/1.0.2/artifacthub-pkg.yml +++ b/artifacthub/library/general/requiredlabels/1.0.2/artifacthub-pkg.yml @@ -3,7 +3,7 @@ name: k8srequiredlabels displayName: Required Labels createdAt: "2024-05-02T19:01:02Z" description: Requires resources to contain specified labels, with values matching provided regular expressions. -digest: e41978589a21f07237a098331543f99ede07098acac8d80a4d44cc050a1ad618 +digest: cdb14cb125780aa34641e23998403049748d74bf78239382e959cc844ed0d15e license: Apache-2.0 homeURL: https://open-policy-agent.github.io/gatekeeper-library/website/requiredlabels keywords: diff --git a/artifacthub/library/general/requiredlabels/1.0.2/template.yaml b/artifacthub/library/general/requiredlabels/1.0.2/template.yaml index 14aa8d9d2..aa467438d 100644 --- a/artifacthub/library/general/requiredlabels/1.0.2/template.yaml +++ b/artifacthub/library/general/requiredlabels/1.0.2/template.yaml @@ -46,31 +46,33 @@ spec: messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' - expression: '[object, oldObject].exists(obj, obj != null && !variables.params.labels.exists(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels && !string(obj.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' message: "regex mismatch" - rego: | - package k8srequiredlabels + - engine: Rego + source: + rego: | + package k8srequiredlabels - get_message(parameters, _default) := _default { - not parameters.message - } + get_message(parameters, _default) := _default { + not parameters.message + } - get_message(parameters, _) := parameters.message + get_message(parameters, _) := parameters.message - violation[{"msg": msg, "details": {"missing_labels": missing}}] { - provided := {label | input.review.object.metadata.labels[label]} - required := {label | label := input.parameters.labels[_].key} - missing := required - provided - count(missing) > 0 - def_msg := sprintf("you must provide labels: %v", [missing]) - msg := get_message(input.parameters, def_msg) - } + violation[{"msg": msg, "details": {"missing_labels": missing}}] { + provided := {label | input.review.object.metadata.labels[label]} + required := {label | label := input.parameters.labels[_].key} + missing := required - provided + count(missing) > 0 + def_msg := sprintf("you must provide labels: %v", [missing]) + msg := get_message(input.parameters, def_msg) + } - violation[{"msg": msg}] { - value := input.review.object.metadata.labels[key] - expected := input.parameters.labels[_] - expected.key == key - # do not match if allowedRegex is not defined, or is an empty string - expected.allowedRegex != "" - not regex.match(expected.allowedRegex, value) - def_msg := sprintf("Label <%v: %v> does not satisfy allowed regex: %v", [key, value, expected.allowedRegex]) - msg := get_message(input.parameters, def_msg) - } + violation[{"msg": msg}] { + value := input.review.object.metadata.labels[key] + expected := input.parameters.labels[_] + expected.key == key + # do not match if allowedRegex is not defined, or is an empty string + expected.allowedRegex != "" + not regex.match(expected.allowedRegex, value) + def_msg := sprintf("Label <%v: %v> does not satisfy allowed regex: %v", [key, value, expected.allowedRegex]) + msg := get_message(input.parameters, def_msg) + } diff --git a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/artifacthub-pkg.yml b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/artifacthub-pkg.yml index b1f227992..260f49154 100644 --- a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/artifacthub-pkg.yml +++ b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/artifacthub-pkg.yml @@ -3,7 +3,7 @@ name: k8spspallowprivilegeescalationcontainer displayName: Allow Privilege Escalation in Container createdAt: "2024-05-02T19:01:02Z" description: Controls restricting escalation to root privileges. Corresponds to the `allowPrivilegeEscalation` field in a PodSecurityPolicy. For more information, see https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation -digest: 64107d0d609554fcc6740d2a2c45bd5d221c1eedaaaee3a409aec827aa196a64 +digest: 13c36cccfca382be8eed58e9bec65a4ba93d061480a3c085a17ca68aed804ac6 license: Apache-2.0 homeURL: https://open-policy-agent.github.io/gatekeeper-library/website/allow-privilege-escalation keywords: diff --git a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/template.yaml b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/template.yaml index 52dd5da2c..c25cd5e28 100644 --- a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/template.yaml +++ b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/template.yaml @@ -65,65 +65,67 @@ spec: validations: - expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.badContainers) == 0' messageExpression: '"Privilege escalation container is not allowed: " + variables.badContainers.map(c, c.image).join(", ")' - rego: | - package k8spspallowprivilegeescalationcontainer + - engine: Rego + source: + rego: | + package k8spspallowprivilegeescalationcontainer - import data.lib.exclude_update.is_update - import data.lib.exempt_container.is_exempt + import data.lib.exclude_update.is_update + import data.lib.exempt_container.is_exempt - violation[{"msg": msg, "details": {}}] { - # spec.containers.securityContext.allowPrivilegeEscalation field is immutable. - not is_update(input.review) + violation[{"msg": msg, "details": {}}] { + # spec.containers.securityContext.allowPrivilegeEscalation field is immutable. + not is_update(input.review) - c := input_containers[_] - not is_exempt(c) - input_allow_privilege_escalation(c) - msg := sprintf("Privilege escalation container is not allowed: %v", [c.name]) - } + c := input_containers[_] + not is_exempt(c) + input_allow_privilege_escalation(c) + msg := sprintf("Privilege escalation container is not allowed: %v", [c.name]) + } - input_allow_privilege_escalation(c) { - not has_field(c, "securityContext") - } - input_allow_privilege_escalation(c) { - not c.securityContext.allowPrivilegeEscalation == false - } - input_containers[c] { - c := input.review.object.spec.containers[_] - } - input_containers[c] { - c := input.review.object.spec.initContainers[_] - } - input_containers[c] { - c := input.review.object.spec.ephemeralContainers[_] - } - # has_field returns whether an object has a field - has_field(object, field) = true { - object[field] - } - libs: - - | - package lib.exclude_update + input_allow_privilege_escalation(c) { + not has_field(c, "securityContext") + } + input_allow_privilege_escalation(c) { + not c.securityContext.allowPrivilegeEscalation == false + } + input_containers[c] { + c := input.review.object.spec.containers[_] + } + input_containers[c] { + c := input.review.object.spec.initContainers[_] + } + input_containers[c] { + c := input.review.object.spec.ephemeralContainers[_] + } + # 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" - } - - | - package lib.exempt_container + is_update(review) { + review.operation == "UPDATE" + } + - | + package lib.exempt_container - is_exempt(container) { - exempt_images := object.get(object.get(input, "parameters", {}), "exemptImages", []) - img := container.image - exemption := exempt_images[_] - _matches_exemption(img, exemption) - } + is_exempt(container) { + exempt_images := object.get(object.get(input, "parameters", {}), "exemptImages", []) + img := container.image + exemption := exempt_images[_] + _matches_exemption(img, exemption) + } - _matches_exemption(img, exemption) { - not endswith(exemption, "*") - exemption == img - } + _matches_exemption(img, exemption) { + not endswith(exemption, "*") + exemption == img + } - _matches_exemption(img, exemption) { - endswith(exemption, "*") - prefix := trim_suffix(exemption, "*") - startswith(img, prefix) - } + _matches_exemption(img, exemption) { + endswith(exemption, "*") + prefix := trim_suffix(exemption, "*") + startswith(img, prefix) + } diff --git a/website/docs/validation/allow-privilege-escalation.md b/website/docs/validation/allow-privilege-escalation.md index e19dfb7b9..7a0c3820a 100644 --- a/website/docs/validation/allow-privilege-escalation.md +++ b/website/docs/validation/allow-privilege-escalation.md @@ -77,68 +77,70 @@ spec: validations: - expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.badContainers) == 0' messageExpression: '"Privilege escalation container is not allowed: " + variables.badContainers.map(c, c.image).join(", ")' - rego: | - package k8spspallowprivilegeescalationcontainer - - import data.lib.exclude_update.is_update - import data.lib.exempt_container.is_exempt - - violation[{"msg": msg, "details": {}}] { - # spec.containers.securityContext.allowPrivilegeEscalation field is immutable. - not is_update(input.review) - - c := input_containers[_] - not is_exempt(c) - input_allow_privilege_escalation(c) - msg := sprintf("Privilege escalation container is not allowed: %v", [c.name]) - } - - input_allow_privilege_escalation(c) { - not has_field(c, "securityContext") - } - input_allow_privilege_escalation(c) { - not c.securityContext.allowPrivilegeEscalation == false - } - input_containers[c] { - c := input.review.object.spec.containers[_] - } - input_containers[c] { - c := input.review.object.spec.initContainers[_] - } - input_containers[c] { - c := input.review.object.spec.ephemeralContainers[_] - } - # 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" - } - - | - package lib.exempt_container - - is_exempt(container) { - exempt_images := object.get(object.get(input, "parameters", {}), "exemptImages", []) - img := container.image - exemption := exempt_images[_] - _matches_exemption(img, exemption) - } - - _matches_exemption(img, exemption) { - not endswith(exemption, "*") - exemption == img - } - - _matches_exemption(img, exemption) { - endswith(exemption, "*") - prefix := trim_suffix(exemption, "*") - startswith(img, prefix) - } + - engine: Rego + source: + rego: | + package k8spspallowprivilegeescalationcontainer + + import data.lib.exclude_update.is_update + import data.lib.exempt_container.is_exempt + + violation[{"msg": msg, "details": {}}] { + # spec.containers.securityContext.allowPrivilegeEscalation field is immutable. + not is_update(input.review) + + c := input_containers[_] + not is_exempt(c) + input_allow_privilege_escalation(c) + msg := sprintf("Privilege escalation container is not allowed: %v", [c.name]) + } + + input_allow_privilege_escalation(c) { + not has_field(c, "securityContext") + } + input_allow_privilege_escalation(c) { + not c.securityContext.allowPrivilegeEscalation == false + } + input_containers[c] { + c := input.review.object.spec.containers[_] + } + input_containers[c] { + c := input.review.object.spec.initContainers[_] + } + input_containers[c] { + c := input.review.object.spec.ephemeralContainers[_] + } + # 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" + } + - | + package lib.exempt_container + + is_exempt(container) { + exempt_images := object.get(object.get(input, "parameters", {}), "exemptImages", []) + img := container.image + exemption := exempt_images[_] + _matches_exemption(img, exemption) + } + + _matches_exemption(img, exemption) { + not endswith(exemption, "*") + exemption == img + } + + _matches_exemption(img, exemption) { + endswith(exemption, "*") + prefix := trim_suffix(exemption, "*") + startswith(img, prefix) + } ``` diff --git a/website/docs/validation/requiredlabels.md b/website/docs/validation/requiredlabels.md index 2b7182f21..8246746fa 100644 --- a/website/docs/validation/requiredlabels.md +++ b/website/docs/validation/requiredlabels.md @@ -58,34 +58,36 @@ spec: messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' - expression: '[object, oldObject].exists(obj, obj != null && !variables.params.labels.exists(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels && !string(obj.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' message: "regex mismatch" - rego: | - package k8srequiredlabels - - get_message(parameters, _default) := _default { - not parameters.message - } - - get_message(parameters, _) := parameters.message - - violation[{"msg": msg, "details": {"missing_labels": missing}}] { - provided := {label | input.review.object.metadata.labels[label]} - required := {label | label := input.parameters.labels[_].key} - missing := required - provided - count(missing) > 0 - def_msg := sprintf("you must provide labels: %v", [missing]) - msg := get_message(input.parameters, def_msg) - } - - violation[{"msg": msg}] { - value := input.review.object.metadata.labels[key] - expected := input.parameters.labels[_] - expected.key == key - # do not match if allowedRegex is not defined, or is an empty string - expected.allowedRegex != "" - not regex.match(expected.allowedRegex, value) - def_msg := sprintf("Label <%v: %v> does not satisfy allowed regex: %v", [key, value, expected.allowedRegex]) - msg := get_message(input.parameters, def_msg) - } + - engine: Rego + source: + rego: | + package k8srequiredlabels + + get_message(parameters, _default) := _default { + not parameters.message + } + + get_message(parameters, _) := parameters.message + + violation[{"msg": msg, "details": {"missing_labels": missing}}] { + provided := {label | input.review.object.metadata.labels[label]} + required := {label | label := input.parameters.labels[_].key} + missing := required - provided + count(missing) > 0 + def_msg := sprintf("you must provide labels: %v", [missing]) + msg := get_message(input.parameters, def_msg) + } + + violation[{"msg": msg}] { + value := input.review.object.metadata.labels[key] + expected := input.parameters.labels[_] + expected.key == key + # do not match if allowedRegex is not defined, or is an empty string + expected.allowedRegex != "" + not regex.match(expected.allowedRegex, value) + def_msg := sprintf("Label <%v: %v> does not satisfy allowed regex: %v", [key, value, expected.allowedRegex]) + msg := get_message(input.parameters, def_msg) + } ``` From bf316d9ecb8a8283acaec1b508475963da1afd83 Mon Sep 17 00:00:00 2001 From: Jaydip Gabani Date: Mon, 6 May 2024 17:37:48 +0000 Subject: [PATCH 07/23] correcting required label cel policy Signed-off-by: Jaydip Gabani --- .../library/general/requiredlabels/1.0.2/artifacthub-pkg.yml | 2 +- .../library/general/requiredlabels/1.0.2/template.yaml | 4 ++-- library/general/requiredlabels/template.yaml | 4 ++-- src/general/requiredlabels/src.cel | 4 ++-- website/docs/validation/requiredlabels.md | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/artifacthub/library/general/requiredlabels/1.0.2/artifacthub-pkg.yml b/artifacthub/library/general/requiredlabels/1.0.2/artifacthub-pkg.yml index 20e43726c..264a51589 100644 --- a/artifacthub/library/general/requiredlabels/1.0.2/artifacthub-pkg.yml +++ b/artifacthub/library/general/requiredlabels/1.0.2/artifacthub-pkg.yml @@ -3,7 +3,7 @@ name: k8srequiredlabels displayName: Required Labels createdAt: "2024-05-02T19:01:02Z" description: Requires resources to contain specified labels, with values matching provided regular expressions. -digest: cdb14cb125780aa34641e23998403049748d74bf78239382e959cc844ed0d15e +digest: 46e3f6b92f1aab8f8257407a51a3df1aba697bd83d90d5dfc8f00493886ea4eb license: Apache-2.0 homeURL: https://open-policy-agent.github.io/gatekeeper-library/website/requiredlabels keywords: diff --git a/artifacthub/library/general/requiredlabels/1.0.2/template.yaml b/artifacthub/library/general/requiredlabels/1.0.2/template.yaml index aa467438d..5a9d2cb07 100644 --- a/artifacthub/library/general/requiredlabels/1.0.2/template.yaml +++ b/artifacthub/library/general/requiredlabels/1.0.2/template.yaml @@ -42,8 +42,8 @@ spec: - engine: K8sNativeValidation source: validations: - - expression: '[object, oldObject].exists(obj, obj != null && has(obj.metadata) && variables.params.labels.all(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels))' - messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' + - expression: '(has(request.operation) && request.operation == "DELETE") ||(has(object.metadata) && variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels))' + messageExpression: '"object missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' - expression: '[object, oldObject].exists(obj, obj != null && !variables.params.labels.exists(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels && !string(obj.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' message: "regex mismatch" - engine: Rego diff --git a/library/general/requiredlabels/template.yaml b/library/general/requiredlabels/template.yaml index aa467438d..5a9d2cb07 100644 --- a/library/general/requiredlabels/template.yaml +++ b/library/general/requiredlabels/template.yaml @@ -42,8 +42,8 @@ spec: - engine: K8sNativeValidation source: validations: - - expression: '[object, oldObject].exists(obj, obj != null && has(obj.metadata) && variables.params.labels.all(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels))' - messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' + - expression: '(has(request.operation) && request.operation == "DELETE") ||(has(object.metadata) && variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels))' + messageExpression: '"object missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' - expression: '[object, oldObject].exists(obj, obj != null && !variables.params.labels.exists(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels && !string(obj.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' message: "regex mismatch" - engine: Rego diff --git a/src/general/requiredlabels/src.cel b/src/general/requiredlabels/src.cel index eefb48361..be8e2a700 100644 --- a/src/general/requiredlabels/src.cel +++ b/src/general/requiredlabels/src.cel @@ -1,5 +1,5 @@ validations: -- expression: '[object, oldObject].exists(obj, obj != null && has(obj.metadata) && variables.params.labels.all(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels))' - messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' +- expression: '(has(request.operation) && request.operation == "DELETE") ||(has(object.metadata) && variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels))' + messageExpression: '"object missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' - expression: '[object, oldObject].exists(obj, obj != null && !variables.params.labels.exists(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels && !string(obj.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' message: "regex mismatch" diff --git a/website/docs/validation/requiredlabels.md b/website/docs/validation/requiredlabels.md index 8246746fa..3635b0884 100644 --- a/website/docs/validation/requiredlabels.md +++ b/website/docs/validation/requiredlabels.md @@ -54,8 +54,8 @@ spec: - engine: K8sNativeValidation source: validations: - - expression: '[object, oldObject].exists(obj, obj != null && has(obj.metadata) && variables.params.labels.all(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels))' - messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' + - expression: '(has(request.operation) && request.operation == "DELETE") ||(has(object.metadata) && variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels))' + messageExpression: '"object missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' - expression: '[object, oldObject].exists(obj, obj != null && !variables.params.labels.exists(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels && !string(obj.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' message: "regex mismatch" - engine: Rego From 45e9b6afa94ffdb98a1517a5deaf94a473ad95bb Mon Sep 17 00:00:00 2001 From: Jaydip Gabani Date: Wed, 8 May 2024 19:47:35 +0000 Subject: [PATCH 08/23] removing CEL from policies Signed-off-by: Jaydip Gabani --- .../requiredlabels/1.0.2/artifacthub-pkg.yml | 2 +- .../requiredlabels/1.0.2/template.yaml | 7 ----- .../1.0.2/artifacthub-pkg.yml | 2 +- .../1.0.2/template.yaml | 28 ------------------- library/general/requiredlabels/template.yaml | 7 ----- .../allow-privilege-escalation/template.yaml | 28 ------------------- src/general/requiredlabels/constraint.tmpl | 3 -- src/general/requiredlabels/src.cel | 5 ---- .../constraint.tmpl | 3 -- .../allow-privilege-escalation/src.cel | 26 ----------------- .../validation/allow-privilege-escalation.md | 28 ------------------- website/docs/validation/requiredlabels.md | 7 ----- 12 files changed, 2 insertions(+), 144 deletions(-) delete mode 100644 src/general/requiredlabels/src.cel delete mode 100644 src/pod-security-policy/allow-privilege-escalation/src.cel diff --git a/artifacthub/library/general/requiredlabels/1.0.2/artifacthub-pkg.yml b/artifacthub/library/general/requiredlabels/1.0.2/artifacthub-pkg.yml index 264a51589..68d09f5a5 100644 --- a/artifacthub/library/general/requiredlabels/1.0.2/artifacthub-pkg.yml +++ b/artifacthub/library/general/requiredlabels/1.0.2/artifacthub-pkg.yml @@ -3,7 +3,7 @@ name: k8srequiredlabels displayName: Required Labels createdAt: "2024-05-02T19:01:02Z" description: Requires resources to contain specified labels, with values matching provided regular expressions. -digest: 46e3f6b92f1aab8f8257407a51a3df1aba697bd83d90d5dfc8f00493886ea4eb +digest: 686f97f6c57dc0196c405c7d03e606a3823696db418fedbd7d0064033cce54f0 license: Apache-2.0 homeURL: https://open-policy-agent.github.io/gatekeeper-library/website/requiredlabels keywords: diff --git a/artifacthub/library/general/requiredlabels/1.0.2/template.yaml b/artifacthub/library/general/requiredlabels/1.0.2/template.yaml index 5a9d2cb07..b56429b3a 100644 --- a/artifacthub/library/general/requiredlabels/1.0.2/template.yaml +++ b/artifacthub/library/general/requiredlabels/1.0.2/template.yaml @@ -39,13 +39,6 @@ spec: targets: - target: admission.k8s.gatekeeper.sh code: - - engine: K8sNativeValidation - source: - validations: - - expression: '(has(request.operation) && request.operation == "DELETE") ||(has(object.metadata) && variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels))' - messageExpression: '"object missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' - - expression: '[object, oldObject].exists(obj, obj != null && !variables.params.labels.exists(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels && !string(obj.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' - message: "regex mismatch" - engine: Rego source: rego: | diff --git a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/artifacthub-pkg.yml b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/artifacthub-pkg.yml index 260f49154..e55766fba 100644 --- a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/artifacthub-pkg.yml +++ b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/artifacthub-pkg.yml @@ -3,7 +3,7 @@ name: k8spspallowprivilegeescalationcontainer displayName: Allow Privilege Escalation in Container createdAt: "2024-05-02T19:01:02Z" description: Controls restricting escalation to root privileges. Corresponds to the `allowPrivilegeEscalation` field in a PodSecurityPolicy. For more information, see https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation -digest: 13c36cccfca382be8eed58e9bec65a4ba93d061480a3c085a17ca68aed804ac6 +digest: c0c4f10500dac29c8851dcb84cfa1d89c3e1cffac20bff1685f9fab91a66509a license: Apache-2.0 homeURL: https://open-policy-agent.github.io/gatekeeper-library/website/allow-privilege-escalation keywords: diff --git a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/template.yaml b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/template.yaml index c25cd5e28..f8d2f2aa9 100644 --- a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/template.yaml +++ b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/template.yaml @@ -37,34 +37,6 @@ spec: targets: - target: admission.k8s.gatekeeper.sh code: - - engine: K8sNativeValidation - source: - variables: - - name: containers - expression: 'has(object.spec.containers) ? object.spec.containers : []' - - name: initContainers - expression: 'has(object.spec.initContainers) ? object.spec.initContainers : []' - - name: ephemeralContainers - expression: 'has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []' - - name: exemptImages - expression: | - !has(variables.params.exemptImages) ? [] : - (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, - // we can use the regex substitution because docker images do not allow "." as a valid character - variables.params.exemptImages.exists(exemption, container.image == exemption || (exemption.endsWith("*") && string(container.image).matches("^" + string(variables.params.exemptImages).replace("*", ".*") + "$"))) - ) - - name: badContainers - expression: | - (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, - !(container.image in variables.exemptImages) && ( - !has(container.securityContext) || - !has(container.securityContext.allowPrivilegeEscalation) || - container.securityContext.allowPrivilegeEscalation != false - ) - ) - validations: - - expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.badContainers) == 0' - messageExpression: '"Privilege escalation container is not allowed: " + variables.badContainers.map(c, c.image).join(", ")' - engine: Rego source: rego: | diff --git a/library/general/requiredlabels/template.yaml b/library/general/requiredlabels/template.yaml index 5a9d2cb07..b56429b3a 100644 --- a/library/general/requiredlabels/template.yaml +++ b/library/general/requiredlabels/template.yaml @@ -39,13 +39,6 @@ spec: targets: - target: admission.k8s.gatekeeper.sh code: - - engine: K8sNativeValidation - source: - validations: - - expression: '(has(request.operation) && request.operation == "DELETE") ||(has(object.metadata) && variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels))' - messageExpression: '"object missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' - - expression: '[object, oldObject].exists(obj, obj != null && !variables.params.labels.exists(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels && !string(obj.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' - message: "regex mismatch" - engine: Rego source: rego: | diff --git a/library/pod-security-policy/allow-privilege-escalation/template.yaml b/library/pod-security-policy/allow-privilege-escalation/template.yaml index c25cd5e28..f8d2f2aa9 100644 --- a/library/pod-security-policy/allow-privilege-escalation/template.yaml +++ b/library/pod-security-policy/allow-privilege-escalation/template.yaml @@ -37,34 +37,6 @@ spec: targets: - target: admission.k8s.gatekeeper.sh code: - - engine: K8sNativeValidation - source: - variables: - - name: containers - expression: 'has(object.spec.containers) ? object.spec.containers : []' - - name: initContainers - expression: 'has(object.spec.initContainers) ? object.spec.initContainers : []' - - name: ephemeralContainers - expression: 'has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []' - - name: exemptImages - expression: | - !has(variables.params.exemptImages) ? [] : - (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, - // we can use the regex substitution because docker images do not allow "." as a valid character - variables.params.exemptImages.exists(exemption, container.image == exemption || (exemption.endsWith("*") && string(container.image).matches("^" + string(variables.params.exemptImages).replace("*", ".*") + "$"))) - ) - - name: badContainers - expression: | - (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, - !(container.image in variables.exemptImages) && ( - !has(container.securityContext) || - !has(container.securityContext.allowPrivilegeEscalation) || - container.securityContext.allowPrivilegeEscalation != false - ) - ) - validations: - - expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.badContainers) == 0' - messageExpression: '"Privilege escalation container is not allowed: " + variables.badContainers.map(c, c.image).join(", ")' - engine: Rego source: rego: | diff --git a/src/general/requiredlabels/constraint.tmpl b/src/general/requiredlabels/constraint.tmpl index 34815bbf7..ffaf04ab4 100644 --- a/src/general/requiredlabels/constraint.tmpl +++ b/src/general/requiredlabels/constraint.tmpl @@ -39,9 +39,6 @@ spec: targets: - target: admission.k8s.gatekeeper.sh code: - - engine: K8sNativeValidation - source: -{{ file.Read "src/general/requiredlabels/src.cel" | strings.Indent 10 | strings.TrimSuffix "\n" }} - engine: Rego source: rego: | diff --git a/src/general/requiredlabels/src.cel b/src/general/requiredlabels/src.cel deleted file mode 100644 index be8e2a700..000000000 --- a/src/general/requiredlabels/src.cel +++ /dev/null @@ -1,5 +0,0 @@ -validations: -- expression: '(has(request.operation) && request.operation == "DELETE") ||(has(object.metadata) && variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels))' - messageExpression: '"object missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' -- expression: '[object, oldObject].exists(obj, obj != null && !variables.params.labels.exists(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels && !string(obj.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' - message: "regex mismatch" diff --git a/src/pod-security-policy/allow-privilege-escalation/constraint.tmpl b/src/pod-security-policy/allow-privilege-escalation/constraint.tmpl index f18c91bd4..314031d76 100644 --- a/src/pod-security-policy/allow-privilege-escalation/constraint.tmpl +++ b/src/pod-security-policy/allow-privilege-escalation/constraint.tmpl @@ -37,9 +37,6 @@ spec: targets: - target: admission.k8s.gatekeeper.sh code: - - engine: K8sNativeValidation - source: -{{ file.Read "src/pod-security-policy/allow-privilege-escalation/src.cel" | strings.Indent 10 | strings.TrimSuffix "\n" }} - engine: Rego source: rego: | diff --git a/src/pod-security-policy/allow-privilege-escalation/src.cel b/src/pod-security-policy/allow-privilege-escalation/src.cel deleted file mode 100644 index 11c8c6b76..000000000 --- a/src/pod-security-policy/allow-privilege-escalation/src.cel +++ /dev/null @@ -1,26 +0,0 @@ -variables: -- name: containers - expression: 'has(object.spec.containers) ? object.spec.containers : []' -- name: initContainers - expression: 'has(object.spec.initContainers) ? object.spec.initContainers : []' -- name: ephemeralContainers - expression: 'has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []' -- name: exemptImages - expression: | - !has(variables.params.exemptImages) ? [] : - (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, - // we can use the regex substitution because docker images do not allow "." as a valid character - variables.params.exemptImages.exists(exemption, container.image == exemption || (exemption.endsWith("*") && string(container.image).matches("^" + string(variables.params.exemptImages).replace("*", ".*") + "$"))) - ) -- name: badContainers - expression: | - (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, - !(container.image in variables.exemptImages) && ( - !has(container.securityContext) || - !has(container.securityContext.allowPrivilegeEscalation) || - container.securityContext.allowPrivilegeEscalation != false - ) - ) -validations: -- expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.badContainers) == 0' - messageExpression: '"Privilege escalation container is not allowed: " + variables.badContainers.map(c, c.image).join(", ")' diff --git a/website/docs/validation/allow-privilege-escalation.md b/website/docs/validation/allow-privilege-escalation.md index 7a0c3820a..753395dcf 100644 --- a/website/docs/validation/allow-privilege-escalation.md +++ b/website/docs/validation/allow-privilege-escalation.md @@ -49,34 +49,6 @@ spec: targets: - target: admission.k8s.gatekeeper.sh code: - - engine: K8sNativeValidation - source: - variables: - - name: containers - expression: 'has(object.spec.containers) ? object.spec.containers : []' - - name: initContainers - expression: 'has(object.spec.initContainers) ? object.spec.initContainers : []' - - name: ephemeralContainers - expression: 'has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []' - - name: exemptImages - expression: | - !has(variables.params.exemptImages) ? [] : - (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, - // we can use the regex substitution because docker images do not allow "." as a valid character - variables.params.exemptImages.exists(exemption, container.image == exemption || (exemption.endsWith("*") && string(container.image).matches("^" + string(variables.params.exemptImages).replace("*", ".*") + "$"))) - ) - - name: badContainers - expression: | - (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, - !(container.image in variables.exemptImages) && ( - !has(container.securityContext) || - !has(container.securityContext.allowPrivilegeEscalation) || - container.securityContext.allowPrivilegeEscalation != false - ) - ) - validations: - - expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.badContainers) == 0' - messageExpression: '"Privilege escalation container is not allowed: " + variables.badContainers.map(c, c.image).join(", ")' - engine: Rego source: rego: | diff --git a/website/docs/validation/requiredlabels.md b/website/docs/validation/requiredlabels.md index 3635b0884..260c24ded 100644 --- a/website/docs/validation/requiredlabels.md +++ b/website/docs/validation/requiredlabels.md @@ -51,13 +51,6 @@ spec: targets: - target: admission.k8s.gatekeeper.sh code: - - engine: K8sNativeValidation - source: - validations: - - expression: '(has(request.operation) && request.operation == "DELETE") ||(has(object.metadata) && variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels))' - messageExpression: '"object missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' - - expression: '[object, oldObject].exists(obj, obj != null && !variables.params.labels.exists(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels && !string(obj.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' - message: "regex mismatch" - engine: Rego source: rego: | From f7b47b8283d0fc85b43fd6d1316036e4dbdfd3a6 Mon Sep 17 00:00:00 2001 From: Jaydip Gabani Date: Wed, 8 May 2024 20:55:34 +0000 Subject: [PATCH 09/23] Using sed to modify gk.yml Signed-off-by: Jaydip Gabani --- .github/workflows/workflow.yaml | 2 +- Makefile | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/workflow.yaml b/.github/workflows/workflow.yaml index 85da2abb5..1ab5c4e84 100644 --- a/.github/workflows/workflow.yaml +++ b/.github/workflows/workflow.yaml @@ -65,7 +65,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - gatekeeper: [ "3.14.2", "3.15.1" ] + gatekeeper: [ "release-3.14", "release-3.15" ] engine: [ "cel", "rego" ] name: "Integration test on Gatekeeper ${{ matrix.gatekeeper }}" steps: diff --git a/Makefile b/Makefile index 417626eb1..1cc44945d 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ KIND_VERSION ?= 0.17.0 # note: k8s version pinned since KIND image availability lags k8s releases KUBERNETES_VERSION ?= 1.26.0 KUSTOMIZE_VERSION ?= 4.5.5 -GATEKEEPER_VERSION ?= 3.15.1 +GATEKEEPER_VERSION ?= release-3.15 BATS_VERSION ?= 1.8.2 GATOR_VERSION ?= 3.15.1 GOMPLATE_VERSION ?= 3.11.6 @@ -32,15 +32,18 @@ integration-bootstrap: TERM=dumb ${GITHUB_WORKSPACE}/bin/kind create cluster --image kindest/node:v${KUBERNETES_VERSION} --wait 5m --config=test/kind_config.yaml deploy: - helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts + wget https://raw.githubusercontent.com/open-policy-agent/gatekeeper/${GATEKEEPER_VERSION}/deploy/gatekeeper.yaml ifeq ($(POLICY_ENGINE), rego) - helm install gatekeeper/gatekeeper --name-template=gatekeeper --namespace gatekeeper-system --create-namespace --version=${GATEKEEPER_VERSION} --set enableK8sNativeValidation=false + sed -i '/- args:/a \ \ \ \ \ \ \ \ - --validate-template-rego=true' gatekeeper.yaml + sed -i '/- args:/a \ \ \ \ \ \ \ \ - --experimental-enable-k8s-native-validation=false' gatekeeper.yaml else ifeq ($(POLICY_ENGINE), cel) - helm install gatekeeper/gatekeeper --name-template=gatekeeper --namespace gatekeeper-system --create-namespace --version=${GATEKEEPER_VERSION} --set enableK8sNativeValidation=true + sed -i '/- args:/a \ \ \ \ \ \ \ \ - --validate-template-rego=false' gatekeeper.yaml + sed -i '/- args:/a \ \ \ \ \ \ \ \ - --experimental-enable-k8s-native-validation=true' gatekeeper.yaml endif + kubectl apply -f gatekeeper.yaml uninstall: - helm delete gatekeeper --namespace gatekeeper-system + kubectl delete -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/${GATEKEEPER_VERSION}/deploy/gatekeeper.yaml test-integration: bats -t test/bats/test.bats From 18cd62a29e54607a88d3d3e0ed834de8179c3f50 Mon Sep 17 00:00:00 2001 From: Jaydip Gabani Date: Thu, 9 May 2024 18:52:17 +0000 Subject: [PATCH 10/23] adding required label policy and fixing deployment for gk Signed-off-by: Jaydip Gabani --- Makefile | 6 +- .../requiredlabels/1.0.2/artifacthub-pkg.yml | 2 +- .../requiredlabels/1.0.2/template.yaml | 8 ++ .../1.0.1/artifacthub-pkg.yml | 4 +- .../1.0.1/template.yaml | 2 +- .../1.0.2/artifacthub-pkg.yml | 22 --- .../1.0.2/kustomization.yaml | 2 - .../constraint.yaml | 9 -- .../disallowed_ephemeral.yaml | 12 -- .../example_allowed.yaml | 12 -- .../example_disallowed.yaml | 12 -- .../update.yaml | 17 --- .../1.0.2/suite.yaml | 25 ---- .../1.0.2/template.yaml | 103 -------------- library/general/requiredlabels/template.yaml | 8 ++ .../allow-privilege-escalation/template.yaml | 113 ++++++++------- src/general/requiredlabels/constraint.tmpl | 4 + src/general/requiredlabels/src.cel | 5 + .../constraint.tmpl | 19 ++- .../validation/allow-privilege-escalation.md | 130 +++++++++--------- website/docs/validation/requiredlabels.md | 8 ++ 21 files changed, 168 insertions(+), 355 deletions(-) delete mode 100644 artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/artifacthub-pkg.yml delete mode 100644 artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/kustomization.yaml delete mode 100644 artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/constraint.yaml delete mode 100644 artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/disallowed_ephemeral.yaml delete mode 100644 artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/example_allowed.yaml delete mode 100644 artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/example_disallowed.yaml delete mode 100644 artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/update.yaml delete mode 100644 artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/suite.yaml delete mode 100644 artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/template.yaml create mode 100644 src/general/requiredlabels/src.cel diff --git a/Makefile b/Makefile index 1cc44945d..25f55348a 100644 --- a/Makefile +++ b/Makefile @@ -37,8 +37,12 @@ ifeq ($(POLICY_ENGINE), rego) sed -i '/- args:/a \ \ \ \ \ \ \ \ - --validate-template-rego=true' gatekeeper.yaml sed -i '/- args:/a \ \ \ \ \ \ \ \ - --experimental-enable-k8s-native-validation=false' gatekeeper.yaml else ifeq ($(POLICY_ENGINE), cel) +ifeq ($(GATEKEEPER_VERSION), release-3.16) + sed -i '/- args:/a \ \ \ \ \ \ \ \ - --experimental-enable-k8s-native-validation=true' gatekeeper.yaml +else sed -i '/- args:/a \ \ \ \ \ \ \ \ - --validate-template-rego=false' gatekeeper.yaml - sed -i '/- args:/a \ \ \ \ \ \ \ \ - --experimental-enable-k8s-native-validation=true' gatekeeper.yaml + sed -i '/- args:/a \ \ \ \ \ \ \ \ - --experimental-enable-k8s-native-validation=true' gatekeeper.yaml +endif endif kubectl apply -f gatekeeper.yaml diff --git a/artifacthub/library/general/requiredlabels/1.0.2/artifacthub-pkg.yml b/artifacthub/library/general/requiredlabels/1.0.2/artifacthub-pkg.yml index 68d09f5a5..20c5b6efe 100644 --- a/artifacthub/library/general/requiredlabels/1.0.2/artifacthub-pkg.yml +++ b/artifacthub/library/general/requiredlabels/1.0.2/artifacthub-pkg.yml @@ -3,7 +3,7 @@ name: k8srequiredlabels displayName: Required Labels createdAt: "2024-05-02T19:01:02Z" description: Requires resources to contain specified labels, with values matching provided regular expressions. -digest: 686f97f6c57dc0196c405c7d03e606a3823696db418fedbd7d0064033cce54f0 +digest: f23618ee55f71e661846ff24d3e06ed0178394be5f6733fa5a14f8b544a8f590 license: Apache-2.0 homeURL: https://open-policy-agent.github.io/gatekeeper-library/website/requiredlabels keywords: diff --git a/artifacthub/library/general/requiredlabels/1.0.2/template.yaml b/artifacthub/library/general/requiredlabels/1.0.2/template.yaml index b56429b3a..989b89bca 100644 --- a/artifacthub/library/general/requiredlabels/1.0.2/template.yaml +++ b/artifacthub/library/general/requiredlabels/1.0.2/template.yaml @@ -39,6 +39,13 @@ spec: targets: - target: admission.k8s.gatekeeper.sh code: + - engine: K8sNativeValidation + source: + validations: + - expression: '(has(object.metadata) && variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels))' + messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' + - expression: '(has(object.metadata) && !variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels && !string(object.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' + message: "regex mismatch" - engine: Rego source: rego: | @@ -69,3 +76,4 @@ spec: def_msg := sprintf("Label <%v: %v> does not satisfy allowed regex: %v", [key, value, expected.allowedRegex]) msg := get_message(input.parameters, def_msg) } + diff --git a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.1/artifacthub-pkg.yml b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.1/artifacthub-pkg.yml index c9378d2b9..170d8c9c4 100644 --- a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.1/artifacthub-pkg.yml +++ b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.1/artifacthub-pkg.yml @@ -1,9 +1,9 @@ version: 1.0.1 name: k8spspallowprivilegeescalationcontainer displayName: Allow Privilege Escalation in Container -createdAt: "2023-05-23T09:47:31Z" +createdAt: "2024-05-09T18:32:02Z" description: Controls restricting escalation to root privileges. Corresponds to the `allowPrivilegeEscalation` field in a PodSecurityPolicy. For more information, see https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation -digest: a3c63022c554318dcc9589828a7b135c80740772375b071dfc0625fdaea91f66 +digest: 4180fd8f3c065c492585922900aa50ff5990fa3384365725a087b2c36bcb0b0c license: Apache-2.0 homeURL: https://open-policy-agent.github.io/gatekeeper-library/website/allow-privilege-escalation keywords: diff --git a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.1/template.yaml b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.1/template.yaml index a7f4694a2..0c4c0f885 100644 --- a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.1/template.yaml +++ b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.1/template.yaml @@ -97,4 +97,4 @@ spec: endswith(exemption, "*") prefix := trim_suffix(exemption, "*") startswith(img, prefix) - } + } \ No newline at end of file diff --git a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/artifacthub-pkg.yml b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/artifacthub-pkg.yml deleted file mode 100644 index e55766fba..000000000 --- a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/artifacthub-pkg.yml +++ /dev/null @@ -1,22 +0,0 @@ -version: 1.0.2 -name: k8spspallowprivilegeescalationcontainer -displayName: Allow Privilege Escalation in Container -createdAt: "2024-05-02T19:01:02Z" -description: Controls restricting escalation to root privileges. Corresponds to the `allowPrivilegeEscalation` field in a PodSecurityPolicy. For more information, see https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation -digest: c0c4f10500dac29c8851dcb84cfa1d89c3e1cffac20bff1685f9fab91a66509a -license: Apache-2.0 -homeURL: https://open-policy-agent.github.io/gatekeeper-library/website/allow-privilege-escalation -keywords: - - gatekeeper - - open-policy-agent - - policies -readme: |- - # Allow Privilege Escalation in Container - Controls restricting escalation to root privileges. Corresponds to the `allowPrivilegeEscalation` field in a PodSecurityPolicy. For more information, see https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation -install: |- - ### Usage - ```shell - kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/template.yaml - ``` -provider: - name: Gatekeeper Library diff --git a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/kustomization.yaml b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/kustomization.yaml deleted file mode 100644 index 7d70d11b7..000000000 --- a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/kustomization.yaml +++ /dev/null @@ -1,2 +0,0 @@ -resources: - - template.yaml diff --git a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/constraint.yaml b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/constraint.yaml deleted file mode 100644 index fdc05a1c0..000000000 --- a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/constraint.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: constraints.gatekeeper.sh/v1beta1 -kind: K8sPSPAllowPrivilegeEscalationContainer -metadata: - name: psp-allow-privilege-escalation-container -spec: - match: - kinds: - - apiGroups: [""] - kinds: ["Pod"] diff --git a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/disallowed_ephemeral.yaml b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/disallowed_ephemeral.yaml deleted file mode 100644 index 5992f96b3..000000000 --- a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/disallowed_ephemeral.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: nginx-privilege-escalation-disallowed - labels: - app: nginx-privilege-escalation -spec: - ephemeralContainers: - - name: nginx - image: nginx - securityContext: - allowPrivilegeEscalation: true diff --git a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/example_allowed.yaml b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/example_allowed.yaml deleted file mode 100644 index 26c8dd879..000000000 --- a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/example_allowed.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: nginx-privilege-escalation-allowed - labels: - app: nginx-privilege-escalation -spec: - containers: - - name: nginx - image: nginx - securityContext: - allowPrivilegeEscalation: false diff --git a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/example_disallowed.yaml b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/example_disallowed.yaml deleted file mode 100644 index d3648d2f2..000000000 --- a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/example_disallowed.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: nginx-privilege-escalation-disallowed - labels: - app: nginx-privilege-escalation -spec: - containers: - - name: nginx - image: nginx - securityContext: - allowPrivilegeEscalation: true diff --git a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/update.yaml b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/update.yaml deleted file mode 100644 index a79d40a1b..000000000 --- a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/samples/psp-allow-privilege-escalation-container/update.yaml +++ /dev/null @@ -1,17 +0,0 @@ -kind: AdmissionReview -apiVersion: admission.k8s.io/v1beta1 -request: - operation: "UPDATE" - object: - apiVersion: v1 - kind: Pod - metadata: - name: nginx-privilege-escalation-disallowed - labels: - app: nginx-privilege-escalation - spec: - containers: - - name: nginx - image: nginx - securityContext: - allowPrivilegeEscalation: true diff --git a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/suite.yaml b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/suite.yaml deleted file mode 100644 index cd7531cfa..000000000 --- a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/suite.yaml +++ /dev/null @@ -1,25 +0,0 @@ -kind: Suite -apiVersion: test.gatekeeper.sh/v1alpha1 -metadata: - name: allow-privilege-escalation -tests: - - name: allow-privilege-escalation - template: template.yaml - constraint: samples/psp-allow-privilege-escalation-container/constraint.yaml - cases: - - name: example-allowed - object: samples/psp-allow-privilege-escalation-container/example_allowed.yaml - assertions: - - violations: no - - name: example-disallowed - object: samples/psp-allow-privilege-escalation-container/example_disallowed.yaml - assertions: - - violations: yes - - name: disallowed-ephemeral - object: samples/psp-allow-privilege-escalation-container/disallowed_ephemeral.yaml - assertions: - - violations: yes - - name: update - object: samples/psp-allow-privilege-escalation-container/update.yaml - assertions: - - violations: no diff --git a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/template.yaml b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/template.yaml deleted file mode 100644 index f8d2f2aa9..000000000 --- a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.2/template.yaml +++ /dev/null @@ -1,103 +0,0 @@ -apiVersion: templates.gatekeeper.sh/v1 -kind: ConstraintTemplate -metadata: - name: k8spspallowprivilegeescalationcontainer - annotations: - metadata.gatekeeper.sh/title: "Allow Privilege Escalation in Container" - metadata.gatekeeper.sh/version: 1.0.2 - description: >- - Controls restricting escalation to root privileges. Corresponds to the - `allowPrivilegeEscalation` field in a PodSecurityPolicy. For more - information, see - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation -spec: - crd: - spec: - names: - kind: K8sPSPAllowPrivilegeEscalationContainer - validation: - openAPIV3Schema: - type: object - description: >- - Controls restricting escalation to root privileges. Corresponds to the - `allowPrivilegeEscalation` field in a PodSecurityPolicy. For more - information, see - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation - properties: - exemptImages: - description: >- - Any container that uses an image that matches an entry in this list will be excluded - from enforcement. Prefix-matching can be signified with `*`. For example: `my-image-*`. - - It is recommended that users use the fully-qualified Docker image name (e.g. start with a domain name) - in order to avoid unexpectedly exempting images from an untrusted repository. - type: array - items: - type: string - targets: - - target: admission.k8s.gatekeeper.sh - code: - - engine: Rego - source: - rego: | - package k8spspallowprivilegeescalationcontainer - - import data.lib.exclude_update.is_update - import data.lib.exempt_container.is_exempt - - violation[{"msg": msg, "details": {}}] { - # spec.containers.securityContext.allowPrivilegeEscalation field is immutable. - not is_update(input.review) - - c := input_containers[_] - not is_exempt(c) - input_allow_privilege_escalation(c) - msg := sprintf("Privilege escalation container is not allowed: %v", [c.name]) - } - - input_allow_privilege_escalation(c) { - not has_field(c, "securityContext") - } - input_allow_privilege_escalation(c) { - not c.securityContext.allowPrivilegeEscalation == false - } - input_containers[c] { - c := input.review.object.spec.containers[_] - } - input_containers[c] { - c := input.review.object.spec.initContainers[_] - } - input_containers[c] { - c := input.review.object.spec.ephemeralContainers[_] - } - # 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" - } - - | - package lib.exempt_container - - is_exempt(container) { - exempt_images := object.get(object.get(input, "parameters", {}), "exemptImages", []) - img := container.image - exemption := exempt_images[_] - _matches_exemption(img, exemption) - } - - _matches_exemption(img, exemption) { - not endswith(exemption, "*") - exemption == img - } - - _matches_exemption(img, exemption) { - endswith(exemption, "*") - prefix := trim_suffix(exemption, "*") - startswith(img, prefix) - } diff --git a/library/general/requiredlabels/template.yaml b/library/general/requiredlabels/template.yaml index b56429b3a..989b89bca 100644 --- a/library/general/requiredlabels/template.yaml +++ b/library/general/requiredlabels/template.yaml @@ -39,6 +39,13 @@ spec: targets: - target: admission.k8s.gatekeeper.sh code: + - engine: K8sNativeValidation + source: + validations: + - expression: '(has(object.metadata) && variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels))' + messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' + - expression: '(has(object.metadata) && !variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels && !string(object.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' + message: "regex mismatch" - engine: Rego source: rego: | @@ -69,3 +76,4 @@ spec: def_msg := sprintf("Label <%v: %v> does not satisfy allowed regex: %v", [key, value, expected.allowedRegex]) msg := get_message(input.parameters, def_msg) } + diff --git a/library/pod-security-policy/allow-privilege-escalation/template.yaml b/library/pod-security-policy/allow-privilege-escalation/template.yaml index f8d2f2aa9..0c4c0f885 100644 --- a/library/pod-security-policy/allow-privilege-escalation/template.yaml +++ b/library/pod-security-policy/allow-privilege-escalation/template.yaml @@ -4,7 +4,7 @@ metadata: name: k8spspallowprivilegeescalationcontainer annotations: metadata.gatekeeper.sh/title: "Allow Privilege Escalation in Container" - metadata.gatekeeper.sh/version: 1.0.2 + metadata.gatekeeper.sh/version: 1.0.1 description: >- Controls restricting escalation to root privileges. Corresponds to the `allowPrivilegeEscalation` field in a PodSecurityPolicy. For more @@ -36,68 +36,65 @@ spec: type: string targets: - target: admission.k8s.gatekeeper.sh - code: - - engine: Rego - source: - rego: | - package k8spspallowprivilegeescalationcontainer + rego: | + package k8spspallowprivilegeescalationcontainer - import data.lib.exclude_update.is_update - import data.lib.exempt_container.is_exempt + import data.lib.exclude_update.is_update + import data.lib.exempt_container.is_exempt - violation[{"msg": msg, "details": {}}] { - # spec.containers.securityContext.allowPrivilegeEscalation field is immutable. - not is_update(input.review) + violation[{"msg": msg, "details": {}}] { + # spec.containers.securityContext.allowPrivilegeEscalation field is immutable. + not is_update(input.review) - c := input_containers[_] - not is_exempt(c) - input_allow_privilege_escalation(c) - msg := sprintf("Privilege escalation container is not allowed: %v", [c.name]) - } + c := input_containers[_] + not is_exempt(c) + input_allow_privilege_escalation(c) + msg := sprintf("Privilege escalation container is not allowed: %v", [c.name]) + } - input_allow_privilege_escalation(c) { - not has_field(c, "securityContext") - } - input_allow_privilege_escalation(c) { - not c.securityContext.allowPrivilegeEscalation == false - } - input_containers[c] { - c := input.review.object.spec.containers[_] - } - input_containers[c] { - c := input.review.object.spec.initContainers[_] - } - input_containers[c] { - c := input.review.object.spec.ephemeralContainers[_] - } - # has_field returns whether an object has a field - has_field(object, field) = true { - object[field] - } - libs: - - | - package lib.exclude_update + input_allow_privilege_escalation(c) { + not has_field(c, "securityContext") + } + input_allow_privilege_escalation(c) { + not c.securityContext.allowPrivilegeEscalation == false + } + input_containers[c] { + c := input.review.object.spec.containers[_] + } + input_containers[c] { + c := input.review.object.spec.initContainers[_] + } + input_containers[c] { + c := input.review.object.spec.ephemeralContainers[_] + } + # 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" - } - - | - package lib.exempt_container + is_update(review) { + review.operation == "UPDATE" + } + - | + package lib.exempt_container - is_exempt(container) { - exempt_images := object.get(object.get(input, "parameters", {}), "exemptImages", []) - img := container.image - exemption := exempt_images[_] - _matches_exemption(img, exemption) - } + is_exempt(container) { + exempt_images := object.get(object.get(input, "parameters", {}), "exemptImages", []) + img := container.image + exemption := exempt_images[_] + _matches_exemption(img, exemption) + } - _matches_exemption(img, exemption) { - not endswith(exemption, "*") - exemption == img - } + _matches_exemption(img, exemption) { + not endswith(exemption, "*") + exemption == img + } - _matches_exemption(img, exemption) { - endswith(exemption, "*") - prefix := trim_suffix(exemption, "*") - startswith(img, prefix) - } + _matches_exemption(img, exemption) { + endswith(exemption, "*") + prefix := trim_suffix(exemption, "*") + startswith(img, prefix) + } \ No newline at end of file diff --git a/src/general/requiredlabels/constraint.tmpl b/src/general/requiredlabels/constraint.tmpl index ffaf04ab4..217d94a5d 100644 --- a/src/general/requiredlabels/constraint.tmpl +++ b/src/general/requiredlabels/constraint.tmpl @@ -39,7 +39,11 @@ spec: targets: - target: admission.k8s.gatekeeper.sh code: + - engine: K8sNativeValidation + source: +{{ file.Read "src/general/requiredlabels/src.cel" | strings.Indent 10 | strings.TrimSuffix "\n" }} - engine: Rego source: rego: | {{ file.Read "src/general/requiredlabels/src.rego" | strings.Indent 12 | strings.TrimSuffix "\n" }} + diff --git a/src/general/requiredlabels/src.cel b/src/general/requiredlabels/src.cel new file mode 100644 index 000000000..62ba71680 --- /dev/null +++ b/src/general/requiredlabels/src.cel @@ -0,0 +1,5 @@ +validations: +- expression: '(has(object.metadata) && variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels))' + messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' +- expression: '(has(object.metadata) && !variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels && !string(object.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' + message: "regex mismatch" \ No newline at end of file diff --git a/src/pod-security-policy/allow-privilege-escalation/constraint.tmpl b/src/pod-security-policy/allow-privilege-escalation/constraint.tmpl index 314031d76..de94aa698 100644 --- a/src/pod-security-policy/allow-privilege-escalation/constraint.tmpl +++ b/src/pod-security-policy/allow-privilege-escalation/constraint.tmpl @@ -4,7 +4,7 @@ metadata: name: k8spspallowprivilegeescalationcontainer annotations: metadata.gatekeeper.sh/title: "Allow Privilege Escalation in Container" - metadata.gatekeeper.sh/version: 1.0.2 + metadata.gatekeeper.sh/version: 1.0.1 description: >- Controls restricting escalation to root privileges. Corresponds to the `allowPrivilegeEscalation` field in a PodSecurityPolicy. For more @@ -36,13 +36,10 @@ spec: type: string targets: - target: admission.k8s.gatekeeper.sh - code: - - engine: Rego - source: - rego: | -{{ file.Read "src/pod-security-policy/allow-privilege-escalation/src.rego" | strings.Indent 12 | strings.TrimSuffix "\n" }} - libs: - - | -{{ file.Read "src/pod-security-policy/allow-privilege-escalation/lib_exclude_update.rego" | strings.Indent 14 | strings.TrimSuffix "\n" }} - - | -{{ file.Read "src/pod-security-policy/allow-privilege-escalation/lib_exempt_container.rego" | strings.Indent 14 | strings.TrimSuffix "\n" }} + rego: | +{{ file.Read "src/pod-security-policy/allow-privilege-escalation/src.rego" | strings.Indent 8 | strings.TrimSuffix "\n" }} + libs: + - | +{{ file.Read "src/pod-security-policy/allow-privilege-escalation/lib_exclude_update.rego" | strings.Indent 10 | strings.TrimSuffix "\n" }} + - | +{{ file.Read "src/pod-security-policy/allow-privilege-escalation/lib_exempt_container.rego" | strings.Indent 10 | strings.TrimSuffix "\n" }} \ No newline at end of file diff --git a/website/docs/validation/allow-privilege-escalation.md b/website/docs/validation/allow-privilege-escalation.md index 753395dcf..247c3b86d 100644 --- a/website/docs/validation/allow-privilege-escalation.md +++ b/website/docs/validation/allow-privilege-escalation.md @@ -16,7 +16,7 @@ metadata: name: k8spspallowprivilegeescalationcontainer annotations: metadata.gatekeeper.sh/title: "Allow Privilege Escalation in Container" - metadata.gatekeeper.sh/version: 1.0.2 + metadata.gatekeeper.sh/version: 1.0.1 description: >- Controls restricting escalation to root privileges. Corresponds to the `allowPrivilegeEscalation` field in a PodSecurityPolicy. For more @@ -48,72 +48,68 @@ spec: type: string targets: - target: admission.k8s.gatekeeper.sh - code: - - engine: Rego - source: - rego: | - package k8spspallowprivilegeescalationcontainer - - import data.lib.exclude_update.is_update - import data.lib.exempt_container.is_exempt - - violation[{"msg": msg, "details": {}}] { - # spec.containers.securityContext.allowPrivilegeEscalation field is immutable. - not is_update(input.review) - - c := input_containers[_] - not is_exempt(c) - input_allow_privilege_escalation(c) - msg := sprintf("Privilege escalation container is not allowed: %v", [c.name]) - } - - input_allow_privilege_escalation(c) { - not has_field(c, "securityContext") - } - input_allow_privilege_escalation(c) { - not c.securityContext.allowPrivilegeEscalation == false - } - input_containers[c] { - c := input.review.object.spec.containers[_] - } - input_containers[c] { - c := input.review.object.spec.initContainers[_] - } - input_containers[c] { - c := input.review.object.spec.ephemeralContainers[_] - } - # 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" - } - - | - package lib.exempt_container - - is_exempt(container) { - exempt_images := object.get(object.get(input, "parameters", {}), "exemptImages", []) - img := container.image - exemption := exempt_images[_] - _matches_exemption(img, exemption) - } - - _matches_exemption(img, exemption) { - not endswith(exemption, "*") - exemption == img - } - - _matches_exemption(img, exemption) { - endswith(exemption, "*") - prefix := trim_suffix(exemption, "*") - startswith(img, prefix) - } - + rego: | + package k8spspallowprivilegeescalationcontainer + + import data.lib.exclude_update.is_update + import data.lib.exempt_container.is_exempt + + violation[{"msg": msg, "details": {}}] { + # spec.containers.securityContext.allowPrivilegeEscalation field is immutable. + not is_update(input.review) + + c := input_containers[_] + not is_exempt(c) + input_allow_privilege_escalation(c) + msg := sprintf("Privilege escalation container is not allowed: %v", [c.name]) + } + + input_allow_privilege_escalation(c) { + not has_field(c, "securityContext") + } + input_allow_privilege_escalation(c) { + not c.securityContext.allowPrivilegeEscalation == false + } + input_containers[c] { + c := input.review.object.spec.containers[_] + } + input_containers[c] { + c := input.review.object.spec.initContainers[_] + } + input_containers[c] { + c := input.review.object.spec.ephemeralContainers[_] + } + # 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" + } + - | + package lib.exempt_container + + is_exempt(container) { + exempt_images := object.get(object.get(input, "parameters", {}), "exemptImages", []) + img := container.image + exemption := exempt_images[_] + _matches_exemption(img, exemption) + } + + _matches_exemption(img, exemption) { + not endswith(exemption, "*") + exemption == img + } + + _matches_exemption(img, exemption) { + endswith(exemption, "*") + prefix := trim_suffix(exemption, "*") + startswith(img, prefix) + } ``` ### Usage diff --git a/website/docs/validation/requiredlabels.md b/website/docs/validation/requiredlabels.md index 260c24ded..d3aaf2f9f 100644 --- a/website/docs/validation/requiredlabels.md +++ b/website/docs/validation/requiredlabels.md @@ -51,6 +51,13 @@ spec: targets: - target: admission.k8s.gatekeeper.sh code: + - engine: K8sNativeValidation + source: + validations: + - expression: '(has(object.metadata) && variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels))' + messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' + - expression: '(has(object.metadata) && !variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels && !string(object.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' + message: "regex mismatch" - engine: Rego source: rego: | @@ -82,6 +89,7 @@ spec: msg := get_message(input.parameters, def_msg) } + ``` ### Usage From a965f5ac75f0ee1c55cedfd703a1aa2a5dcca683 Mon Sep 17 00:00:00 2001 From: Jaydip Gabani Date: Thu, 9 May 2024 19:11:19 +0000 Subject: [PATCH 11/23] fixing ci Signed-off-by: Jaydip Gabani --- .../allow-privilege-escalation/1.0.1/artifacthub-pkg.yml | 4 ++-- .../allow-privilege-escalation/1.0.1/template.yaml | 2 +- .../allow-privilege-escalation/template.yaml | 2 +- .../allow-privilege-escalation/constraint.tmpl | 2 +- website/docs/validation/allow-privilege-escalation.md | 1 + 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.1/artifacthub-pkg.yml b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.1/artifacthub-pkg.yml index 170d8c9c4..cbbcdea17 100644 --- a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.1/artifacthub-pkg.yml +++ b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.1/artifacthub-pkg.yml @@ -1,9 +1,9 @@ version: 1.0.1 name: k8spspallowprivilegeescalationcontainer displayName: Allow Privilege Escalation in Container -createdAt: "2024-05-09T18:32:02Z" +createdAt: "2024-05-09T19:10:40Z" description: Controls restricting escalation to root privileges. Corresponds to the `allowPrivilegeEscalation` field in a PodSecurityPolicy. For more information, see https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation -digest: 4180fd8f3c065c492585922900aa50ff5990fa3384365725a087b2c36bcb0b0c +digest: a3c63022c554318dcc9589828a7b135c80740772375b071dfc0625fdaea91f66 license: Apache-2.0 homeURL: https://open-policy-agent.github.io/gatekeeper-library/website/allow-privilege-escalation keywords: diff --git a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.1/template.yaml b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.1/template.yaml index 0c4c0f885..a7f4694a2 100644 --- a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.1/template.yaml +++ b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.1/template.yaml @@ -97,4 +97,4 @@ spec: endswith(exemption, "*") prefix := trim_suffix(exemption, "*") startswith(img, prefix) - } \ No newline at end of file + } diff --git a/library/pod-security-policy/allow-privilege-escalation/template.yaml b/library/pod-security-policy/allow-privilege-escalation/template.yaml index 0c4c0f885..a7f4694a2 100644 --- a/library/pod-security-policy/allow-privilege-escalation/template.yaml +++ b/library/pod-security-policy/allow-privilege-escalation/template.yaml @@ -97,4 +97,4 @@ spec: endswith(exemption, "*") prefix := trim_suffix(exemption, "*") startswith(img, prefix) - } \ No newline at end of file + } diff --git a/src/pod-security-policy/allow-privilege-escalation/constraint.tmpl b/src/pod-security-policy/allow-privilege-escalation/constraint.tmpl index de94aa698..e5f6f323f 100644 --- a/src/pod-security-policy/allow-privilege-escalation/constraint.tmpl +++ b/src/pod-security-policy/allow-privilege-escalation/constraint.tmpl @@ -42,4 +42,4 @@ spec: - | {{ file.Read "src/pod-security-policy/allow-privilege-escalation/lib_exclude_update.rego" | strings.Indent 10 | strings.TrimSuffix "\n" }} - | -{{ file.Read "src/pod-security-policy/allow-privilege-escalation/lib_exempt_container.rego" | strings.Indent 10 | strings.TrimSuffix "\n" }} \ No newline at end of file +{{ file.Read "src/pod-security-policy/allow-privilege-escalation/lib_exempt_container.rego" | strings.Indent 10 | strings.TrimSuffix "\n" }} diff --git a/website/docs/validation/allow-privilege-escalation.md b/website/docs/validation/allow-privilege-escalation.md index 247c3b86d..fbb56a6b2 100644 --- a/website/docs/validation/allow-privilege-escalation.md +++ b/website/docs/validation/allow-privilege-escalation.md @@ -110,6 +110,7 @@ spec: prefix := trim_suffix(exemption, "*") startswith(img, prefix) } + ``` ### Usage From fbd06cc6f22f955005c686a629d424433eff7333 Mon Sep 17 00:00:00 2001 From: Jaydip Gabani Date: Thu, 9 May 2024 19:57:53 +0000 Subject: [PATCH 12/23] adding not allowed label value example for required label policy Signed-off-by: Jaydip Gabani --- .../example_disallowed_label_value.yaml | 6 ++++++ .../general/requiredlabels/1.0.2/suite.yaml | 4 ++++ .../1.0.1/artifacthub-pkg.yml | 2 +- .../example_disallowed_label_value.yaml | 6 ++++++ library/general/requiredlabels/suite.yaml | 4 ++++ website/docs/validation/requiredlabels.md | 20 +++++++++++++++++++ 6 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 artifacthub/library/general/requiredlabels/1.0.2/samples/all-must-have-owner/example_disallowed_label_value.yaml create mode 100644 library/general/requiredlabels/samples/all-must-have-owner/example_disallowed_label_value.yaml diff --git a/artifacthub/library/general/requiredlabels/1.0.2/samples/all-must-have-owner/example_disallowed_label_value.yaml b/artifacthub/library/general/requiredlabels/1.0.2/samples/all-must-have-owner/example_disallowed_label_value.yaml new file mode 100644 index 000000000..36ae77176 --- /dev/null +++ b/artifacthub/library/general/requiredlabels/1.0.2/samples/all-must-have-owner/example_disallowed_label_value.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: disallowed-namespace + labels: + owner: user diff --git a/artifacthub/library/general/requiredlabels/1.0.2/suite.yaml b/artifacthub/library/general/requiredlabels/1.0.2/suite.yaml index 64c5b4130..0995d8ea0 100644 --- a/artifacthub/library/general/requiredlabels/1.0.2/suite.yaml +++ b/artifacthub/library/general/requiredlabels/1.0.2/suite.yaml @@ -15,3 +15,7 @@ tests: object: samples/all-must-have-owner/example_disallowed.yaml assertions: - violations: yes + - name: example-disallowed-label-value + object: samples/all-must-have-owner/example_disallowed_label_value.yaml + assertions: + - violations: yes diff --git a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.1/artifacthub-pkg.yml b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.1/artifacthub-pkg.yml index cbbcdea17..c9378d2b9 100644 --- a/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.1/artifacthub-pkg.yml +++ b/artifacthub/library/pod-security-policy/allow-privilege-escalation/1.0.1/artifacthub-pkg.yml @@ -1,7 +1,7 @@ version: 1.0.1 name: k8spspallowprivilegeescalationcontainer displayName: Allow Privilege Escalation in Container -createdAt: "2024-05-09T19:10:40Z" +createdAt: "2023-05-23T09:47:31Z" description: Controls restricting escalation to root privileges. Corresponds to the `allowPrivilegeEscalation` field in a PodSecurityPolicy. For more information, see https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation digest: a3c63022c554318dcc9589828a7b135c80740772375b071dfc0625fdaea91f66 license: Apache-2.0 diff --git a/library/general/requiredlabels/samples/all-must-have-owner/example_disallowed_label_value.yaml b/library/general/requiredlabels/samples/all-must-have-owner/example_disallowed_label_value.yaml new file mode 100644 index 000000000..36ae77176 --- /dev/null +++ b/library/general/requiredlabels/samples/all-must-have-owner/example_disallowed_label_value.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: disallowed-namespace + labels: + owner: user diff --git a/library/general/requiredlabels/suite.yaml b/library/general/requiredlabels/suite.yaml index 64c5b4130..0995d8ea0 100644 --- a/library/general/requiredlabels/suite.yaml +++ b/library/general/requiredlabels/suite.yaml @@ -15,3 +15,7 @@ tests: object: samples/all-must-have-owner/example_disallowed.yaml assertions: - violations: yes + - name: example-disallowed-label-value + object: samples/all-must-have-owner/example_disallowed_label_value.yaml + assertions: + - violations: yes diff --git a/website/docs/validation/requiredlabels.md b/website/docs/validation/requiredlabels.md index d3aaf2f9f..4b0682a62 100644 --- a/website/docs/validation/requiredlabels.md +++ b/website/docs/validation/requiredlabels.md @@ -166,6 +166,26 @@ Usage kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/general/requiredlabels/samples/all-must-have-owner/example_disallowed.yaml ``` + +
+example-disallowed-label-value + +```yaml +apiVersion: v1 +kind: Namespace +metadata: + name: disallowed-namespace + labels: + owner: user + +``` + +Usage + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/general/requiredlabels/samples/all-must-have-owner/example_disallowed_label_value.yaml +``` +
From 960614de79325848aa7c2d93efb029e9907b309a Mon Sep 17 00:00:00 2001 From: Jaydip Gabani Date: Fri, 10 May 2024 20:08:42 +0000 Subject: [PATCH 13/23] testing cel with 3.16+ Signed-off-by: Jaydip Gabani --- .github/workflows/workflow.yaml | 2 +- Makefile | 19 +++++++------------ 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/.github/workflows/workflow.yaml b/.github/workflows/workflow.yaml index 1ab5c4e84..a3e812b62 100644 --- a/.github/workflows/workflow.yaml +++ b/.github/workflows/workflow.yaml @@ -65,7 +65,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - gatekeeper: [ "release-3.14", "release-3.15" ] + gatekeeper: [ "3.15.1", "3.16.0" ] engine: [ "cel", "rego" ] name: "Integration test on Gatekeeper ${{ matrix.gatekeeper }}" steps: diff --git a/Makefile b/Makefile index 25f55348a..cc00a42eb 100644 --- a/Makefile +++ b/Makefile @@ -3,9 +3,9 @@ KIND_VERSION ?= 0.17.0 # note: k8s version pinned since KIND image availability lags k8s releases KUBERNETES_VERSION ?= 1.26.0 KUSTOMIZE_VERSION ?= 4.5.5 -GATEKEEPER_VERSION ?= release-3.15 +GATEKEEPER_VERSION ?= 3.16.0 BATS_VERSION ?= 1.8.2 -GATOR_VERSION ?= 3.15.1 +GATOR_VERSION ?= 3.16.0 GOMPLATE_VERSION ?= 3.11.6 POLICY_ENGINE ?= rego @@ -32,22 +32,17 @@ integration-bootstrap: TERM=dumb ${GITHUB_WORKSPACE}/bin/kind create cluster --image kindest/node:v${KUBERNETES_VERSION} --wait 5m --config=test/kind_config.yaml deploy: - wget https://raw.githubusercontent.com/open-policy-agent/gatekeeper/${GATEKEEPER_VERSION}/deploy/gatekeeper.yaml + helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts ifeq ($(POLICY_ENGINE), rego) - sed -i '/- args:/a \ \ \ \ \ \ \ \ - --validate-template-rego=true' gatekeeper.yaml - sed -i '/- args:/a \ \ \ \ \ \ \ \ - --experimental-enable-k8s-native-validation=false' gatekeeper.yaml + helm install -n gatekeeper-system gatekeeper gatekeeper/gatekeeper --create-namespace --version $(GATEKEEPER_VERSION) --set enableK8sNativeValidation=false else ifeq ($(POLICY_ENGINE), cel) -ifeq ($(GATEKEEPER_VERSION), release-3.16) - sed -i '/- args:/a \ \ \ \ \ \ \ \ - --experimental-enable-k8s-native-validation=true' gatekeeper.yaml -else - sed -i '/- args:/a \ \ \ \ \ \ \ \ - --validate-template-rego=false' gatekeeper.yaml - sed -i '/- args:/a \ \ \ \ \ \ \ \ - --experimental-enable-k8s-native-validation=true' gatekeeper.yaml +ifneq ($(GATEKEEPER_VERSION), 3.15.1) + helm install -n gatekeeper-system gatekeeper gatekeeper/gatekeeper --create-namespace --version $(GATEKEEPER_VERSION) --set enableK8sNativeValidation=true endif endif - kubectl apply -f gatekeeper.yaml uninstall: - kubectl delete -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/${GATEKEEPER_VERSION}/deploy/gatekeeper.yaml + helm uninstall -n gatekeeper-system gatekeeper test-integration: bats -t test/bats/test.bats From ad3ab1d061480cf7db7738e1a9e378155aace1ec Mon Sep 17 00:00:00 2001 From: Jaydip Gabani Date: Fri, 10 May 2024 21:50:10 +0000 Subject: [PATCH 14/23] changing required label cel Signed-off-by: Jaydip Gabani --- .../library/general/requiredlabels/1.0.2/artifacthub-pkg.yml | 2 +- artifacthub/library/general/requiredlabels/1.0.2/suite.yaml | 4 ++-- .../library/general/requiredlabels/1.0.2/template.yaml | 4 ++-- .../all-must-have-owner/example_disallowed_label_value.yaml | 1 + library/general/requiredlabels/template.yaml | 4 ++-- src/general/requiredlabels/src.cel | 4 ++-- website/docs/validation/requiredlabels.md | 5 +++-- 7 files changed, 13 insertions(+), 11 deletions(-) diff --git a/artifacthub/library/general/requiredlabels/1.0.2/artifacthub-pkg.yml b/artifacthub/library/general/requiredlabels/1.0.2/artifacthub-pkg.yml index 20c5b6efe..c532b1800 100644 --- a/artifacthub/library/general/requiredlabels/1.0.2/artifacthub-pkg.yml +++ b/artifacthub/library/general/requiredlabels/1.0.2/artifacthub-pkg.yml @@ -3,7 +3,7 @@ name: k8srequiredlabels displayName: Required Labels createdAt: "2024-05-02T19:01:02Z" description: Requires resources to contain specified labels, with values matching provided regular expressions. -digest: f23618ee55f71e661846ff24d3e06ed0178394be5f6733fa5a14f8b544a8f590 +digest: 0bd026da84bf4f57a45d34661a9641c96eca580ccee7b3ab5f10b952f9106362 license: Apache-2.0 homeURL: https://open-policy-agent.github.io/gatekeeper-library/website/requiredlabels keywords: diff --git a/artifacthub/library/general/requiredlabels/1.0.2/suite.yaml b/artifacthub/library/general/requiredlabels/1.0.2/suite.yaml index 0995d8ea0..24709fa9c 100644 --- a/artifacthub/library/general/requiredlabels/1.0.2/suite.yaml +++ b/artifacthub/library/general/requiredlabels/1.0.2/suite.yaml @@ -14,8 +14,8 @@ tests: - name: example-disallowed object: samples/all-must-have-owner/example_disallowed.yaml assertions: - - violations: yes + - violations: no - name: example-disallowed-label-value object: samples/all-must-have-owner/example_disallowed_label_value.yaml assertions: - - violations: yes + - violations: no diff --git a/artifacthub/library/general/requiredlabels/1.0.2/template.yaml b/artifacthub/library/general/requiredlabels/1.0.2/template.yaml index 989b89bca..33422f35b 100644 --- a/artifacthub/library/general/requiredlabels/1.0.2/template.yaml +++ b/artifacthub/library/general/requiredlabels/1.0.2/template.yaml @@ -42,9 +42,9 @@ spec: - engine: K8sNativeValidation source: validations: - - expression: '(has(object.metadata) && variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels))' + - expression: '(has(object.metadata) && variables.params.labels.exists_one(entry, has(object.metadata.labels) && entry.key in object.metadata.labels))' messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' - - expression: '(has(object.metadata) && !variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels && !string(object.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' + - expression: '(has(object.metadata) && variables.params.labels.exists_one(entry, has(object.metadata.labels) && entry.key in object.metadata.labels && string(object.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' message: "regex mismatch" - engine: Rego source: diff --git a/library/general/requiredlabels/samples/all-must-have-owner/example_disallowed_label_value.yaml b/library/general/requiredlabels/samples/all-must-have-owner/example_disallowed_label_value.yaml index 36ae77176..fddeb6653 100644 --- a/library/general/requiredlabels/samples/all-must-have-owner/example_disallowed_label_value.yaml +++ b/library/general/requiredlabels/samples/all-must-have-owner/example_disallowed_label_value.yaml @@ -4,3 +4,4 @@ metadata: name: disallowed-namespace labels: owner: user + test: test diff --git a/library/general/requiredlabels/template.yaml b/library/general/requiredlabels/template.yaml index 989b89bca..33422f35b 100644 --- a/library/general/requiredlabels/template.yaml +++ b/library/general/requiredlabels/template.yaml @@ -42,9 +42,9 @@ spec: - engine: K8sNativeValidation source: validations: - - expression: '(has(object.metadata) && variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels))' + - expression: '(has(object.metadata) && variables.params.labels.exists_one(entry, has(object.metadata.labels) && entry.key in object.metadata.labels))' messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' - - expression: '(has(object.metadata) && !variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels && !string(object.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' + - expression: '(has(object.metadata) && variables.params.labels.exists_one(entry, has(object.metadata.labels) && entry.key in object.metadata.labels && string(object.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' message: "regex mismatch" - engine: Rego source: diff --git a/src/general/requiredlabels/src.cel b/src/general/requiredlabels/src.cel index 62ba71680..c52e19991 100644 --- a/src/general/requiredlabels/src.cel +++ b/src/general/requiredlabels/src.cel @@ -1,5 +1,5 @@ validations: -- expression: '(has(object.metadata) && variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels))' +- expression: '(has(object.metadata) && variables.params.labels.exists_one(entry, has(object.metadata.labels) && entry.key in object.metadata.labels))' messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' -- expression: '(has(object.metadata) && !variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels && !string(object.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' +- expression: '(has(object.metadata) && variables.params.labels.exists_one(entry, has(object.metadata.labels) && entry.key in object.metadata.labels && string(object.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' message: "regex mismatch" \ No newline at end of file diff --git a/website/docs/validation/requiredlabels.md b/website/docs/validation/requiredlabels.md index 4b0682a62..981b0e6c3 100644 --- a/website/docs/validation/requiredlabels.md +++ b/website/docs/validation/requiredlabels.md @@ -54,9 +54,9 @@ spec: - engine: K8sNativeValidation source: validations: - - expression: '(has(object.metadata) && variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels))' + - expression: '(has(object.metadata) && variables.params.labels.exists_one(entry, has(object.metadata.labels) && entry.key in object.metadata.labels))' messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' - - expression: '(has(object.metadata) && !variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels && !string(object.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' + - expression: '(has(object.metadata) && variables.params.labels.exists_one(entry, has(object.metadata.labels) && entry.key in object.metadata.labels && string(object.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' message: "regex mismatch" - engine: Rego source: @@ -177,6 +177,7 @@ metadata: name: disallowed-namespace labels: owner: user + test: test ``` From 77fc2496d3a5fb27ec4d40801d2225fa7804bad6 Mon Sep 17 00:00:00 2001 From: Jaydip Gabani Date: Fri, 10 May 2024 21:57:47 +0000 Subject: [PATCH 15/23] only testing rego for 3.15 Signed-off-by: Jaydip Gabani --- .github/workflows/workflow.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/workflow.yaml b/.github/workflows/workflow.yaml index a3e812b62..1878a1fc8 100644 --- a/.github/workflows/workflow.yaml +++ b/.github/workflows/workflow.yaml @@ -68,6 +68,7 @@ jobs: gatekeeper: [ "3.15.1", "3.16.0" ] engine: [ "cel", "rego" ] name: "Integration test on Gatekeeper ${{ matrix.gatekeeper }}" + if: (${{ matrix.gatekeeper }} == '3.15.1' && ${{ matrix.engine }} == 'rego') || (${{ matrix.gatekeeper }} == '3.16.0') steps: - name: Harden Runner uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1 From 58a9b576bb180dd04c946acbc50555033213bd75 Mon Sep 17 00:00:00 2001 From: Jaydip Gabani Date: Fri, 10 May 2024 22:19:39 +0000 Subject: [PATCH 16/23] fixing ci Signed-off-by: Jaydip Gabani --- .github/workflows/workflow.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workflow.yaml b/.github/workflows/workflow.yaml index 1878a1fc8..cbd0aaf7b 100644 --- a/.github/workflows/workflow.yaml +++ b/.github/workflows/workflow.yaml @@ -68,7 +68,7 @@ jobs: gatekeeper: [ "3.15.1", "3.16.0" ] engine: [ "cel", "rego" ] name: "Integration test on Gatekeeper ${{ matrix.gatekeeper }}" - if: (${{ matrix.gatekeeper }} == '3.15.1' && ${{ matrix.engine }} == 'rego') || (${{ matrix.gatekeeper }} == '3.16.0') + if: ${{ matrix.gatekeeper == '3.15.1' && matrix.engine == 'rego' }} || ${{ matrix.gatekeeper == '3.16.0' }} steps: - name: Harden Runner uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1 From 466d8eb8bae59939a3546bdc815e8d5f711c46ad Mon Sep 17 00:00:00 2001 From: Jaydip Gabani Date: Fri, 10 May 2024 23:07:13 +0000 Subject: [PATCH 17/23] fixing ci Signed-off-by: Jaydip Gabani --- .github/workflows/workflow.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/workflow.yaml b/.github/workflows/workflow.yaml index cbd0aaf7b..633b374b4 100644 --- a/.github/workflows/workflow.yaml +++ b/.github/workflows/workflow.yaml @@ -68,17 +68,19 @@ jobs: gatekeeper: [ "3.15.1", "3.16.0" ] engine: [ "cel", "rego" ] name: "Integration test on Gatekeeper ${{ matrix.gatekeeper }}" - if: ${{ matrix.gatekeeper == '3.15.1' && matrix.engine == 'rego' }} || ${{ matrix.gatekeeper == '3.16.0' }} steps: - name: Harden Runner + if: ${{ matrix.gatekeeper == '3.15.1' && matrix.engine == 'rego' }} || ${{ matrix.gatekeeper == '3.16.0' }} # remove this condition once 3.17 is out uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1 with: egress-policy: audit - name: Check out code into the Go module directory + if: ${{ matrix.gatekeeper == '3.15.1' && matrix.engine == 'rego' }} || ${{ matrix.gatekeeper == '3.16.0' }} uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - name: Bootstrap integration test + if: ${{ matrix.gatekeeper == '3.15.1' && matrix.engine == 'rego' }} || ${{ matrix.gatekeeper == '3.16.0' }} run: | mkdir -p $GITHUB_WORKSPACE/bin echo "$GITHUB_WORKSPACE/bin" >> $GITHUB_PATH @@ -86,10 +88,12 @@ jobs: make deploy GATEKEEPER_VERSION=${{ matrix.gatekeeper }} POLICY_ENGINE=${{ matrix.engine }} - name: Run integration test + if: ${{ matrix.gatekeeper == '3.15.1' && matrix.engine == 'rego' }} || ${{ matrix.gatekeeper == '3.16.0' }} run: | make test-integration - name: Save logs + if: ${{ matrix.gatekeeper == '3.15.1' && matrix.engine == 'rego' }} || ${{ matrix.gatekeeper == '3.16.0' }} run: | kubectl logs -n gatekeeper-system -l control-plane=controller-manager --tail=-1 > logs-controller.json kubectl logs -n gatekeeper-system -l control-plane=audit-controller --tail=-1 > logs-audit.json From b9ab792ca443e33a417d260587a41a4acfd6fa2c Mon Sep 17 00:00:00 2001 From: Jaydip Gabani Date: Fri, 10 May 2024 23:16:30 +0000 Subject: [PATCH 18/23] fixing examples Signed-off-by: Jaydip Gabani --- artifacthub/library/general/requiredlabels/1.0.2/suite.yaml | 4 ++-- .../all-must-have-owner/example_disallowed_label_value.yaml | 1 - website/docs/validation/requiredlabels.md | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/artifacthub/library/general/requiredlabels/1.0.2/suite.yaml b/artifacthub/library/general/requiredlabels/1.0.2/suite.yaml index 24709fa9c..0995d8ea0 100644 --- a/artifacthub/library/general/requiredlabels/1.0.2/suite.yaml +++ b/artifacthub/library/general/requiredlabels/1.0.2/suite.yaml @@ -14,8 +14,8 @@ tests: - name: example-disallowed object: samples/all-must-have-owner/example_disallowed.yaml assertions: - - violations: no + - violations: yes - name: example-disallowed-label-value object: samples/all-must-have-owner/example_disallowed_label_value.yaml assertions: - - violations: no + - violations: yes diff --git a/library/general/requiredlabels/samples/all-must-have-owner/example_disallowed_label_value.yaml b/library/general/requiredlabels/samples/all-must-have-owner/example_disallowed_label_value.yaml index fddeb6653..36ae77176 100644 --- a/library/general/requiredlabels/samples/all-must-have-owner/example_disallowed_label_value.yaml +++ b/library/general/requiredlabels/samples/all-must-have-owner/example_disallowed_label_value.yaml @@ -4,4 +4,3 @@ metadata: name: disallowed-namespace labels: owner: user - test: test diff --git a/website/docs/validation/requiredlabels.md b/website/docs/validation/requiredlabels.md index 981b0e6c3..e837d8cc1 100644 --- a/website/docs/validation/requiredlabels.md +++ b/website/docs/validation/requiredlabels.md @@ -177,7 +177,6 @@ metadata: name: disallowed-namespace labels: owner: user - test: test ``` From f8a4a7e82df680b54a0d62c2071725e0a0367b73 Mon Sep 17 00:00:00 2001 From: Jaydip Gabani Date: Sat, 11 May 2024 00:11:01 +0000 Subject: [PATCH 19/23] fixing CEL code Signed-off-by: Jaydip Gabani --- .../requiredlabels/{1.0.2 => 1.1.0}/artifacthub-pkg.yml | 8 ++++---- .../requiredlabels/{1.0.2 => 1.1.0}/kustomization.yaml | 0 .../samples/all-must-have-owner/constraint.yaml | 0 .../samples/all-must-have-owner/example_allowed.yaml | 0 .../samples/all-must-have-owner/example_disallowed.yaml | 0 .../example_disallowed_label_value.yaml | 0 .../general/requiredlabels/{1.0.2 => 1.1.0}/suite.yaml | 0 .../general/requiredlabels/{1.0.2 => 1.1.0}/template.yaml | 6 +++--- library/general/requiredlabels/template.yaml | 6 +++--- src/general/requiredlabels/constraint.tmpl | 2 +- src/general/requiredlabels/src.cel | 4 ++-- website/docs/validation/requiredlabels.md | 6 +++--- 12 files changed, 16 insertions(+), 16 deletions(-) rename artifacthub/library/general/requiredlabels/{1.0.2 => 1.1.0}/artifacthub-pkg.yml (81%) rename artifacthub/library/general/requiredlabels/{1.0.2 => 1.1.0}/kustomization.yaml (100%) rename artifacthub/library/general/requiredlabels/{1.0.2 => 1.1.0}/samples/all-must-have-owner/constraint.yaml (100%) rename artifacthub/library/general/requiredlabels/{1.0.2 => 1.1.0}/samples/all-must-have-owner/example_allowed.yaml (100%) rename artifacthub/library/general/requiredlabels/{1.0.2 => 1.1.0}/samples/all-must-have-owner/example_disallowed.yaml (100%) rename artifacthub/library/general/requiredlabels/{1.0.2 => 1.1.0}/samples/all-must-have-owner/example_disallowed_label_value.yaml (100%) rename artifacthub/library/general/requiredlabels/{1.0.2 => 1.1.0}/suite.yaml (100%) rename artifacthub/library/general/requiredlabels/{1.0.2 => 1.1.0}/template.yaml (90%) diff --git a/artifacthub/library/general/requiredlabels/1.0.2/artifacthub-pkg.yml b/artifacthub/library/general/requiredlabels/1.1.0/artifacthub-pkg.yml similarity index 81% rename from artifacthub/library/general/requiredlabels/1.0.2/artifacthub-pkg.yml rename to artifacthub/library/general/requiredlabels/1.1.0/artifacthub-pkg.yml index c532b1800..395e04461 100644 --- a/artifacthub/library/general/requiredlabels/1.0.2/artifacthub-pkg.yml +++ b/artifacthub/library/general/requiredlabels/1.1.0/artifacthub-pkg.yml @@ -1,9 +1,9 @@ -version: 1.0.2 +version: 1.1.0 name: k8srequiredlabels displayName: Required Labels -createdAt: "2024-05-02T19:01:02Z" +createdAt: "2024-05-10T23:29:29Z" description: Requires resources to contain specified labels, with values matching provided regular expressions. -digest: 0bd026da84bf4f57a45d34661a9641c96eca580ccee7b3ab5f10b952f9106362 +digest: 84897cdfe60dbe9c1726581fe0626d254477a176b143a2cff36b5cf24465e8b8 license: Apache-2.0 homeURL: https://open-policy-agent.github.io/gatekeeper-library/website/requiredlabels keywords: @@ -16,7 +16,7 @@ readme: |- install: |- ### Usage ```shell - kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/artifacthub/library/general/requiredlabels/1.0.2/template.yaml + kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/artifacthub/library/general/requiredlabels/1.1.0/template.yaml ``` provider: name: Gatekeeper Library diff --git a/artifacthub/library/general/requiredlabels/1.0.2/kustomization.yaml b/artifacthub/library/general/requiredlabels/1.1.0/kustomization.yaml similarity index 100% rename from artifacthub/library/general/requiredlabels/1.0.2/kustomization.yaml rename to artifacthub/library/general/requiredlabels/1.1.0/kustomization.yaml diff --git a/artifacthub/library/general/requiredlabels/1.0.2/samples/all-must-have-owner/constraint.yaml b/artifacthub/library/general/requiredlabels/1.1.0/samples/all-must-have-owner/constraint.yaml similarity index 100% rename from artifacthub/library/general/requiredlabels/1.0.2/samples/all-must-have-owner/constraint.yaml rename to artifacthub/library/general/requiredlabels/1.1.0/samples/all-must-have-owner/constraint.yaml diff --git a/artifacthub/library/general/requiredlabels/1.0.2/samples/all-must-have-owner/example_allowed.yaml b/artifacthub/library/general/requiredlabels/1.1.0/samples/all-must-have-owner/example_allowed.yaml similarity index 100% rename from artifacthub/library/general/requiredlabels/1.0.2/samples/all-must-have-owner/example_allowed.yaml rename to artifacthub/library/general/requiredlabels/1.1.0/samples/all-must-have-owner/example_allowed.yaml diff --git a/artifacthub/library/general/requiredlabels/1.0.2/samples/all-must-have-owner/example_disallowed.yaml b/artifacthub/library/general/requiredlabels/1.1.0/samples/all-must-have-owner/example_disallowed.yaml similarity index 100% rename from artifacthub/library/general/requiredlabels/1.0.2/samples/all-must-have-owner/example_disallowed.yaml rename to artifacthub/library/general/requiredlabels/1.1.0/samples/all-must-have-owner/example_disallowed.yaml diff --git a/artifacthub/library/general/requiredlabels/1.0.2/samples/all-must-have-owner/example_disallowed_label_value.yaml b/artifacthub/library/general/requiredlabels/1.1.0/samples/all-must-have-owner/example_disallowed_label_value.yaml similarity index 100% rename from artifacthub/library/general/requiredlabels/1.0.2/samples/all-must-have-owner/example_disallowed_label_value.yaml rename to artifacthub/library/general/requiredlabels/1.1.0/samples/all-must-have-owner/example_disallowed_label_value.yaml diff --git a/artifacthub/library/general/requiredlabels/1.0.2/suite.yaml b/artifacthub/library/general/requiredlabels/1.1.0/suite.yaml similarity index 100% rename from artifacthub/library/general/requiredlabels/1.0.2/suite.yaml rename to artifacthub/library/general/requiredlabels/1.1.0/suite.yaml diff --git a/artifacthub/library/general/requiredlabels/1.0.2/template.yaml b/artifacthub/library/general/requiredlabels/1.1.0/template.yaml similarity index 90% rename from artifacthub/library/general/requiredlabels/1.0.2/template.yaml rename to artifacthub/library/general/requiredlabels/1.1.0/template.yaml index 33422f35b..d1447017e 100644 --- a/artifacthub/library/general/requiredlabels/1.0.2/template.yaml +++ b/artifacthub/library/general/requiredlabels/1.1.0/template.yaml @@ -4,7 +4,7 @@ metadata: name: k8srequiredlabels annotations: metadata.gatekeeper.sh/title: "Required Labels" - metadata.gatekeeper.sh/version: 1.0.2 + metadata.gatekeeper.sh/version: 1.1.0 description: >- Requires resources to contain specified labels, with values matching provided regular expressions. @@ -42,9 +42,9 @@ spec: - engine: K8sNativeValidation source: validations: - - expression: '(has(object.metadata) && variables.params.labels.exists_one(entry, has(object.metadata.labels) && entry.key in object.metadata.labels))' + - expression: '(has(object.metadata) && variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels))' messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' - - expression: '(has(object.metadata) && variables.params.labels.exists_one(entry, has(object.metadata.labels) && entry.key in object.metadata.labels && string(object.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' + - expression: '(has(object.metadata) && variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels && string(object.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' message: "regex mismatch" - engine: Rego source: diff --git a/library/general/requiredlabels/template.yaml b/library/general/requiredlabels/template.yaml index 33422f35b..d1447017e 100644 --- a/library/general/requiredlabels/template.yaml +++ b/library/general/requiredlabels/template.yaml @@ -4,7 +4,7 @@ metadata: name: k8srequiredlabels annotations: metadata.gatekeeper.sh/title: "Required Labels" - metadata.gatekeeper.sh/version: 1.0.2 + metadata.gatekeeper.sh/version: 1.1.0 description: >- Requires resources to contain specified labels, with values matching provided regular expressions. @@ -42,9 +42,9 @@ spec: - engine: K8sNativeValidation source: validations: - - expression: '(has(object.metadata) && variables.params.labels.exists_one(entry, has(object.metadata.labels) && entry.key in object.metadata.labels))' + - expression: '(has(object.metadata) && variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels))' messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' - - expression: '(has(object.metadata) && variables.params.labels.exists_one(entry, has(object.metadata.labels) && entry.key in object.metadata.labels && string(object.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' + - expression: '(has(object.metadata) && variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels && string(object.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' message: "regex mismatch" - engine: Rego source: diff --git a/src/general/requiredlabels/constraint.tmpl b/src/general/requiredlabels/constraint.tmpl index 217d94a5d..6de54a1ce 100644 --- a/src/general/requiredlabels/constraint.tmpl +++ b/src/general/requiredlabels/constraint.tmpl @@ -4,7 +4,7 @@ metadata: name: k8srequiredlabels annotations: metadata.gatekeeper.sh/title: "Required Labels" - metadata.gatekeeper.sh/version: 1.0.2 + metadata.gatekeeper.sh/version: 1.1.0 description: >- Requires resources to contain specified labels, with values matching provided regular expressions. diff --git a/src/general/requiredlabels/src.cel b/src/general/requiredlabels/src.cel index c52e19991..f58ff1f26 100644 --- a/src/general/requiredlabels/src.cel +++ b/src/general/requiredlabels/src.cel @@ -1,5 +1,5 @@ validations: -- expression: '(has(object.metadata) && variables.params.labels.exists_one(entry, has(object.metadata.labels) && entry.key in object.metadata.labels))' +- expression: '(has(object.metadata) && variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels))' messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' -- expression: '(has(object.metadata) && variables.params.labels.exists_one(entry, has(object.metadata.labels) && entry.key in object.metadata.labels && string(object.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' +- expression: '(has(object.metadata) && variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels && string(object.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' message: "regex mismatch" \ No newline at end of file diff --git a/website/docs/validation/requiredlabels.md b/website/docs/validation/requiredlabels.md index e837d8cc1..7ac5fbcdf 100644 --- a/website/docs/validation/requiredlabels.md +++ b/website/docs/validation/requiredlabels.md @@ -16,7 +16,7 @@ metadata: name: k8srequiredlabels annotations: metadata.gatekeeper.sh/title: "Required Labels" - metadata.gatekeeper.sh/version: 1.0.2 + metadata.gatekeeper.sh/version: 1.1.0 description: >- Requires resources to contain specified labels, with values matching provided regular expressions. @@ -54,9 +54,9 @@ spec: - engine: K8sNativeValidation source: validations: - - expression: '(has(object.metadata) && variables.params.labels.exists_one(entry, has(object.metadata.labels) && entry.key in object.metadata.labels))' + - expression: '(has(object.metadata) && variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels))' messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' - - expression: '(has(object.metadata) && variables.params.labels.exists_one(entry, has(object.metadata.labels) && entry.key in object.metadata.labels && string(object.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' + - expression: '(has(object.metadata) && variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels && string(object.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' message: "regex mismatch" - engine: Rego source: From f07d1002ff19f2de6fbf6a88c8a7a73f71ff8ff4 Mon Sep 17 00:00:00 2001 From: Jaydip Gabani Date: Sat, 11 May 2024 00:48:22 +0000 Subject: [PATCH 20/23] fixing ci Signed-off-by: Jaydip Gabani --- .github/workflows/workflow.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/workflow.yaml b/.github/workflows/workflow.yaml index 633b374b4..152c36b37 100644 --- a/.github/workflows/workflow.yaml +++ b/.github/workflows/workflow.yaml @@ -67,10 +67,10 @@ jobs: matrix: gatekeeper: [ "3.15.1", "3.16.0" ] engine: [ "cel", "rego" ] - name: "Integration test on Gatekeeper ${{ matrix.gatekeeper }}" + name: "Integration test on Gatekeeper ${{ matrix.gatekeeper }} for ${{ matrix.engine }} policies" steps: - name: Harden Runner - if: ${{ matrix.gatekeeper == '3.15.1' && matrix.engine == 'rego' }} || ${{ matrix.gatekeeper == '3.16.0' }} # remove this condition once 3.17 is out + if: ${{ (matrix.gatekeeper == '3.15.1' && matrix.engine == 'rego') || matrix.gatekeeper == '3.16.0' }} # remove this condition once 3.17 is out uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1 with: egress-policy: audit From 823c3bb1e20c930b27958a3f5a180c5072976be7 Mon Sep 17 00:00:00 2001 From: Jaydip Gabani Date: Sat, 11 May 2024 00:52:05 +0000 Subject: [PATCH 21/23] fixing ci Signed-off-by: Jaydip Gabani --- .github/workflows/workflow.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/workflow.yaml b/.github/workflows/workflow.yaml index 152c36b37..d6c6a01ce 100644 --- a/.github/workflows/workflow.yaml +++ b/.github/workflows/workflow.yaml @@ -76,11 +76,11 @@ jobs: egress-policy: audit - name: Check out code into the Go module directory - if: ${{ matrix.gatekeeper == '3.15.1' && matrix.engine == 'rego' }} || ${{ matrix.gatekeeper == '3.16.0' }} + if: ${{ (matrix.gatekeeper == '3.15.1' && matrix.engine == 'rego') || matrix.gatekeeper == '3.16.0' }} uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - name: Bootstrap integration test - if: ${{ matrix.gatekeeper == '3.15.1' && matrix.engine == 'rego' }} || ${{ matrix.gatekeeper == '3.16.0' }} + if: ${{ (matrix.gatekeeper == '3.15.1' && matrix.engine == 'rego') || matrix.gatekeeper == '3.16.0' }} run: | mkdir -p $GITHUB_WORKSPACE/bin echo "$GITHUB_WORKSPACE/bin" >> $GITHUB_PATH @@ -88,12 +88,12 @@ jobs: make deploy GATEKEEPER_VERSION=${{ matrix.gatekeeper }} POLICY_ENGINE=${{ matrix.engine }} - name: Run integration test - if: ${{ matrix.gatekeeper == '3.15.1' && matrix.engine == 'rego' }} || ${{ matrix.gatekeeper == '3.16.0' }} + if: ${{ (matrix.gatekeeper == '3.15.1' && matrix.engine == 'rego') || matrix.gatekeeper == '3.16.0' }} run: | make test-integration - name: Save logs - if: ${{ matrix.gatekeeper == '3.15.1' && matrix.engine == 'rego' }} || ${{ matrix.gatekeeper == '3.16.0' }} + if: ${{ (matrix.gatekeeper == '3.15.1' && matrix.engine == 'rego') || matrix.gatekeeper == '3.16.0' }} run: | kubectl logs -n gatekeeper-system -l control-plane=controller-manager --tail=-1 > logs-controller.json kubectl logs -n gatekeeper-system -l control-plane=audit-controller --tail=-1 > logs-audit.json From 6fe0ef292a925fde1fd9a14b45ecd8907c661137 Mon Sep 17 00:00:00 2001 From: Jaydip Gabani Date: Wed, 22 May 2024 00:13:18 +0000 Subject: [PATCH 22/23] testing with gk 3.16.1 Signed-off-by: Jaydip Gabani --- .github/workflows/workflow.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workflow.yaml b/.github/workflows/workflow.yaml index 0be4f57e9..04664b8b5 100644 --- a/.github/workflows/workflow.yaml +++ b/.github/workflows/workflow.yaml @@ -65,7 +65,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - gatekeeper: [ "3.15.1", "3.16.0" ] + gatekeeper: [ "3.15.1", "3.16.1" ] engine: [ "cel", "rego" ] name: "Integration test on Gatekeeper ${{ matrix.gatekeeper }} for ${{ matrix.engine }} policies" steps: From bfb2e894741c5fe6e8045ef51567c0f2f0f62699 Mon Sep 17 00:00:00 2001 From: Jaydip Gabani Date: Wed, 22 May 2024 01:00:43 +0000 Subject: [PATCH 23/23] testing with gk 3.16.2 Signed-off-by: Jaydip Gabani --- .github/workflows/workflow.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workflow.yaml b/.github/workflows/workflow.yaml index 04664b8b5..f72bb944f 100644 --- a/.github/workflows/workflow.yaml +++ b/.github/workflows/workflow.yaml @@ -65,7 +65,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - gatekeeper: [ "3.15.1", "3.16.1" ] + gatekeeper: [ "3.15.1", "3.16.2" ] engine: [ "cel", "rego" ] name: "Integration test on Gatekeeper ${{ matrix.gatekeeper }} for ${{ matrix.engine }} policies" steps: