diff --git a/charts/rhdh/Chart.yaml b/charts/rhdh/Chart.yaml index 3d444056d..4d5cca2b5 100644 --- a/charts/rhdh/Chart.yaml +++ b/charts/rhdh/Chart.yaml @@ -1,8 +1,8 @@ apiVersion: v2 name: redhat-developer-hub type: application -version: 2.2.0 -appVersion: 2.2.0 +version: 2.3.0 +appVersion: 2.1.0 annotations: artifacthub.io/category: integration-delivery artifacthub.io/license: Apache-2.0 diff --git a/charts/rhdh/README.md b/charts/rhdh/README.md index 850783a9a..4de0b71be 100644 --- a/charts/rhdh/README.md +++ b/charts/rhdh/README.md @@ -1,7 +1,7 @@ # RHDH Helm Chart for OpenShift and Kubernetes -![Version: 2.2.0](https://img.shields.io/badge/Version-2.2.0-informational?style=flat-square) +![Version: 2.3.0](https://img.shields.io/badge/Version-2.3.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) A Helm chart for deploying Red Hat Developer Hub, which is a Red Hat supported version of Backstage. @@ -36,7 +36,7 @@ For the **Generally Available** version of this chart, see: helm repo add bitnami https://charts.bitnami.com/bitnami helm repo add redhat-developer https://redhat-developer.github.io/rhdh-chart -helm install my-rhdh redhat-developer/redhat-developer-hub --version 2.2.0 +helm install my-rhdh redhat-developer/redhat-developer-hub --version 2.3.0 ``` ## Introduction @@ -293,7 +293,7 @@ Kubernetes: `>= 1.31.0-0` | podDisruptionBudget | Pod Disruption Budget configuration. | object | `{"create":false,"maxUnavailable":1,"minAvailable":""}` | | podLabels | Labels to add to the pod. | object | `{}` | | podSecurityContext | Pod-level security context. | object | `{}` | -| postgresql | Built-in PostgreSQL database (bitnami subchart). | object | `{"auth":{"secretKeys":{"adminPasswordKey":"postgres-password","userPasswordKey":"password"}},"enabled":true,"image":{"digest":"","registry":"quay.io","repository":"fedora/postgresql-15","tag":"latest"},"postgresqlDataDir":"/var/lib/pgsql/data/userdata","primary":{"containerSecurityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"enabled":false},"extraEnvVars":[{"name":"POSTGRESQL_ADMIN_PASSWORD","valueFrom":{"secretKeyRef":{"key":"{{- include \"rhdh.postgresql.adminPasswordKey\" . }}","name":"{{- include \"rhdh.postgresql.secretName\" . }}"}}}],"persistence":{"enabled":true,"mountPath":"/var/lib/pgsql/data","size":"1Gi"},"podSecurityContext":{"enabled":false},"resources":{"limits":{"cpu":"250m","ephemeral-storage":"20Mi","memory":"1024Mi"},"requests":{"cpu":"250m","memory":"256Mi"}}},"serviceBindings":{"enabled":true}}` | +| postgresql | Built-in PostgreSQL database (bitnami subchart). | object | `{"auth":{"secretKeys":{"adminPasswordKey":"postgres-password","userPasswordKey":"password"}},"enabled":true,"image":{"digest":"","registry":"quay.io","repository":"fedora/postgresql-15","tag":"latest"},"postgresqlDataDir":"/var/lib/pgsql/data/userdata","primary":{"containerSecurityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"enabled":false},"extraEnvVars":[{"name":"POSTGRESQL_ADMIN_PASSWORD","valueFrom":{"secretKeyRef":{"key":"{{- include \"rhdh.postgresql.adminPasswordKey\" . }}","name":"{{- include \"rhdh.postgresql.secretName\" . }}"}}}],"networkPolicy":{"enabled":false},"persistence":{"enabled":true,"mountPath":"/var/lib/pgsql/data","size":"1Gi"},"podSecurityContext":{"enabled":false},"resources":{"limits":{"cpu":"250m","ephemeral-storage":"20Mi","memory":"1024Mi"},"requests":{"cpu":"250m","memory":"256Mi"}}},"readReplicas":{"networkPolicy":{"enabled":false}},"serviceBindings":{"enabled":true}}` | | preInitContainers | Init containers to run BEFORE the system init containers (e.g. inject auth credentials before install-dynamic-plugins runs). | list | `[]` | | readinessProbe | Readiness probe configuration. | object | `{"failureThreshold":3,"httpGet":{"path":"/.backstage/health/v1/readiness","port":"backend","scheme":"HTTP"},"periodSeconds":10,"successThreshold":2,"timeoutSeconds":4}` | | replicaCount | Number of desired pods. | int | `1` | @@ -410,6 +410,31 @@ You can also configure additional catalog index images via `catalogIndex.extraIm For detailed information on configuring the catalog index, including how to override the default image, use a private registry, or add extra catalog index images, see the [Catalog Index Configuration documentation](../../docs/catalog-index-configuration.md). +### NetworkPolicies + +This chart deploys a **default-deny** NetworkPolicy for the RHDH backend pod, blocking all ingress and egress traffic that is not explicitly allowed. When the built-in PostgreSQL is enabled (`postgresql.enabled=true`), the database pods also get their own default-deny policy with selective allow rules. + +The following traffic is allowed out of the box: + +| Direction | Port | Destination / Source | Purpose | +|-----------|------|----------------------|---------| +| Egress | 53, 5353 (UDP/TCP) | Any | DNS resolution | +| Egress | 443 (TCP) | Any | HTTPS (Git forges, auth providers, external APIs) | +| Egress | 5432 (TCP) | Built-in PostgreSQL pods (scoped) or any (external DB) | Database access | +| Egress | 6379 (TCP) | Any | Redis (BYO — no pod/namespace selector) | +| Ingress | 7007 (TCP) | OpenShift router namespace or any namespace (non-OCP) | User traffic via Route / Ingress | +| Ingress | 9464 (TCP) | `openshift-monitoring`, `openshift-user-workload-monitoring`, `gmp-system`, `gke-gmp-system`, `monitoring` | Prometheus metrics scraping | + +**Redis egress is intentionally unscoped.** RHDH does not deploy Redis; users bring their own instance, which may live in the same namespace, a different namespace, or an external managed service. The rule therefore allows egress on port 6379 to any destination. + +**Bitnami subchart NetworkPolicies are disabled** (`postgresql.primary.networkPolicy.enabled=false`, `postgresql.readReplicas.networkPolicy.enabled=false`) because this chart provides its own tighter policies for the built-in database pods. + +**Helm test NetworkPolicies** (`allow-test-connection` and `allow-test-connection-ingress`) are Helm test hooks: they are created just before `helm test` runs and cleaned up automatically on success. + +**Adding your own NetworkPolicies.** Kubernetes evaluates NetworkPolicies additively — if any policy allows a connection, the connection is permitted. You **cannot** tighten an existing allow rule by adding another NetworkPolicy; you can only broaden access. To restrict traffic further, you would need to modify or remove the chart's policies via values overrides or post-render patches. + +For more information on user workload monitoring on OpenShift, see [Configuring user workload monitoring](https://docs.redhat.com/en/documentation/monitoring_stack_for_red_hat_openshift/4.22/html/configuring_user_workload_monitoring/preparing-to-configure-the-monitoring-stack-uwm). + ### Intelligent Assistant Use `intelligentAssistant.enabled` to enable or disable the built-in Intelligent Assistant feature. diff --git a/charts/rhdh/README.md.gotmpl b/charts/rhdh/README.md.gotmpl index 96a24bb22..77060edb1 100644 --- a/charts/rhdh/README.md.gotmpl +++ b/charts/rhdh/README.md.gotmpl @@ -255,6 +255,31 @@ You can also configure additional catalog index images via `catalogIndex.extraIm For detailed information on configuring the catalog index, including how to override the default image, use a private registry, or add extra catalog index images, see the [Catalog Index Configuration documentation](../../docs/catalog-index-configuration.md). +### NetworkPolicies + +This chart deploys a **default-deny** NetworkPolicy for the RHDH backend pod, blocking all ingress and egress traffic that is not explicitly allowed. When the built-in PostgreSQL is enabled (`postgresql.enabled=true`), the database pods also get their own default-deny policy with selective allow rules. + +The following traffic is allowed out of the box: + +| Direction | Port | Destination / Source | Purpose | +|-----------|------|----------------------|---------| +| Egress | 53, 5353 (UDP/TCP) | Any | DNS resolution | +| Egress | 443 (TCP) | Any | HTTPS (Git forges, auth providers, external APIs) | +| Egress | 5432 (TCP) | Built-in PostgreSQL pods (scoped) or any (external DB) | Database access | +| Egress | 6379 (TCP) | Any | Redis (BYO — no pod/namespace selector) | +| Ingress | 7007 (TCP) | OpenShift router namespace or any namespace (non-OCP) | User traffic via Route / Ingress | +| Ingress | 9464 (TCP) | `openshift-monitoring`, `openshift-user-workload-monitoring`, `gmp-system`, `gke-gmp-system`, `monitoring` | Prometheus metrics scraping | + +**Redis egress is intentionally unscoped.** RHDH does not deploy Redis; users bring their own instance, which may live in the same namespace, a different namespace, or an external managed service. The rule therefore allows egress on port 6379 to any destination. + +**Bitnami subchart NetworkPolicies are disabled** (`postgresql.primary.networkPolicy.enabled=false`, `postgresql.readReplicas.networkPolicy.enabled=false`) because this chart provides its own tighter policies for the built-in database pods. + +**Helm test NetworkPolicies** (`allow-test-connection` and `allow-test-connection-ingress`) are Helm test hooks: they are created just before `helm test` runs and cleaned up automatically on success. + +**Adding your own NetworkPolicies.** Kubernetes evaluates NetworkPolicies additively — if any policy allows a connection, the connection is permitted. You **cannot** tighten an existing allow rule by adding another NetworkPolicy; you can only broaden access. To restrict traffic further, you would need to modify or remove the chart's policies via values overrides or post-render patches. + +For more information on user workload monitoring on OpenShift, see [Configuring user workload monitoring](https://docs.redhat.com/en/documentation/monitoring_stack_for_red_hat_openshift/4.22/html/configuring_user_workload_monitoring/preparing-to-configure-the-monitoring-stack-uwm). + ### Intelligent Assistant Use `intelligentAssistant.enabled` to enable or disable the built-in Intelligent Assistant feature. diff --git a/charts/rhdh/templates/network-policies.yaml b/charts/rhdh/templates/network-policies.yaml new file mode 100644 index 000000000..5be32b576 --- /dev/null +++ b/charts/rhdh/templates/network-policies.yaml @@ -0,0 +1,548 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "rhdh.fullname" . }}-default-deny + labels: + {{- include "rhdh.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- include "common.tplvalues.render" (dict "value" . "context" $) | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + {{- include "rhdh.selectorLabels" . | nindent 6 }} + policyTypes: + - Ingress + - Egress + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "rhdh.fullname" . }}-allow-dns-egress + labels: + {{- include "rhdh.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- include "common.tplvalues.render" (dict "value" . "context" $) | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + {{- include "rhdh.selectorLabels" . | nindent 6 }} + policyTypes: + - Egress + egress: + - ports: + - port: 53 + protocol: UDP + - port: 53 + protocol: TCP + - port: 5353 + protocol: UDP + - port: 5353 + protocol: TCP + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "rhdh.fullname" . }}-allow-https-egress + labels: + {{- include "rhdh.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- include "common.tplvalues.render" (dict "value" . "context" $) | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + {{- include "rhdh.selectorLabels" . | nindent 6 }} + policyTypes: + - Egress + egress: + - ports: + - port: 443 + protocol: TCP + +--- +# Redis is part of the recommended checklist for production deployments +# (see https://docs.redhat.com/en/documentation/red_hat_developer_hub/1.10/html/setting_up_and_configuring_your_first_red_hat_developer_hub_instance/checklist-to-run-your-first-rhdh-instance-in-production_setting-up-and-configuring-your-first-red-hat-developer-hub-instance). +# RHDH does not deploy Redis OOTB; users bring their own, which could be in the same +# namespace, a different namespace, or an external managed service. The rule therefore +# has no pod or namespace selector. +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "rhdh.fullname" . }}-allow-redis-egress + labels: + {{- include "rhdh.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- include "common.tplvalues.render" (dict "value" . "context" $) | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + {{- include "rhdh.selectorLabels" . | nindent 6 }} + policyTypes: + - Egress + egress: + - ports: + - port: 6379 + protocol: TCP + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "rhdh.fullname" . }}-allow-psql-egress + labels: + {{- include "rhdh.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- include "common.tplvalues.render" (dict "value" . "context" $) | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + {{- include "rhdh.selectorLabels" . | nindent 6 }} + policyTypes: + - Egress + egress: + - {{- if .Values.postgresql.enabled }} + to: + - podSelector: + matchLabels: + app.kubernetes.io/name: postgresql + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: primary + {{- if eq (default "standalone" .Values.postgresql.architecture) "replication" }} + - podSelector: + matchLabels: + app.kubernetes.io/name: postgresql + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: read + {{- end }} + {{- end }} + ports: + - port: {{ if .Values.postgresql.enabled }}5432{{ else }}{{ .Values.externalDatabase.port | default 5432 }}{{ end }} + protocol: TCP + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "rhdh.fullname" . }}-allow-metrics-ingress + labels: + {{- include "rhdh.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- include "common.tplvalues.render" (dict "value" . "context" $) | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + {{- include "rhdh.selectorLabels" . | nindent 6 }} + policyTypes: + - Ingress + ingress: + - from: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: openshift-monitoring + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: openshift-user-workload-monitoring + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: gmp-system + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: gke-gmp-system + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: monitoring + ports: + - port: 9464 + protocol: TCP + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "rhdh.fullname" . }}-allow-router-ingress + labels: + {{- include "rhdh.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- include "common.tplvalues.render" (dict "value" . "context" $) | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + {{- include "rhdh.selectorLabels" . | nindent 6 }} + policyTypes: + - Ingress + ingress: + - from: + - namespaceSelector: + {{- if .Values.openshift.route.enabled }} + matchLabels: + policy-group.network.openshift.io/ingress: "" + {{- else }} + {} + {{- end }} + ports: + - port: 7007 + protocol: TCP + +{{- if .Values.test.enabled }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "rhdh.fullname" . }}-allow-test-connection + labels: + {{- include "rhdh.labels" . | nindent 4 }} + annotations: + {{- with .Values.commonAnnotations }} + {{- include "common.tplvalues.render" (dict "value" . "context" $) | nindent 4 }} + {{- end }} + helm.sh/hook: test + helm.sh/hook-weight: "-1" + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded +spec: + podSelector: + matchLabels: + app.kubernetes.io/instance: {{ .Release.Name }} + rhdh.redhat.com/test-connection: "true" + policyTypes: + - Egress + egress: + - ports: + - port: 53 + protocol: UDP + - port: 53 + protocol: TCP + - port: 5353 + protocol: UDP + - port: 5353 + protocol: TCP + - to: + - podSelector: + matchLabels: + {{- include "rhdh.selectorLabels" . | nindent 14 }} + ports: + - port: 7007 + protocol: TCP + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "rhdh.fullname" . }}-allow-test-connection-ingress + labels: + {{- include "rhdh.labels" . | nindent 4 }} + annotations: + {{- with .Values.commonAnnotations }} + {{- include "common.tplvalues.render" (dict "value" . "context" $) | nindent 4 }} + {{- end }} + helm.sh/hook: test + helm.sh/hook-weight: "-1" + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded +spec: + podSelector: + matchLabels: + {{- include "rhdh.selectorLabels" . | nindent 6 }} + policyTypes: + - Ingress + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/instance: {{ .Release.Name }} + rhdh.redhat.com/test-connection: "true" + ports: + - port: 7007 + protocol: TCP +{{- end }} + +{{- if .Values.postgresql.enabled }} + +# The following db-* policies are only created when the built-in PostgreSQL is enabled. +# When using an external database (postgresql.enabled=false), only the backend NPs above +# are created, and allow-psql-egress has no 'to' selector (broad egress on the configured port). +# +# These replace the bitnami subchart's own NPs (disabled via +# postgresql.primary.networkPolicy.enabled=false and +# postgresql.readReplicas.networkPolicy.enabled=false in values.yaml) +# so we can enforce tighter rules. + +{{- $isReplication := eq (default "standalone" .Values.postgresql.architecture) "replication" }} + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "rhdh.fullname" . }}-db-default-deny + labels: + {{- include "rhdh.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- include "common.tplvalues.render" (dict "value" . "context" $) | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: postgresql + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: primary + policyTypes: + - Ingress + - Egress + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "rhdh.fullname" . }}-db-allow-dns-egress + labels: + {{- include "rhdh.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- include "common.tplvalues.render" (dict "value" . "context" $) | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: postgresql + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: primary + policyTypes: + - Egress + egress: + - ports: + - port: 53 + protocol: UDP + - port: 53 + protocol: TCP + - port: 5353 + protocol: UDP + - port: 5353 + protocol: TCP + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "rhdh.fullname" . }}-db-allow-backend-ingress + labels: + {{- include "rhdh.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- include "common.tplvalues.render" (dict "value" . "context" $) | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: postgresql + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: primary + policyTypes: + - Ingress + ingress: + - from: + - podSelector: + matchLabels: + {{- include "rhdh.selectorLabels" . | nindent 14 }} + ports: + - port: 5432 + protocol: TCP + +{{- if $isReplication }} + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "rhdh.fullname" . }}-db-allow-replication + labels: + {{- include "rhdh.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- include "common.tplvalues.render" (dict "value" . "context" $) | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: postgresql + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: primary + policyTypes: + - Ingress + - Egress + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: postgresql + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: read + ports: + - port: 5432 + protocol: TCP + egress: + - to: + - podSelector: + matchLabels: + app.kubernetes.io/name: postgresql + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: read + ports: + - port: 5432 + protocol: TCP + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "rhdh.fullname" . }}-db-read-default-deny + labels: + {{- include "rhdh.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- include "common.tplvalues.render" (dict "value" . "context" $) | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: postgresql + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: read + policyTypes: + - Ingress + - Egress + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "rhdh.fullname" . }}-db-read-allow-dns-egress + labels: + {{- include "rhdh.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- include "common.tplvalues.render" (dict "value" . "context" $) | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: postgresql + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: read + policyTypes: + - Egress + egress: + - ports: + - port: 53 + protocol: UDP + - port: 53 + protocol: TCP + - port: 5353 + protocol: UDP + - port: 5353 + protocol: TCP + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "rhdh.fullname" . }}-db-read-allow-primary-egress + labels: + {{- include "rhdh.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- include "common.tplvalues.render" (dict "value" . "context" $) | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: postgresql + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: read + policyTypes: + - Egress + egress: + - to: + - podSelector: + matchLabels: + app.kubernetes.io/name: postgresql + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: primary + ports: + - port: 5432 + protocol: TCP + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "rhdh.fullname" . }}-db-read-allow-primary-ingress + labels: + {{- include "rhdh.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- include "common.tplvalues.render" (dict "value" . "context" $) | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: postgresql + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: read + policyTypes: + - Ingress + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: postgresql + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: primary + ports: + - port: 5432 + protocol: TCP + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "rhdh.fullname" . }}-db-read-allow-backend-ingress + labels: + {{- include "rhdh.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- include "common.tplvalues.render" (dict "value" . "context" $) | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: postgresql + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: read + policyTypes: + - Ingress + ingress: + - from: + - podSelector: + matchLabels: + {{- include "rhdh.selectorLabels" . | nindent 14 }} + ports: + - port: 5432 + protocol: TCP + +{{- end }} + +{{- end }} diff --git a/charts/rhdh/templates/orchestrator/network-policies.yaml b/charts/rhdh/templates/orchestrator/network-policies.yaml index 27afbbae8..d20e38579 100644 --- a/charts/rhdh/templates/orchestrator/network-policies.yaml +++ b/charts/rhdh/templates/orchestrator/network-policies.yaml @@ -1,3 +1,10 @@ +# TODO: these Orchestrator policies use podSelector: {} (namespace-wide) and conflict with +# the ADR's "default deny with selective allow" and "label-scoped policies" principles. +# They weaken per-component ingress isolation for RHDH backend and DB pods in the same namespace. +# Even though only one Orchestrator-flavoured RHDH instance is supported per namespace (the +# SonataFlow Operator enforces one SonataFlowPlatform per namespace), a non-Orchestrator RHDH +# instance could coexist in the same namespace; these namespace-wide policies would affect it too. +# Review and make stricter by scoping to SonataFlow-specific labels where possible. {{- if .Values.orchestrator.enabled }} apiVersion: networking.k8s.io/v1 kind: NetworkPolicy @@ -15,12 +22,15 @@ spec: - from: - namespaceSelector: matchLabels: + # Allow knative events to be delivered to workflows. kubernetes.io/metadata.name: knative-eventing - namespaceSelector: matchLabels: + # Allow auxiliary knative function for workflow (such as m2k-save-transformation) kubernetes.io/metadata.name: knative-serving - namespaceSelector: matchLabels: + # Allow openshift serverless logic operator controller pod to access all pods in sonataflow kubernetes.io/metadata.name: openshift-serverless-logic --- apiVersion: networking.k8s.io/v1 @@ -41,6 +51,7 @@ spec: - from: - namespaceSelector: matchLabels: + # Allow knative events to be delivered to workflows. policy-group.network.openshift.io/ingress: "" --- apiVersion: networking.k8s.io/v1 @@ -61,6 +72,28 @@ spec: - from: - podSelector: {} {{- end }} +{{- if .Values.orchestrator.enabled }} +# Allow all egress from all pods in the namespace. +# The Orchestrator backend plugin needs HTTP egress to reach SonataFlow and Data Index services; +# SonataFlow workflows may also need arbitrary outbound access. +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "rhdh.fullname" . }}-allow-all-egress + labels: + {{- include "rhdh.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- include "common.tplvalues.render" (dict "value" . "context" $) | nindent 4 }} + {{- end }} +spec: + podSelector: {} + policyTypes: + - Egress + egress: + - {} +{{- end }} --- {{- if and .Values.orchestrator.enabled .Values.orchestrator.sonataflowPlatform.monitoring.enabled }} apiVersion: networking.k8s.io/v1 @@ -81,5 +114,6 @@ spec: - from: - namespaceSelector: matchLabels: + # Allow openshift-user-workload-monitoring pods to access the workflow. kubernetes.io/metadata.name: openshift-user-workload-monitoring {{- end }} diff --git a/charts/rhdh/templates/tests/test-connection.yaml b/charts/rhdh/templates/tests/test-connection.yaml index 92e6156ed..1f3af3167 100644 --- a/charts/rhdh/templates/tests/test-connection.yaml +++ b/charts/rhdh/templates/tests/test-connection.yaml @@ -4,7 +4,8 @@ kind: Pod metadata: name: "{{ include "rhdh.fullname" . }}-test-connection" labels: - {{- include "rhdh.labels" . | nindent 4 }} + app.kubernetes.io/instance: {{ .Release.Name }} + rhdh.redhat.com/test-connection: "true" annotations: {{- with .Values.commonAnnotations }} {{- toYaml . | nindent 4 }} diff --git a/charts/rhdh/values.yaml b/charts/rhdh/values.yaml index 0d8718939..bf292f65f 100644 --- a/charts/rhdh/values.yaml +++ b/charts/rhdh/values.yaml @@ -421,6 +421,11 @@ postgresql: adminPasswordKey: "postgres-password" userPasswordKey: "password" primary: + # The bitnami subchart ships its own NP, but it defaults to allow-all egress + # and unrestricted ingress on 5432. We disable it and provide tighter + # replacements in templates/network-policies.yaml. + networkPolicy: + enabled: false podSecurityContext: enabled: false containerSecurityContext: @@ -447,6 +452,11 @@ postgresql: secretKeyRef: key: '{{- include "rhdh.postgresql.adminPasswordKey" . }}' name: '{{- include "rhdh.postgresql.secretName" . }}' + readReplicas: + # Same rationale as primary.networkPolicy above; our own read-replica NPs + # in templates/network-policies.yaml are tighter. + networkPolicy: + enabled: false # -- External database connection. Used when postgresql.enabled is false. # See docs/external-db.md for TLS setup and privilege requirements.