From 5fba10fa2d74f885f7ada9b23efc5be532103987 Mon Sep 17 00:00:00 2001 From: MergeCheck Date: Fri, 3 Jul 2026 13:46:25 -0300 Subject: [PATCH 1/4] fix(envoy-gateway): align template standards --- charts/envoy-gateway/templates/_helpers.tpl | 25 ++++++++++ .../envoy-gateway/templates/certgen-job.yaml | 2 +- .../templates/networkpolicy.yaml | 3 ++ charts/envoy-gateway/templates/validate.yaml | 2 + charts/envoy-gateway/tests/certgen_test.yaml | 14 ++++++ charts/envoy-gateway/tests/security_test.yaml | 25 ++++++++++ .../envoy-gateway/tests/validation_test.yaml | 48 +++++++++++++++++++ charts/envoy-gateway/values.schema.json | 12 +++++ charts/envoy-gateway/values.yaml | 3 ++ 9 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 charts/envoy-gateway/templates/validate.yaml create mode 100644 charts/envoy-gateway/tests/validation_test.yaml diff --git a/charts/envoy-gateway/templates/_helpers.tpl b/charts/envoy-gateway/templates/_helpers.tpl index 07c6c19a2..f72a3685b 100644 --- a/charts/envoy-gateway/templates/_helpers.tpl +++ b/charts/envoy-gateway/templates/_helpers.tpl @@ -235,3 +235,28 @@ affinity: {{- toYaml $affinity | nindent 2 }} {{- end }} {{- end }} + +{{/* +Central fail-fast validation entrypoint. +*/}} +{{- define "envoy-gateway.validate" -}} +{{- if and .Values.externalSecrets.enabled (not .Values.rateLimiting.externalRedis.auth.secretName) -}} +{{- fail "externalSecrets.enabled requires rateLimiting.externalRedis.auth.secretName to be set to prevent credential drift between the chart-managed Secret and the ExternalSecret." -}} +{{- end -}} +{{- if and .Values.rateLimiting.enabled (not .Values.redis.enabled) (not .Values.rateLimiting.externalRedis.host) -}} +{{- fail "rateLimiting.enabled requires redis.enabled=true or rateLimiting.externalRedis.host to be set" -}} +{{- end -}} +{{- if and .Values.rateLimiting.externalRedis.auth.enabled (not .Values.rateLimiting.externalRedis.auth.secretName) -}} +{{- fail "rateLimiting.externalRedis.auth.enabled requires rateLimiting.externalRedis.auth.secretName" -}} +{{- end -}} +{{- $podLabels := .Values.podLabels | default dict -}} +{{- if hasKey $podLabels "app.kubernetes.io/name" -}} +{{- fail "podLabels must not override selector label app.kubernetes.io/name" -}} +{{- end -}} +{{- if hasKey $podLabels "app.kubernetes.io/instance" -}} +{{- fail "podLabels must not override selector label app.kubernetes.io/instance" -}} +{{- end -}} +{{- if hasKey $podLabels "app.kubernetes.io/component" -}} +{{- fail "podLabels must not override selector label app.kubernetes.io/component" -}} +{{- end -}} +{{- end -}} diff --git a/charts/envoy-gateway/templates/certgen-job.yaml b/charts/envoy-gateway/templates/certgen-job.yaml index 2cde00cee..a2652eb01 100644 --- a/charts/envoy-gateway/templates/certgen-job.yaml +++ b/charts/envoy-gateway/templates/certgen-job.yaml @@ -67,7 +67,7 @@ spec: template: metadata: labels: - {{- include "envoy-gateway.labels" . | nindent 8 }} + {{- include "envoy-gateway.selectorLabels" . | nindent 8 }} app.kubernetes.io/component: certgen spec: serviceAccountName: {{ $fullName }}-certgen diff --git a/charts/envoy-gateway/templates/networkpolicy.yaml b/charts/envoy-gateway/templates/networkpolicy.yaml index 3334e01f6..15cb1e947 100644 --- a/charts/envoy-gateway/templates/networkpolicy.yaml +++ b/charts/envoy-gateway/templates/networkpolicy.yaml @@ -49,6 +49,9 @@ spec: port: 53 - protocol: UDP port: 53 + {{- with .Values.security.networkPolicy.extraEgress }} + {{- toYaml . | nindent 2 }} + {{- end }} {{- if and .Values.rateLimiting.enabled .Values.redis.enabled }} --- apiVersion: networking.k8s.io/v1 diff --git a/charts/envoy-gateway/templates/validate.yaml b/charts/envoy-gateway/templates/validate.yaml new file mode 100644 index 000000000..ba97da839 --- /dev/null +++ b/charts/envoy-gateway/templates/validate.yaml @@ -0,0 +1,2 @@ +{{/* SPDX-License-Identifier: Apache-2.0 */}} +{{- include "envoy-gateway.validate" . -}} diff --git a/charts/envoy-gateway/tests/certgen_test.yaml b/charts/envoy-gateway/tests/certgen_test.yaml index 01390162a..b727e15c3 100644 --- a/charts/envoy-gateway/tests/certgen_test.yaml +++ b/charts/envoy-gateway/tests/certgen_test.yaml @@ -47,6 +47,20 @@ tests: content: --disable-topology-injector documentIndex: 3 + - it: should keep certgen pod labels limited to selector labels and component + asserts: + - notExists: + path: spec.template.metadata.labels["helm.sh/chart"] + documentIndex: 3 + - equal: + path: spec.template.metadata.labels["app.kubernetes.io/name"] + value: envoy-gateway + documentIndex: 3 + - equal: + path: spec.template.metadata.labels["app.kubernetes.io/component"] + value: certgen + documentIndex: 3 + - it: should have pre-install hook annotation on Job asserts: - equal: diff --git a/charts/envoy-gateway/tests/security_test.yaml b/charts/envoy-gateway/tests/security_test.yaml index b9388e870..337847035 100644 --- a/charts/envoy-gateway/tests/security_test.yaml +++ b/charts/envoy-gateway/tests/security_test.yaml @@ -42,6 +42,31 @@ tests: count: 0 template: networkpolicy.yaml + - it: should append controller extra egress rules + set: + security: + networkPolicies: true + networkPolicy: + extraEgress: + - to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: observability + ports: + - protocol: TCP + port: 4317 + asserts: + - equal: + path: spec.egress[2].to[0].namespaceSelector.matchLabels["kubernetes.io/metadata.name"] + value: observability + template: networkpolicy.yaml + documentIndex: 0 + - equal: + path: spec.egress[2].ports[0].port + value: 4317 + template: networkpolicy.yaml + documentIndex: 0 + - it: should create NetworkPolicies for Redis and ratelimit when rate limiting enabled set: namespaceOverride: envoy-system diff --git a/charts/envoy-gateway/tests/validation_test.yaml b/charts/envoy-gateway/tests/validation_test.yaml new file mode 100644 index 000000000..3c370f462 --- /dev/null +++ b/charts/envoy-gateway/tests/validation_test.yaml @@ -0,0 +1,48 @@ +# SPDX-License-Identifier: Apache-2.0 +suite: Validation +templates: + - validate.yaml +tests: + - it: should reject rate limiting without redis backend + set: + rateLimiting: + enabled: true + redis: + enabled: false + asserts: + - failedTemplate: + errorMessage: "rateLimiting.enabled requires redis.enabled=true or rateLimiting.externalRedis.host to be set" + + - it: should reject external redis auth without secret + set: + rateLimiting: + externalRedis: + host: redis.example.com + auth: + enabled: true + secretName: "" + asserts: + - failedTemplate: + errorMessage: "rateLimiting.externalRedis.auth.enabled requires rateLimiting.externalRedis.auth.secretName" + + - it: should reject external secrets without external redis auth secret + set: + externalSecrets: + enabled: true + asserts: + - failedTemplate: + errorMessage: "externalSecrets.enabled requires rateLimiting.externalRedis.auth.secretName to be set to prevent credential drift between the chart-managed Secret and the ExternalSecret." + + - it: should reject reserved pod label overrides + set: + podLabels: + app.kubernetes.io/component: custom + asserts: + - failedTemplate: + errorMessage: "podLabels must not override selector label app.kubernetes.io/component" + + - it: should allow null pod labels + set: + podLabels: null + asserts: + - notFailedTemplate: {} diff --git a/charts/envoy-gateway/values.schema.json b/charts/envoy-gateway/values.schema.json index ac42077ba..c029bbb36 100644 --- a/charts/envoy-gateway/values.schema.json +++ b/charts/envoy-gateway/values.schema.json @@ -638,6 +638,18 @@ "description": "Enable NetworkPolicies for zero-trust networking", "default": false }, + "networkPolicy": { + "type": "object", + "description": "NetworkPolicy rule extensions", + "properties": { + "extraEgress": { + "type": "array", + "description": "Additional complete egress rules appended to the controller NetworkPolicy", + "items": { "type": "object" }, + "default": [] + } + } + }, "podSecurityStandards": { "type": "boolean", "description": "Enable PodSecurityStandard restricted mode", diff --git a/charts/envoy-gateway/values.yaml b/charts/envoy-gateway/values.yaml index 0410e2a45..295f72862 100644 --- a/charts/envoy-gateway/values.yaml +++ b/charts/envoy-gateway/values.yaml @@ -386,6 +386,9 @@ monitoring: security: # -- Enable NetworkPolicies networkPolicies: false + networkPolicy: + # -- Additional complete egress rules appended to the controller NetworkPolicy + extraEgress: [] # -- Enable PodSecurityStandard restricted podSecurityStandards: true From 2564cc87e16ee021b02f6861fb105faa00b8c055 Mon Sep 17 00:00:00 2001 From: MergeCheck Date: Fri, 3 Jul 2026 13:57:11 -0300 Subject: [PATCH 2/4] fix(envoy-gateway): refine validation guards --- charts/envoy-gateway/templates/_helpers.tpl | 2 +- charts/envoy-gateway/templates/validate.yaml | 2 +- charts/envoy-gateway/tests/validation_test.yaml | 16 ++++++++++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/charts/envoy-gateway/templates/_helpers.tpl b/charts/envoy-gateway/templates/_helpers.tpl index f72a3685b..bd546e1a3 100644 --- a/charts/envoy-gateway/templates/_helpers.tpl +++ b/charts/envoy-gateway/templates/_helpers.tpl @@ -246,7 +246,7 @@ Central fail-fast validation entrypoint. {{- if and .Values.rateLimiting.enabled (not .Values.redis.enabled) (not .Values.rateLimiting.externalRedis.host) -}} {{- fail "rateLimiting.enabled requires redis.enabled=true or rateLimiting.externalRedis.host to be set" -}} {{- end -}} -{{- if and .Values.rateLimiting.externalRedis.auth.enabled (not .Values.rateLimiting.externalRedis.auth.secretName) -}} +{{- if and .Values.rateLimiting.enabled (not .Values.redis.enabled) .Values.rateLimiting.externalRedis.host .Values.rateLimiting.externalRedis.auth.enabled (not .Values.rateLimiting.externalRedis.auth.secretName) -}} {{- fail "rateLimiting.externalRedis.auth.enabled requires rateLimiting.externalRedis.auth.secretName" -}} {{- end -}} {{- $podLabels := .Values.podLabels | default dict -}} diff --git a/charts/envoy-gateway/templates/validate.yaml b/charts/envoy-gateway/templates/validate.yaml index ba97da839..ebad63614 100644 --- a/charts/envoy-gateway/templates/validate.yaml +++ b/charts/envoy-gateway/templates/validate.yaml @@ -1,2 +1,2 @@ -{{/* SPDX-License-Identifier: Apache-2.0 */}} +# SPDX-License-Identifier: Apache-2.0 {{- include "envoy-gateway.validate" . -}} diff --git a/charts/envoy-gateway/tests/validation_test.yaml b/charts/envoy-gateway/tests/validation_test.yaml index 3c370f462..87fbb0a44 100644 --- a/charts/envoy-gateway/tests/validation_test.yaml +++ b/charts/envoy-gateway/tests/validation_test.yaml @@ -16,15 +16,31 @@ tests: - it: should reject external redis auth without secret set: rateLimiting: + enabled: true externalRedis: host: redis.example.com auth: enabled: true secretName: "" + redis: + enabled: false asserts: - failedTemplate: errorMessage: "rateLimiting.externalRedis.auth.enabled requires rateLimiting.externalRedis.auth.secretName" + - it: should allow unused external redis auth settings + set: + rateLimiting: + enabled: false + externalRedis: + auth: + enabled: true + secretName: "" + redis: + enabled: true + asserts: + - notFailedTemplate: {} + - it: should reject external secrets without external redis auth secret set: externalSecrets: From bed186124737465430d405fb75ee2dce224ac64e Mon Sep 17 00:00:00 2001 From: MergeCheck Date: Sun, 5 Jul 2026 04:14:28 -0300 Subject: [PATCH 3/4] fix(envoy-gateway): disable yamllint for validate include --- charts/envoy-gateway/templates/validate.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/charts/envoy-gateway/templates/validate.yaml b/charts/envoy-gateway/templates/validate.yaml index ebad63614..97bc07fd0 100644 --- a/charts/envoy-gateway/templates/validate.yaml +++ b/charts/envoy-gateway/templates/validate.yaml @@ -1,2 +1,3 @@ +# yamllint disable-file # SPDX-License-Identifier: Apache-2.0 {{- include "envoy-gateway.validate" . -}} From 4d4a1a179a7897140cf1619dac0863b1ee29ebe2 Mon Sep 17 00:00:00 2001 From: MergeCheck Date: Sun, 5 Jul 2026 17:30:32 -0300 Subject: [PATCH 4/4] fix(envoy-gateway): derive reserved pod label keys --- charts/envoy-gateway/README.md | 2 +- charts/envoy-gateway/templates/_helpers.tpl | 11 ++++------- charts/envoy-gateway/values.schema.json | 4 ++-- charts/envoy-gateway/values.yaml | 4 ++-- 4 files changed, 9 insertions(+), 12 deletions(-) diff --git a/charts/envoy-gateway/README.md b/charts/envoy-gateway/README.md index 9185716ef..5667d0434 100644 --- a/charts/envoy-gateway/README.md +++ b/charts/envoy-gateway/README.md @@ -314,7 +314,7 @@ highAvailability: | Key | Default | Description | |-----|---------|-------------| -| `security.networkPolicies` | `false` | Enable NetworkPolicies | +| `security.networkPolicies` | `false` | Enable rendering of NetworkPolicy resources | | `security.podSecurityStandards` | `true` | Enable PodSecurityStandards (restricted mode) | ### High Availability diff --git a/charts/envoy-gateway/templates/_helpers.tpl b/charts/envoy-gateway/templates/_helpers.tpl index bd546e1a3..c689b0b24 100644 --- a/charts/envoy-gateway/templates/_helpers.tpl +++ b/charts/envoy-gateway/templates/_helpers.tpl @@ -250,13 +250,10 @@ Central fail-fast validation entrypoint. {{- fail "rateLimiting.externalRedis.auth.enabled requires rateLimiting.externalRedis.auth.secretName" -}} {{- end -}} {{- $podLabels := .Values.podLabels | default dict -}} -{{- if hasKey $podLabels "app.kubernetes.io/name" -}} -{{- fail "podLabels must not override selector label app.kubernetes.io/name" -}} +{{- $selectorLabels := include "envoy-gateway.controller.selectorLabels" . | fromYaml -}} +{{- range $key, $_ := $selectorLabels -}} +{{- if hasKey $podLabels $key -}} +{{- fail (printf "podLabels must not override selector label %s" $key) -}} {{- end -}} -{{- if hasKey $podLabels "app.kubernetes.io/instance" -}} -{{- fail "podLabels must not override selector label app.kubernetes.io/instance" -}} -{{- end -}} -{{- if hasKey $podLabels "app.kubernetes.io/component" -}} -{{- fail "podLabels must not override selector label app.kubernetes.io/component" -}} {{- end -}} {{- end -}} diff --git a/charts/envoy-gateway/values.schema.json b/charts/envoy-gateway/values.schema.json index c029bbb36..948e14d6e 100644 --- a/charts/envoy-gateway/values.schema.json +++ b/charts/envoy-gateway/values.schema.json @@ -635,12 +635,12 @@ "properties": { "networkPolicies": { "type": "boolean", - "description": "Enable NetworkPolicies for zero-trust networking", + "description": "Enable rendering of NetworkPolicy resources for zero-trust networking", "default": false }, "networkPolicy": { "type": "object", - "description": "NetworkPolicy rule extensions", + "description": "NetworkPolicy rule extensions used when security.networkPolicies is enabled", "properties": { "extraEgress": { "type": "array", diff --git a/charts/envoy-gateway/values.yaml b/charts/envoy-gateway/values.yaml index 295f72862..88d6ca777 100644 --- a/charts/envoy-gateway/values.yaml +++ b/charts/envoy-gateway/values.yaml @@ -384,10 +384,10 @@ monitoring: ## Security and Hardening security: - # -- Enable NetworkPolicies + # -- Enable rendering of NetworkPolicy resources networkPolicies: false networkPolicy: - # -- Additional complete egress rules appended to the controller NetworkPolicy + # -- Additional complete egress rules appended to the controller NetworkPolicy when security.networkPolicies is enabled extraEgress: [] # -- Enable PodSecurityStandard restricted podSecurityStandards: true