From 358c8be211988a148e9bf38aaea0835f88fb7856 Mon Sep 17 00:00:00 2001 From: Przemyslaw Roguski Date: Tue, 12 May 2026 11:38:54 +0200 Subject: [PATCH] Add optional NetworkPolicy templates for namespace isolation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a default-deny NetworkPolicy and per-pod allow rule templates for keycloak, postgresql-db, and rhbk-operator pods. All disabled by default — patterns opt in via values. The RHBK operator-managed ingress policy is left untouched; the keycloak template covers egress only. Co-Authored-By: Claude Opus 4.6 (1M context) --- README.md.gotmpl | 85 +++++++++++++++++++ templates/default-deny-network-policy.yaml | 12 +++ templates/keycloak-egress-network-policy.yaml | 19 +++++ templates/operator-network-policy.yaml | 22 +++++ templates/postgresql-network-policy.yaml | 22 +++++ values.yaml | 26 ++++++ 6 files changed, 186 insertions(+) create mode 100644 templates/default-deny-network-policy.yaml create mode 100644 templates/keycloak-egress-network-policy.yaml create mode 100644 templates/operator-network-policy.yaml create mode 100644 templates/postgresql-network-policy.yaml diff --git a/README.md.gotmpl b/README.md.gotmpl index c426f84..ac41351 100644 --- a/README.md.gotmpl +++ b/README.md.gotmpl @@ -26,3 +26,88 @@ This chart is used to serve as the template for Validated Patterns Charts {{ template "helm-docs.versionFooter" . }} + +## Network Policies + +This chart supports deploying Kubernetes NetworkPolicies for network isolation +in the Keycloak namespace. Three layers are available: + +### Default-deny policy + +A namespace-wide default-deny NetworkPolicy that blocks all ingress and egress +traffic for every pod in the namespace unless an explicit allow policy exists. +Enable it by setting: + +```yaml +defaultDenyNetworkPolicy: + enabled: true +``` + +### Operator-managed ingress policy + +The RHBK operator automatically creates and manages a `keycloak-network-policy` +that controls ingress to keycloak pods (ports 8443, 9000, and JGroups 7800/57800). +This policy is owned by the operator and should not be modified — the operator +will revert any changes. + +### Per-pod allow rules + +When the default-deny policy is enabled, additional NetworkPolicy templates +allow defining fine-grained rules for each pod type: + +- `networkPolicy.keycloak` — egress rules for keycloak pods (ingress is + managed by the operator policy above) +- `networkPolicy.postgresql` — ingress and egress rules for postgresql-db pods +- `networkPolicy.operator` — ingress and egress rules for rhbk-operator pods + +Example — allow keycloak egress to DNS and PostgreSQL: + +```yaml +defaultDenyNetworkPolicy: + enabled: true + +networkPolicy: + keycloak: + enabled: true + egress: + - ports: + - protocol: UDP + port: 5353 + - protocol: TCP + port: 5353 + to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: openshift-dns + - ports: + - protocol: TCP + port: 5432 + to: + - podSelector: + matchLabels: + app: postgresql-db + postgresql: + enabled: true + ingress: + - ports: + - protocol: TCP + port: 5432 + from: + - podSelector: + matchLabels: + app: keycloak + egress: + - ports: + - protocol: UDP + port: 5353 + - protocol: TCP + port: 5353 + to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: openshift-dns +``` + +Patterns can supply these values via `extraValueFiles` in their +`values-hub.yaml` to keep network policy configuration separate from the main +chart values. diff --git a/templates/default-deny-network-policy.yaml b/templates/default-deny-network-policy.yaml new file mode 100644 index 0000000..6793640 --- /dev/null +++ b/templates/default-deny-network-policy.yaml @@ -0,0 +1,12 @@ +{{- if eq (.Values.defaultDenyNetworkPolicy.enabled | toString) "true" }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: default-deny-in-namespace-{{ .Release.Namespace }} + namespace: {{ .Release.Namespace }} +spec: + podSelector: {} + policyTypes: + - Ingress + - Egress +{{- end }} diff --git a/templates/keycloak-egress-network-policy.yaml b/templates/keycloak-egress-network-policy.yaml new file mode 100644 index 0000000..eb5c3b0 --- /dev/null +++ b/templates/keycloak-egress-network-policy.yaml @@ -0,0 +1,19 @@ +{{- if and (eq (.Values.defaultDenyNetworkPolicy.enabled | toString) "true") .Values.networkPolicy.keycloak.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: keycloak-egress-network-policy + namespace: {{ .Release.Namespace }} +spec: + podSelector: + matchLabels: + app: keycloak + app.kubernetes.io/instance: keycloak + app.kubernetes.io/managed-by: keycloak-operator + policyTypes: + - Egress + egress: + {{- with .Values.networkPolicy.keycloak.egress }} + {{- toYaml . | nindent 2 }} + {{- end }} +{{- end }} diff --git a/templates/operator-network-policy.yaml b/templates/operator-network-policy.yaml new file mode 100644 index 0000000..3142bd6 --- /dev/null +++ b/templates/operator-network-policy.yaml @@ -0,0 +1,22 @@ +{{- if and (eq (.Values.defaultDenyNetworkPolicy.enabled | toString) "true") .Values.networkPolicy.operator.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: keycloak-operator-network-policy + namespace: {{ .Release.Namespace }} +spec: + podSelector: + matchLabels: + name: rhbk-operator + policyTypes: + - Ingress + - Egress + {{- with .Values.networkPolicy.operator.ingress }} + ingress: + {{- toYaml . | nindent 2 }} + {{- end }} + {{- with .Values.networkPolicy.operator.egress }} + egress: + {{- toYaml . | nindent 2 }} + {{- end }} +{{- end }} diff --git a/templates/postgresql-network-policy.yaml b/templates/postgresql-network-policy.yaml new file mode 100644 index 0000000..951153b --- /dev/null +++ b/templates/postgresql-network-policy.yaml @@ -0,0 +1,22 @@ +{{- if and (eq (.Values.defaultDenyNetworkPolicy.enabled | toString) "true") .Values.networkPolicy.postgresql.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: keycloak-postgresql-network-policy + namespace: {{ .Release.Namespace }} +spec: + podSelector: + matchLabels: + app: postgresql-db + policyTypes: + - Ingress + - Egress + {{- with .Values.networkPolicy.postgresql.ingress }} + ingress: + {{- toYaml . | nindent 2 }} + {{- end }} + {{- with .Values.networkPolicy.postgresql.egress }} + egress: + {{- toYaml . | nindent 2 }} + {{- end }} +{{- end }} diff --git a/values.yaml b/values.yaml index 8464bdc..5889863 100644 --- a/values.yaml +++ b/values.yaml @@ -3,6 +3,32 @@ global: secretStore: kind: ClusterSecretStore name: vault-backend + +# -- Default-deny NetworkPolicy for the keycloak namespace. +# When enabled, deploys a namespace-wide NetworkPolicy that blocks all ingress and egress +# for pods without an explicit allow policy. Patterns that need zero-trust network isolation +# should enable this and provide per-pod allow rules via networkPolicy. +# @default -- false +defaultDenyNetworkPolicy: + enabled: false + +# -- Per-pod NetworkPolicy rules for keycloak, postgresql-db, and operator pods. +# Only effective when defaultDenyNetworkPolicy is enabled. The RHBK operator manages its own +# ingress policy for keycloak pods (keycloak-network-policy) — these templates add egress +# rules for keycloak and full ingress/egress rules for postgresql and operator pods. +networkPolicy: + keycloak: + enabled: false + egress: [] + postgresql: + enabled: false + ingress: [] + egress: [] + operator: + enabled: false + ingress: [] + egress: [] + keycloak: adminUser: enabled: true