From 5460bfad35ee5a9102186a87f09c7f768dee1ee1 Mon Sep 17 00:00:00 2001 From: David Papp Date: Thu, 17 Sep 2026 10:17:07 +0200 Subject: [PATCH] fix(charts): grant the operator the RBAC its own feature flags need Enabling a feature without its permissions left ingress-mode and the east-west producers silently non-functional on a default install. Gate each ClusterRole rule on the same value that turns the feature on, so the flag and the grant cannot drift apart: - ingresses/status, needed by --publish-status-address - Gateway API read + status, behind a new operator.gatewayAPI value that also drives the --gateway-api flag - pods for IdentityProducer, namespaces/networkpolicies for EdgeProducer Gateway API stays opt-in because its CRDs are not present on every cluster and an unconditional grant misleads an RBAC audit. --- charts/synapse-operator/Chart.yaml | 10 ++++-- .../templates/operator-clusterrole.yaml | 15 ++++++++ .../templates/operator-deployment.yaml | 3 ++ charts/synapse-operator/values.yaml | 7 ++++ charts/synapse-stack/Chart.yaml | 6 +++- .../templates/operator-clusterrole.yaml | 34 +++++++++++++++++++ .../operator-ingress-deployment.yaml | 3 ++ charts/synapse-stack/values.yaml | 4 +++ 8 files changed, 78 insertions(+), 4 deletions(-) diff --git a/charts/synapse-operator/Chart.yaml b/charts/synapse-operator/Chart.yaml index 8f842a4..3fe808f 100644 --- a/charts/synapse-operator/Chart.yaml +++ b/charts/synapse-operator/Chart.yaml @@ -3,9 +3,13 @@ name: synapse-operator description: Helm chart for the Synapse Kubernetes operator # Release synapse-operator v1.0.0 type: application -# Bumped: --resolve-backend-endpoints defaults ON. Requires a synapse build -# with the atomic reload-publication fix; see values.yaml. -version: 1.5.1 +# Bumped: added the missing ingresses/status grant (--publish-status-address +# was forbidden without it) and an opt-in operator.gatewayAPI that drives both +# the --gateway-api flag and its RBAC. +# +# Still from 1.5.1: --resolve-backend-endpoints defaults ON, which requires a +# synapse build with the atomic reload-publication fix; see values.yaml. +version: 1.6.0 appVersion: "0.1.11" home: https://gen0sec.com icon: https://raw.githubusercontent.com/gen0sec/helm-charts/main/images/logo.png diff --git a/charts/synapse-operator/templates/operator-clusterrole.yaml b/charts/synapse-operator/templates/operator-clusterrole.yaml index ff9bcb2..5e16b9f 100644 --- a/charts/synapse-operator/templates/operator-clusterrole.yaml +++ b/charts/synapse-operator/templates/operator-clusterrole.yaml @@ -34,6 +34,11 @@ rules: - apiGroups: ["networking.k8s.io"] resources: ["ingressclasses"] verbs: ["get", "list", "watch"] + - apiGroups: ["networking.k8s.io"] + resources: ["ingresses/status"] + # --publish-status-address writes .status.loadBalancer.ingress, which is + # what makes `kubectl get ingress` show an address. + verbs: ["get", "update", "patch"] - apiGroups: ["discovery.k8s.io"] resources: ["endpointslices"] # --resolve-backend-endpoints renders ready pod IPs as the server list, @@ -55,4 +60,14 @@ rules: - apiGroups: [""] resources: ["events"] verbs: ["create", "patch", "update"] + {{- if .Values.operator.gatewayAPI }} + # --gateway-api. Kept behind the value because the CRDs are not present on + # every cluster, and an unconditional grant misleads an RBAC audit. + - apiGroups: ["gateway.networking.k8s.io"] + resources: ["gatewayclasses", "gateways", "httproutes"] + verbs: ["get", "list", "watch"] + - apiGroups: ["gateway.networking.k8s.io"] + resources: ["gatewayclasses/status", "gateways/status", "httproutes/status"] + verbs: ["get", "update", "patch"] + {{- end }} {{- end }} diff --git a/charts/synapse-operator/templates/operator-deployment.yaml b/charts/synapse-operator/templates/operator-deployment.yaml index 2be3446..d9360b7 100644 --- a/charts/synapse-operator/templates/operator-deployment.yaml +++ b/charts/synapse-operator/templates/operator-deployment.yaml @@ -89,6 +89,9 @@ spec: {{- if .Values.operator.resolveBackendEndpoints }} - --resolve-backend-endpoints {{- end }} + {{- if .Values.operator.gatewayAPI }} + - --gateway-api + {{- end }} {{- if .Values.operator.upstreamsResolver }} - --upstreams-resolver {{- end }} diff --git a/charts/synapse-operator/values.yaml b/charts/synapse-operator/values.yaml index 0f6a73b..20e64d7 100644 --- a/charts/synapse-operator/values.yaml +++ b/charts/synapse-operator/values.yaml @@ -76,6 +76,13 @@ operator: # "/" — must exist (or operator can create it via # CreateOrUpdate). Required when ingressMode is true. upstreamsOutConfigMap: "" + # Also reconcile Gateway API (GatewayClass/Gateway/HTTPRoute) into the same + # upstreams render. Requires the Gateway API CRDs. Drives both the + # --gateway-api flag and its RBAC, so the two cannot drift apart. + # + # Ingress-mode only: the operator honours this alongside --ingress-mode, so + # setting it without ingressMode is accepted but reconciles nothing. + gatewayAPI: false # Resolve each Ingress backend's Service ClusterIP at render time so # the proxy connects directly to the pod-Service IP instead of going # through cluster DNS on every request. Avoids per-request CoreDNS diff --git a/charts/synapse-stack/Chart.yaml b/charts/synapse-stack/Chart.yaml index c06bc14..8abada2 100644 --- a/charts/synapse-stack/Chart.yaml +++ b/charts/synapse-stack/Chart.yaml @@ -3,7 +3,11 @@ name: synapse-stack description: Umbrella chart that installs the Synapse dataplane together with the Synapse operator # Release synapse-stack v0.1.5 type: application -version: 0.9.2 +# Bumped: the ClusterRole now grants what the chart's own feature flags need +# — Ingress/Gateway API for operator.ingress, Pods/Namespaces/NetworkPolicies +# for the east-west producers. Each rule is gated on the value that enables +# the feature, so permission and flag cannot drift. +version: 0.10.0 appVersion: "0.8.3" home: https://gen0sec.com icon: https://raw.githubusercontent.com/gen0sec/helm-charts/main/images/logo.png diff --git a/charts/synapse-stack/templates/operator-clusterrole.yaml b/charts/synapse-stack/templates/operator-clusterrole.yaml index 48677cc..140fb1a 100644 --- a/charts/synapse-stack/templates/operator-clusterrole.yaml +++ b/charts/synapse-stack/templates/operator-clusterrole.yaml @@ -55,4 +55,38 @@ rules: - apiGroups: [""] resources: ["events"] verbs: ["create", "patch", "update"] + {{- /* + Feature-gated rules. Each is keyed off the SAME value that turns the + feature on, so the permission and the flag can never drift apart: enabling + the feature without its RBAC is what left the east-west producers silently + non-functional on a default install. + */}} + {{- if and .Values.operator.ingress.enabled .Values.operator.ingress.gatewayAPI }} + # --gateway-api. Separate from the Ingress rules above because the CRDs are + # not present on every cluster; granting them unconditionally is harmless to + # the API server but misleading in an RBAC audit. + - apiGroups: ["gateway.networking.k8s.io"] + resources: ["gatewayclasses", "gateways", "httproutes"] + verbs: ["get", "list", "watch"] + - apiGroups: ["gateway.networking.k8s.io"] + resources: ["gatewayclasses/status", "gateways/status", "httproutes/status"] + verbs: ["get", "update", "patch"] + {{- end }} + {{- if or .Values.operator.identityProducer.enabled .Values.operator.edgeProducer.enabled }} + # IdentityProducer builds the pod-IP -> workload MMDB from Pods; EdgeProducer + # resolves NetworkPolicy peers back to the workloads they select. + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch"] + {{- end }} + {{- if .Values.operator.edgeProducer.enabled }} + # EdgeProducer compiles NetworkPolicy into the declared-edge allow-list, and + # reads Namespaces to resolve namespaceSelector peers. + - apiGroups: [""] + resources: ["namespaces"] + verbs: ["get", "list", "watch"] + - apiGroups: ["networking.k8s.io"] + resources: ["networkpolicies"] + verbs: ["get", "list", "watch"] + {{- end }} {{- end }} diff --git a/charts/synapse-stack/templates/operator-ingress-deployment.yaml b/charts/synapse-stack/templates/operator-ingress-deployment.yaml index c58f012..33bddc2 100644 --- a/charts/synapse-stack/templates/operator-ingress-deployment.yaml +++ b/charts/synapse-stack/templates/operator-ingress-deployment.yaml @@ -47,6 +47,9 @@ spec: {{- if .Values.operator.ingress.resolveBackendEndpoints }} - --resolve-backend-endpoints {{- end }} + {{- if .Values.operator.ingress.gatewayAPI }} + - --gateway-api + {{- end }} - --metrics-bind-address=:8080 - --health-probe-bind-address=:8081 {{- with .Values.operator.ingress.extraArgs }} diff --git a/charts/synapse-stack/values.yaml b/charts/synapse-stack/values.yaml index 1f6a756..508a22c 100644 --- a/charts/synapse-stack/values.yaml +++ b/charts/synapse-stack/values.yaml @@ -150,6 +150,10 @@ operator: # Falls back to ClusterIP/FQDN when the endpoint set is missing or empty # (ExternalName, headless, scaled to zero), so a route is never blanked. resolveBackendEndpoints: true + # Also reconcile Gateway API (GatewayClass/Gateway/HTTPRoute) into the same + # upstreams render. Requires the Gateway API CRDs to be installed. Drives + # both the --gateway-api flag and its RBAC, so the two cannot drift. + gatewayAPI: false extraArgs: [] resources: requests: