From 380e8e969b5a0dc5a49947e4c8a5cc2e389fa044 Mon Sep 17 00:00:00 2001 From: Piotr Reszke Date: Thu, 28 May 2026 14:00:25 +0200 Subject: [PATCH 1/4] fix: add gateway to ingress mode validation, validate required fields MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ingress.mode validation in ingress.yaml rejects "gateway" even though httproute.yaml renders for that mode. Also add required-field validation for gateway.name and gateway.namespace — without these the HTTPRoute renders with empty parentRefs. --- templates/httproute.yaml | 6 ++++++ templates/ingress.yaml | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/templates/httproute.yaml b/templates/httproute.yaml index bf4548f..8dbc934 100644 --- a/templates/httproute.yaml +++ b/templates/httproute.yaml @@ -1,4 +1,10 @@ {{- if and .Values.ingress.enabled (eq (.Values.ingress.mode | default "default") "gateway") }} +{{- if not .Values.ingress.gateway.name }} +{{- fail "ingress.gateway.name is required when ingress.mode=gateway" }} +{{- end }} +{{- if not .Values.ingress.gateway.namespace }} +{{- fail "ingress.gateway.namespace is required when ingress.mode=gateway" }} +{{- end }} apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: diff --git a/templates/ingress.yaml b/templates/ingress.yaml index 45b792c..8740c97 100644 --- a/templates/ingress.yaml +++ b/templates/ingress.yaml @@ -1,7 +1,7 @@ {{- if .Values.ingress.enabled }} {{- $mode := .Values.ingress.mode | default "default" }} -{{- if not (has $mode (list "aws" "nginx" "default")) }} -{{- fail (printf "ingress.mode must be one of: aws, nginx, default (got %q)" $mode) }} +{{- if not (has $mode (list "aws" "nginx" "gateway" "default")) }} +{{- fail (printf "ingress.mode must be one of: aws, nginx, gateway, default (got %q)" $mode) }} {{- end }} {{- if eq $mode "default" }} apiVersion: networking.k8s.io/v1 From f9b019230d4257f2d80ab30b5dc0a1745e4a0323 Mon Sep 17 00:00:00 2001 From: Piotr Reszke Date: Thu, 28 May 2026 14:12:45 +0200 Subject: [PATCH 2/4] chore: bump chart version to 0.2.3 --- Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Chart.yaml b/Chart.yaml index 21d2610..2b636b3 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -2,5 +2,5 @@ apiVersion: v2 name: pgdog-control description: PgDog Control type: application -version: 0.2.2 +version: 0.2.3 appVersion: "v2026-05-21" From 8ce86cee3e61d7b3b56af8da8cc3042f02e7c3c8 Mon Sep 17 00:00:00 2001 From: Piotr Reszke Date: Thu, 28 May 2026 14:16:44 +0200 Subject: [PATCH 3/4] feat: make securityContext configurable via values Move hardcoded securityContext from deployment templates to values.yaml with PSS Restricted compliant defaults. Operators can now override pod and container securityContext without monkey-patching. New values: control.podSecurityContext (default: runAsNonRoot, uid 1000, seccomp) control.containerSecurityContext (default: no priv esc, drop ALL) redis.podSecurityContext (default: runAsNonRoot, uid 999, seccomp) redis.containerSecurityContext (default: no priv esc, readonly rootfs, drop ALL) --- templates/deployment.yaml | 14 ++++++-------- templates/redis-deployment.yaml | 16 ++++++---------- values.yaml | 26 ++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 18 deletions(-) diff --git a/templates/deployment.yaml b/templates/deployment.yaml index cbf7c31..092a40c 100644 --- a/templates/deployment.yaml +++ b/templates/deployment.yaml @@ -48,12 +48,10 @@ spec: {{- else }} automountServiceAccountToken: false {{- end }} + {{- with .Values.control.podSecurityContext }} securityContext: - runAsNonRoot: true - runAsUser: 1000 - runAsGroup: 1000 - seccompProfile: - type: RuntimeDefault + {{- toYaml . | nindent 8 }} + {{- end }} {{- with .Values.image.pullSecrets }} imagePullSecrets: {{- toYaml . | nindent 8 }} @@ -62,10 +60,10 @@ spec: - name: control image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- with .Values.control.containerSecurityContext }} securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: ["ALL"] + {{- toYaml . | nindent 10 }} + {{- end }} env: - name: CONTROL_CONFIG value: /etc/pgdog-control/control.toml diff --git a/templates/redis-deployment.yaml b/templates/redis-deployment.yaml index 2222387..03ce85f 100644 --- a/templates/redis-deployment.yaml +++ b/templates/redis-deployment.yaml @@ -17,21 +17,17 @@ spec: cluster-autoscaler.kubernetes.io/safe-to-evict: "false" spec: automountServiceAccountToken: false + {{- with .Values.redis.podSecurityContext }} securityContext: - runAsNonRoot: true - runAsUser: 999 - runAsGroup: 999 - fsGroup: 999 - seccompProfile: - type: RuntimeDefault + {{- toYaml . | nindent 8 }} + {{- end }} containers: - name: redis image: redis:7-alpine + {{- with .Values.redis.containerSecurityContext }} securityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - capabilities: - drop: ["ALL"] + {{- toYaml . | nindent 10 }} + {{- end }} ports: - containerPort: 6379 name: redis diff --git a/values.yaml b/values.yaml index 12e50d9..b957d5d 100644 --- a/values.yaml +++ b/values.yaml @@ -50,6 +50,20 @@ control: limits: memory: "4Gi" cpu: "1000m" + # Pod-level securityContext for the control deployment. + # Defaults are PSS Restricted compliant. + podSecurityContext: + runAsNonRoot: true + runAsUser: 1000 + runAsGroup: 1000 + seccompProfile: + type: RuntimeDefault + # Container-level securityContext for the control container. + # Defaults are PSS Restricted compliant. + containerSecurityContext: + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] # Runtime configuration written to /etc/pgdog-control/control.toml. # Mirrors control2/src/config.rs. Every field is optional — anything left # unset falls back to the Rust-side default. Field names match the TOML @@ -99,6 +113,18 @@ redis: limits: memory: "256Mi" cpu: "500m" + podSecurityContext: + runAsNonRoot: true + runAsUser: 999 + runAsGroup: 999 + fsGroup: 999 + seccompProfile: + type: RuntimeDefault + containerSecurityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: ["ALL"] networkPolicy: enabled: false From c993051b66d657268a4b8892274a8eddaf2f30a0 Mon Sep 17 00:00:00 2001 From: Piotr Reszke Date: Thu, 28 May 2026 14:36:45 +0200 Subject: [PATCH 4/4] fix: add readOnlyRootFilesystem to control, quote gateway refs, add redis comments - Add readOnlyRootFilesystem: true to control containerSecurityContext defaults (matches redis, tested working on EKS staging) - Add comments above redis securityContext values for parity with control - Quote gateway name/namespace in httproute.yaml for defensive correctness --- templates/httproute.yaml | 4 ++-- values.yaml | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/templates/httproute.yaml b/templates/httproute.yaml index 8dbc934..1d4b447 100644 --- a/templates/httproute.yaml +++ b/templates/httproute.yaml @@ -22,8 +22,8 @@ spec: parentRefs: - group: gateway.networking.k8s.io kind: Gateway - name: {{ .Values.ingress.gateway.name }} - namespace: {{ .Values.ingress.gateway.namespace }} + name: {{ .Values.ingress.gateway.name | quote }} + namespace: {{ .Values.ingress.gateway.namespace | quote }} {{- with .Values.ingress.gateway.sectionName }} sectionName: {{ . }} {{- end }} diff --git a/values.yaml b/values.yaml index b957d5d..c7eb5b2 100644 --- a/values.yaml +++ b/values.yaml @@ -62,6 +62,7 @@ control: # Defaults are PSS Restricted compliant. containerSecurityContext: allowPrivilegeEscalation: false + readOnlyRootFilesystem: true capabilities: drop: ["ALL"] # Runtime configuration written to /etc/pgdog-control/control.toml. @@ -113,6 +114,8 @@ redis: limits: memory: "256Mi" cpu: "500m" + # Pod-level securityContext for the Redis deployment. + # Defaults are PSS Restricted compliant. podSecurityContext: runAsNonRoot: true runAsUser: 999 @@ -120,6 +123,8 @@ redis: fsGroup: 999 seccompProfile: type: RuntimeDefault + # Container-level securityContext for the Redis container. + # Defaults are PSS Restricted compliant. containerSecurityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true