diff --git a/gatekeeper-config/charts/Chart.yaml b/gatekeeper-config/charts/Chart.yaml index 06962a225..3f9b32169 100644 --- a/gatekeeper-config/charts/Chart.yaml +++ b/gatekeeper-config/charts/Chart.yaml @@ -4,8 +4,8 @@ apiVersion: v2 description: Helm chart deploying OPA Gatekeeper ConstraintTemplates and Constraints for Kubernetes admission control. name: gatekeeper-config -version: 0.2.0 -appVersion: 0.2.0 +version: 0.3.0 +appVersion: 0.3.0 icon: https://raw.githubusercontent.com/open-policy-agent/gatekeeper/master/logo/gatekeeper-horizontal-color.png keywords: - gatekeeper diff --git a/gatekeeper-config/charts/templates/constraint-ingress-annotations-insecure-snippets.yaml b/gatekeeper-config/charts/templates/constraint-ingress-annotations-insecure-snippets.yaml new file mode 100644 index 000000000..877795880 --- /dev/null +++ b/gatekeeper-config/charts/templates/constraint-ingress-annotations-insecure-snippets.yaml @@ -0,0 +1,21 @@ +{{- if .Values.policies.ingressAnnotations.enabled }} +# SPDX-FileCopyrightText: 2026 SAP SE or an SAP affiliate company and Greenhouse contributors +# SPDX-License-Identifier: Apache-2.0 +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: GkIngressAnnotations +metadata: + name: ingress-annotations-insecure-snippets + labels: + severity: 'info' +spec: + enforcementAction: {{ .Values.policies.ingressAnnotations.enforcementAction }} + match: + kinds: + - apiGroups: ["networking.k8s.io"] + kinds: ["Ingress"] + scope: Namespaced + parameters: + hint: 'disabled due to CVE-2021-25742' + regexes: + - '^(?:nginx\.)?ingress\.kubernetes\.io/(?:auth|configuration|server|modsecurity)-snippet$' +{{- end }} diff --git a/gatekeeper-config/charts/templates/constraint-ingress-annotations-migration.yaml b/gatekeeper-config/charts/templates/constraint-ingress-annotations-migration.yaml new file mode 100644 index 000000000..fb09dfdb5 --- /dev/null +++ b/gatekeeper-config/charts/templates/constraint-ingress-annotations-migration.yaml @@ -0,0 +1,17 @@ +{{- if .Values.policies.ingressAnnotationsMigration.enabled }} +# SPDX-FileCopyrightText: 2026 SAP SE or an SAP affiliate company and Greenhouse contributors +# SPDX-License-Identifier: Apache-2.0 +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: GkIngressAnnotationsMigration +metadata: + name: ingress-annotations-migration + labels: + severity: 'error' +spec: + enforcementAction: {{ .Values.policies.ingressAnnotationsMigration.enforcementAction }} + match: + kinds: + - apiGroups: ["networking.k8s.io"] + kinds: ["Ingress"] + scope: Namespaced +{{- end }} diff --git a/gatekeeper-config/charts/templates/constraint-ingress-annotations-wrong-prefix.yaml b/gatekeeper-config/charts/templates/constraint-ingress-annotations-wrong-prefix.yaml new file mode 100644 index 000000000..e621cdb92 --- /dev/null +++ b/gatekeeper-config/charts/templates/constraint-ingress-annotations-wrong-prefix.yaml @@ -0,0 +1,21 @@ +{{- if .Values.policies.ingressAnnotations.enabled }} +# SPDX-FileCopyrightText: 2026 SAP SE or an SAP affiliate company and Greenhouse contributors +# SPDX-License-Identifier: Apache-2.0 +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: GkIngressAnnotations +metadata: + name: ingress-annotations-wrong-prefix + labels: + severity: 'info' +spec: + enforcementAction: {{ .Values.policies.ingressAnnotations.enforcementAction }} + match: + kinds: + - apiGroups: ["networking.k8s.io"] + kinds: ["Ingress"] + scope: Namespaced + parameters: + hint: 'use the prefix "nginx.ingress.kubernetes.io/" instead (the legacy "ingress.kubernetes.io/" prefix is deprecated)' + regexes: + - '^ingress\.kubernetes\.io/' +{{- end }} diff --git a/gatekeeper-config/charts/templates/constraint-prometheus-scrape-annotations.yaml b/gatekeeper-config/charts/templates/constraint-prometheus-scrape-annotations.yaml new file mode 100644 index 000000000..2f59f7042 --- /dev/null +++ b/gatekeeper-config/charts/templates/constraint-prometheus-scrape-annotations.yaml @@ -0,0 +1,17 @@ +{{- if .Values.policies.prometheusScrapeAnnotations.enabled }} +# SPDX-FileCopyrightText: 2026 SAP SE or an SAP affiliate company and Greenhouse contributors +# SPDX-License-Identifier: Apache-2.0 +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: GkPrometheusScrapeAnnotations +metadata: + name: prometheus-scrape-annotations + labels: + severity: 'debug' +spec: + enforcementAction: {{ .Values.policies.prometheusScrapeAnnotations.enforcementAction }} + match: + kinds: + - apiGroups: [""] + kinds: ["Pod", "Service"] + scope: Namespaced +{{- end }} diff --git a/gatekeeper-config/charts/templates/constrainttemplate-ingress-annotations-migration.yaml b/gatekeeper-config/charts/templates/constrainttemplate-ingress-annotations-migration.yaml new file mode 100644 index 000000000..e980a1ab4 --- /dev/null +++ b/gatekeeper-config/charts/templates/constrainttemplate-ingress-annotations-migration.yaml @@ -0,0 +1,55 @@ +{{- if .Values.policies.ingressAnnotationsMigration.enabled }} +# SPDX-FileCopyrightText: 2026 SAP SE or an SAP affiliate company and Greenhouse contributors +# SPDX-License-Identifier: Apache-2.0 +apiVersion: templates.gatekeeper.sh/v1 +kind: ConstraintTemplate +metadata: + name: gkingressannotationsmigration +spec: + crd: + spec: + names: + kind: GkIngressAnnotationsMigration + + targets: + - target: admission.k8s.gatekeeper.sh + code: + - engine: Rego + source: + version: "v1" + libs: + - | +{{ include "gatekeeper-config.lib.add_support_labels" . | indent 16 }} + rego: | + package ingressannotationsmigration + + import data.lib.add_support_labels + + iro := input.review.object + annotations := object.get(iro, ["metadata", "annotations"], {}) + + violation contains {"msg": add_support_labels.from_k8s_object(iro, msg)} if { + iro.kind == "Ingress" + + oldValue := annotations[oldKey] + startswith(oldKey, "ingress.kubernetes.io/") + subkey := trim_prefix(oldKey, "ingress.kubernetes.io/") + newKey := sprintf("nginx.ingress.kubernetes.io/%s", [subkey]) + newValue := object.get(annotations, [newKey], "") + + oldValue != newValue + msg := sprintf("has not correctly migrated %s annotation (value in old annotation is %q, value in new annotation is %q)", [oldKey, oldValue, newValue]) + } + + violation contains {"msg": add_support_labels.from_k8s_object(iro, msg)} if { + iro.kind == "Ingress" + + annotations[newKey] + startswith(newKey, "nginx.ingress.kubernetes.io/") + subkey := trim_prefix(newKey, "nginx.ingress.kubernetes.io/") + oldKey := sprintf("ingress.kubernetes.io/%s", [subkey]) + + object.get(annotations, [oldKey], "") == "" + msg := sprintf("has deleted %s annotation too early (still required while the legacy prefix is in use)", [oldKey]) + } +{{- end }} diff --git a/gatekeeper-config/charts/templates/constrainttemplate-ingress-annotations.yaml b/gatekeeper-config/charts/templates/constrainttemplate-ingress-annotations.yaml new file mode 100644 index 000000000..9a55a3d51 --- /dev/null +++ b/gatekeeper-config/charts/templates/constrainttemplate-ingress-annotations.yaml @@ -0,0 +1,48 @@ +{{- if .Values.policies.ingressAnnotations.enabled }} +# SPDX-FileCopyrightText: 2026 SAP SE or an SAP affiliate company and Greenhouse contributors +# SPDX-License-Identifier: Apache-2.0 +apiVersion: templates.gatekeeper.sh/v1 +kind: ConstraintTemplate +metadata: + name: gkingressannotations +spec: + crd: + spec: + names: + kind: GkIngressAnnotations + validation: + openAPIV3Schema: + type: object + properties: + hint: + type: string + regexes: + type: array + items: + type: string + + targets: + - target: admission.k8s.gatekeeper.sh + code: + - engine: Rego + source: + version: "v1" + libs: + - | +{{ include "gatekeeper-config.lib.add_support_labels" . | indent 16 }} + rego: | + package ingressannotations + + import data.lib.add_support_labels + + iro := input.review.object + annotations := object.get(iro, ["metadata", "annotations"], {}) + + violation contains {"msg": add_support_labels.from_k8s_object(iro, msg)} if { + iro.kind == "Ingress" + annotations[key] + pattern := input.parameters.regexes[_] + regex.match(pattern, key) + msg := sprintf("has disabled annotation: %q (%s)", [key, input.parameters.hint]) + } +{{- end }} diff --git a/gatekeeper-config/charts/templates/constrainttemplate-prometheus-scrape-annotations.yaml b/gatekeeper-config/charts/templates/constrainttemplate-prometheus-scrape-annotations.yaml new file mode 100644 index 000000000..4954344bd --- /dev/null +++ b/gatekeeper-config/charts/templates/constrainttemplate-prometheus-scrape-annotations.yaml @@ -0,0 +1,52 @@ +{{- if .Values.policies.prometheusScrapeAnnotations.enabled }} +# SPDX-FileCopyrightText: 2026 SAP SE or an SAP affiliate company and Greenhouse contributors +# SPDX-License-Identifier: Apache-2.0 +apiVersion: templates.gatekeeper.sh/v1 +kind: ConstraintTemplate +metadata: + name: gkprometheusscrapeannotations +spec: + crd: + spec: + names: + kind: GkPrometheusScrapeAnnotations + + targets: + - target: admission.k8s.gatekeeper.sh + code: + - engine: Rego + source: + version: "v1" + libs: + - | +{{ include "gatekeeper-config.lib.add_support_labels" . | indent 16 }} + rego: | + package prometheusscrapeannotations + + import data.lib.add_support_labels + + iro := input.review.object + + # Requires a Gatekeeper Config resource syncing + # monitoring.coreos.com/v1 Prometheus objects into the OPA cache. + # The policy defaults to disabled until that Config exists. + is_valid_target contains target if { + target := data.inventory.namespace[_]["monitoring.coreos.com/v1"].Prometheus[_].metadata.name + } + + violation contains {"msg": add_support_labels.from_k8s_object(iro, msg)} if { + regex.match("^(?:Service|Pod)$", iro.kind) + anno := object.get(iro, ["metadata", "annotations"], {}) + object.get(anno, "prometheus.io/scrape", "false") == "true" + + targets := regex.split(`\s*,\s*`, object.get(anno, "prometheus.io/targets", "")) + count(targets) != count({t | t := targets[_]; is_valid_target[_] == t}) + + all_valid_targets := {t | is_valid_target[t]} + + msg := sprintf( + "has prometheus.io/scrape annotation, but prometheus.io/targets annotation is missing or does not have a valid value (got: %s, valid: %s)", + [json.marshal(sort(targets)), json.marshal(sort(all_valid_targets))], + ) + } +{{- end }} diff --git a/gatekeeper-config/charts/values.yaml b/gatekeeper-config/charts/values.yaml index 7587dcc77..61a901933 100644 --- a/gatekeeper-config/charts/values.yaml +++ b/gatekeeper-config/charts/values.yaml @@ -37,5 +37,17 @@ policies: enforcementAction: dryrun allowlist: [] + ingressAnnotations: + enabled: true + enforcementAction: dryrun + + ingressAnnotationsMigration: + enabled: false + enforcementAction: dryrun + + prometheusScrapeAnnotations: + enabled: false + enforcementAction: dryrun + tests: enabled: false diff --git a/gatekeeper-config/plugindefinition.yaml b/gatekeeper-config/plugindefinition.yaml index 2ef2b4cdd..3e976d873 100644 --- a/gatekeeper-config/plugindefinition.yaml +++ b/gatekeeper-config/plugindefinition.yaml @@ -6,7 +6,7 @@ kind: PluginDefinition metadata: name: gatekeeper-config spec: - version: 0.2.0 + version: 0.3.0 displayName: Gatekeeper Config description: | Deploys OPA Gatekeeper ConstraintTemplates and Constraints for Kubernetes @@ -17,7 +17,7 @@ spec: helmChart: name: gatekeeper-config repository: oci://ghcr.io/cloudoperators/greenhouse-extensions/charts - version: 0.2.0 + version: 0.3.0 options: - name: policies.highCpuRequests.enabled displayName: High CPU requests policy enabled @@ -148,3 +148,45 @@ spec: is keyed by {matchNamespace, matchRepository}. required: false type: list + + - name: policies.ingressAnnotations.enabled + displayName: Ingress annotations policy enabled + description: Enable the ingress-annotations policy (flags disabled-snippet annotations and the legacy ingress.kubernetes.io/ prefix). + default: true + required: false + type: bool + - name: policies.ingressAnnotations.enforcementAction + displayName: Ingress annotations enforcement action + description: Gatekeeper enforcementAction for ingress-annotations (dryrun, warn, or deny). + default: dryrun + required: false + type: string + + - name: policies.ingressAnnotationsMigration.enabled + displayName: Ingress annotations migration policy enabled + description: Enable the ingress-annotations-migration policy (catches inconsistent or premature removal of legacy/modern annotation pairs). + default: false + required: false + type: bool + - name: policies.ingressAnnotationsMigration.enforcementAction + displayName: Ingress annotations migration enforcement action + description: Gatekeeper enforcementAction for ingress-annotations-migration (dryrun, warn, or deny). + default: dryrun + required: false + type: string + + - name: policies.prometheusScrapeAnnotations.enabled + displayName: Prometheus scrape annotations policy enabled + description: | + Enable the prometheus-scrape-annotations policy (flags prometheus.io/scrape=true + annotations without a matching prometheus.io/targets entry). Requires a Gatekeeper + Config resource syncing monitoring.coreos.com/v1 Prometheus into the OPA cache. + default: false + required: false + type: bool + - name: policies.prometheusScrapeAnnotations.enforcementAction + displayName: Prometheus scrape annotations enforcement action + description: Gatekeeper enforcementAction for prometheus-scrape-annotations (dryrun, warn, or deny). + default: dryrun + required: false + type: string diff --git a/gatekeeper-config/tests/fixtures/ingress-annotations-migration/ingress-both-matching.yaml b/gatekeeper-config/tests/fixtures/ingress-annotations-migration/ingress-both-matching.yaml new file mode 100644 index 000000000..4f7896503 --- /dev/null +++ b/gatekeeper-config/tests/fixtures/ingress-annotations-migration/ingress-both-matching.yaml @@ -0,0 +1,13 @@ +# SPDX-FileCopyrightText: 2026 SAP SE or an SAP affiliate company and Greenhouse contributors +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: both-matching + namespace: default + annotations: + ingress.kubernetes.io/auth-url: "https://auth.example.com" + nginx.ingress.kubernetes.io/auth-url: "https://auth.example.com" +spec: + rules: [] diff --git a/gatekeeper-config/tests/fixtures/ingress-annotations-migration/ingress-both-mismatched.yaml b/gatekeeper-config/tests/fixtures/ingress-annotations-migration/ingress-both-mismatched.yaml new file mode 100644 index 000000000..76c262c37 --- /dev/null +++ b/gatekeeper-config/tests/fixtures/ingress-annotations-migration/ingress-both-mismatched.yaml @@ -0,0 +1,13 @@ +# SPDX-FileCopyrightText: 2026 SAP SE or an SAP affiliate company and Greenhouse contributors +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: both-mismatched + namespace: default + annotations: + ingress.kubernetes.io/auth-url: "https://old.example.com" + nginx.ingress.kubernetes.io/auth-url: "https://new.example.com" +spec: + rules: [] diff --git a/gatekeeper-config/tests/fixtures/ingress-annotations-migration/ingress-new-only.yaml b/gatekeeper-config/tests/fixtures/ingress-annotations-migration/ingress-new-only.yaml new file mode 100644 index 000000000..5bfe69666 --- /dev/null +++ b/gatekeeper-config/tests/fixtures/ingress-annotations-migration/ingress-new-only.yaml @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: 2026 SAP SE or an SAP affiliate company and Greenhouse contributors +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: new-only + namespace: default + annotations: + nginx.ingress.kubernetes.io/auth-url: "https://auth.example.com" +spec: + rules: [] diff --git a/gatekeeper-config/tests/fixtures/ingress-annotations-migration/ingress-old-only.yaml b/gatekeeper-config/tests/fixtures/ingress-annotations-migration/ingress-old-only.yaml new file mode 100644 index 000000000..3e2c1d776 --- /dev/null +++ b/gatekeeper-config/tests/fixtures/ingress-annotations-migration/ingress-old-only.yaml @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: 2026 SAP SE or an SAP affiliate company and Greenhouse contributors +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: old-only + namespace: default + annotations: + ingress.kubernetes.io/auth-url: "https://auth.example.com" +spec: + rules: [] diff --git a/gatekeeper-config/tests/fixtures/ingress-annotations/ingress-auth-snippet-modern.yaml b/gatekeeper-config/tests/fixtures/ingress-annotations/ingress-auth-snippet-modern.yaml new file mode 100644 index 000000000..933dad8ad --- /dev/null +++ b/gatekeeper-config/tests/fixtures/ingress-annotations/ingress-auth-snippet-modern.yaml @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: 2026 SAP SE or an SAP affiliate company and Greenhouse contributors +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: auth-snippet + namespace: default + annotations: + nginx.ingress.kubernetes.io/auth-snippet: "auth_request /auth;" +spec: + rules: [] diff --git a/gatekeeper-config/tests/fixtures/ingress-annotations/ingress-legacy-prefix.yaml b/gatekeeper-config/tests/fixtures/ingress-annotations/ingress-legacy-prefix.yaml new file mode 100644 index 000000000..df5429a48 --- /dev/null +++ b/gatekeeper-config/tests/fixtures/ingress-annotations/ingress-legacy-prefix.yaml @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: 2026 SAP SE or an SAP affiliate company and Greenhouse contributors +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: legacy-prefix + namespace: default + annotations: + ingress.kubernetes.io/auth-url: "https://auth.example.com" +spec: + rules: [] diff --git a/gatekeeper-config/tests/fixtures/ingress-annotations/ingress-modern-prefix.yaml b/gatekeeper-config/tests/fixtures/ingress-annotations/ingress-modern-prefix.yaml new file mode 100644 index 000000000..eb451a465 --- /dev/null +++ b/gatekeeper-config/tests/fixtures/ingress-annotations/ingress-modern-prefix.yaml @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: 2026 SAP SE or an SAP affiliate company and Greenhouse contributors +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: modern-prefix + namespace: default + annotations: + nginx.ingress.kubernetes.io/auth-url: "https://auth.example.com" +spec: + rules: [] diff --git a/gatekeeper-config/tests/fixtures/ingress-annotations/ingress-modsecurity-snippet-legacy.yaml b/gatekeeper-config/tests/fixtures/ingress-annotations/ingress-modsecurity-snippet-legacy.yaml new file mode 100644 index 000000000..d195ca39b --- /dev/null +++ b/gatekeeper-config/tests/fixtures/ingress-annotations/ingress-modsecurity-snippet-legacy.yaml @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: 2026 SAP SE or an SAP affiliate company and Greenhouse contributors +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: modsecurity-snippet + namespace: default + annotations: + ingress.kubernetes.io/modsecurity-snippet: "SecRuleEngine On" +spec: + rules: [] diff --git a/gatekeeper-config/tests/fixtures/ingress-annotations/ingress-no-snippet.yaml b/gatekeeper-config/tests/fixtures/ingress-annotations/ingress-no-snippet.yaml new file mode 100644 index 000000000..abc806890 --- /dev/null +++ b/gatekeeper-config/tests/fixtures/ingress-annotations/ingress-no-snippet.yaml @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: 2026 SAP SE or an SAP affiliate company and Greenhouse contributors +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: clean + namespace: default + annotations: + nginx.ingress.kubernetes.io/rewrite-target: "/" +spec: + rules: [] diff --git a/gatekeeper-config/tests/fixtures/prometheus-scrape-annotations/pod-scrape-false.yaml b/gatekeeper-config/tests/fixtures/prometheus-scrape-annotations/pod-scrape-false.yaml new file mode 100644 index 000000000..088fec538 --- /dev/null +++ b/gatekeeper-config/tests/fixtures/prometheus-scrape-annotations/pod-scrape-false.yaml @@ -0,0 +1,14 @@ +# SPDX-FileCopyrightText: 2026 SAP SE or an SAP affiliate company and Greenhouse contributors +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: v1 +kind: Pod +metadata: + name: scrape-disabled + namespace: default + annotations: + prometheus.io/scrape: "false" +spec: + containers: + - name: app + image: alpine:3 diff --git a/gatekeeper-config/tests/fixtures/prometheus-scrape-annotations/pod-scrape-true-no-targets.yaml b/gatekeeper-config/tests/fixtures/prometheus-scrape-annotations/pod-scrape-true-no-targets.yaml new file mode 100644 index 000000000..ea5edc28e --- /dev/null +++ b/gatekeeper-config/tests/fixtures/prometheus-scrape-annotations/pod-scrape-true-no-targets.yaml @@ -0,0 +1,14 @@ +# SPDX-FileCopyrightText: 2026 SAP SE or an SAP affiliate company and Greenhouse contributors +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: v1 +kind: Pod +metadata: + name: scrape-missing-targets + namespace: default + annotations: + prometheus.io/scrape: "true" +spec: + containers: + - name: app + image: alpine:3 diff --git a/gatekeeper-config/tests/fixtures/prometheus-scrape-annotations/service-scrape-true-no-targets.yaml b/gatekeeper-config/tests/fixtures/prometheus-scrape-annotations/service-scrape-true-no-targets.yaml new file mode 100644 index 000000000..0c7a51556 --- /dev/null +++ b/gatekeeper-config/tests/fixtures/prometheus-scrape-annotations/service-scrape-true-no-targets.yaml @@ -0,0 +1,15 @@ +# SPDX-FileCopyrightText: 2026 SAP SE or an SAP affiliate company and Greenhouse contributors +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: v1 +kind: Service +metadata: + name: scrape-svc + namespace: default + annotations: + prometheus.io/scrape: "true" +spec: + selector: + app: example + ports: + - port: 80 diff --git a/gatekeeper-config/tests/suite.yaml b/gatekeeper-config/tests/suite.yaml index e4f53cf68..561495daa 100644 --- a/gatekeeper-config/tests/suite.yaml +++ b/gatekeeper-config/tests/suite.yaml @@ -262,3 +262,79 @@ tests: assertions: - violations: 1 message: '^\{"owned_by":"none"\} >> pod is not allowed to set spec\.containers\["app"\]\.securityContext\.capabilities\.add = \["NET_ADMIN"\] \(image = "alpine"\)$' + +- name: ingress-annotations-insecure-snippets + template: rendered/gatekeeper-config/templates/constrainttemplate-ingress-annotations.yaml + constraint: rendered/gatekeeper-config/templates/constraint-ingress-annotations-insecure-snippets.yaml + cases: + - name: ingress-auth-snippet-modern + object: fixtures/ingress-annotations/ingress-auth-snippet-modern.yaml + assertions: + - violations: 1 + message: '^\{"owned_by":"none"\} >> has disabled annotation: "nginx\.ingress\.kubernetes\.io/auth-snippet" \(disabled due to CVE-2021-25742\)$' + - name: ingress-modsecurity-snippet-legacy + object: fixtures/ingress-annotations/ingress-modsecurity-snippet-legacy.yaml + assertions: + - violations: 1 + message: '^\{"owned_by":"none"\} >> has disabled annotation: "ingress\.kubernetes\.io/modsecurity-snippet" \(disabled due to CVE-2021-25742\)$' + - name: ingress-no-snippet + object: fixtures/ingress-annotations/ingress-no-snippet.yaml + assertions: + - violations: 0 + +- name: ingress-annotations-wrong-prefix + template: rendered/gatekeeper-config/templates/constrainttemplate-ingress-annotations.yaml + constraint: rendered/gatekeeper-config/templates/constraint-ingress-annotations-wrong-prefix.yaml + cases: + - name: ingress-legacy-prefix + object: fixtures/ingress-annotations/ingress-legacy-prefix.yaml + assertions: + - violations: 1 + message: '^\{"owned_by":"none"\} >> has disabled annotation: "ingress\.kubernetes\.io/auth-url" \(use the prefix "nginx\.ingress\.kubernetes\.io/" instead \(the legacy "ingress\.kubernetes\.io/" prefix is deprecated\)\)$' + - name: ingress-modern-prefix + object: fixtures/ingress-annotations/ingress-modern-prefix.yaml + assertions: + - violations: 0 + +- name: ingress-annotations-migration + template: rendered/gatekeeper-config/templates/constrainttemplate-ingress-annotations-migration.yaml + constraint: rendered/gatekeeper-config/templates/constraint-ingress-annotations-migration.yaml + cases: + - name: ingress-old-only + object: fixtures/ingress-annotations-migration/ingress-old-only.yaml + assertions: + - violations: 1 + message: '^\{"owned_by":"none"\} >> has not correctly migrated ingress\.kubernetes\.io/auth-url annotation \(value in old annotation is "https://auth\.example\.com", value in new annotation is ""\)$' + - name: ingress-new-only + object: fixtures/ingress-annotations-migration/ingress-new-only.yaml + assertions: + - violations: 1 + message: '^\{"owned_by":"none"\} >> has deleted ingress\.kubernetes\.io/auth-url annotation too early \(still required while the legacy prefix is in use\)$' + - name: ingress-both-matching + object: fixtures/ingress-annotations-migration/ingress-both-matching.yaml + assertions: + - violations: 0 + - name: ingress-both-mismatched + object: fixtures/ingress-annotations-migration/ingress-both-mismatched.yaml + assertions: + - violations: 1 + message: '^\{"owned_by":"none"\} >> has not correctly migrated ingress\.kubernetes\.io/auth-url annotation \(value in old annotation is "https://old\.example\.com", value in new annotation is "https://new\.example\.com"\)$' + +- name: prometheus-scrape-annotations + template: rendered/gatekeeper-config/templates/constrainttemplate-prometheus-scrape-annotations.yaml + constraint: rendered/gatekeeper-config/templates/constraint-prometheus-scrape-annotations.yaml + cases: + - name: pod-scrape-true-no-targets + object: fixtures/prometheus-scrape-annotations/pod-scrape-true-no-targets.yaml + assertions: + - violations: 1 + message: '^\{"owned_by":"none"\} >> has prometheus\.io/scrape annotation, but prometheus\.io/targets annotation is missing or does not have a valid value \(got: \[""\], valid: \[\]\)$' + - name: pod-scrape-false + object: fixtures/prometheus-scrape-annotations/pod-scrape-false.yaml + assertions: + - violations: 0 + - name: service-scrape-true-no-targets + object: fixtures/prometheus-scrape-annotations/service-scrape-true-no-targets.yaml + assertions: + - violations: 1 + message: '^\{"owned_by":"none"\} >> has prometheus\.io/scrape annotation, but prometheus\.io/targets annotation is missing or does not have a valid value \(got: \[""\], valid: \[\]\)$' diff --git a/gatekeeper-config/tests/values-test.yaml b/gatekeeper-config/tests/values-test.yaml index b01ed7a51..76aaf9207 100644 --- a/gatekeeper-config/tests/values-test.yaml +++ b/gatekeeper-config/tests/values-test.yaml @@ -39,5 +39,12 @@ policies: mayReadHostPathVolumes: [] mayWriteHostPathVolumes: [] + ingressAnnotations: + enabled: true + ingressAnnotationsMigration: + enabled: true + prometheusScrapeAnnotations: + enabled: true + tests: enabled: true