From 9e004ccb9b0446b8adfc76b3d0e92210628231e4 Mon Sep 17 00:00:00 2001 From: rock Date: Tue, 3 Nov 2026 21:34:04 +0000 Subject: [PATCH] feat(poimen): restrict the memory database to its own namespace (#103) Co-authored-by: rock --- k8s/infra/poimen/kustomization.yaml | 2 ++ k8s/infra/poimen/memory-db-netpol.yaml | 42 ++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 k8s/infra/poimen/memory-db-netpol.yaml diff --git a/k8s/infra/poimen/kustomization.yaml b/k8s/infra/poimen/kustomization.yaml index ae6ad04..30945a6 100644 --- a/k8s/infra/poimen/kustomization.yaml +++ b/k8s/infra/poimen/kustomization.yaml @@ -6,6 +6,8 @@ kind: Kustomization # deployments (wave 0) are applied. resources: - memory-db.yaml + # ClusterIP alone is not isolation: every pod in the cluster can reach it. + - memory-db-netpol.yaml - poimen-sandbox-namespace.yaml - poimen-sandbox-quota.yaml - pi-session-netpol.yaml diff --git a/k8s/infra/poimen/memory-db-netpol.yaml b/k8s/infra/poimen/memory-db-netpol.yaml new file mode 100644 index 0000000..ddf17b8 --- /dev/null +++ b/k8s/infra/poimen/memory-db-netpol.yaml @@ -0,0 +1,42 @@ +--- +# Keep the memory database reachable only from inside its own namespace. +# +# What this does NOT change: the database was already unreachable from the +# internet. `memory-db-rw`, `memory-db-ro` and `memory-db-r` are ClusterIP +# services, no Ingress backs them, and no public DNS name resolves to them. +# +# What it fixes: a ClusterIP service is reachable by EVERY pod in the cluster, +# because Kubernetes has no implicit isolation. Cilium enforces NetworkPolicy, so +# stating the allowed sources is what turns "not on the internet" into "not +# reachable from another tenant's namespace". +# +# Two sources, both required: +# - the poimen namespace, which holds every client: poimen-memory, poimen-graphql, +# poimen-worker, poimen-workflows and the migration Job. +# - cnpg-system, where the CloudNativePG operator lives. It connects to the +# instance for switchover and failover, so a narrower rule breaks recovery. +# +# No other port is opened. The operator's metrics endpoint stays closed because no +# PodMonitor for this cluster exists, so nothing scrapes it. +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: memory-db-ingress + namespace: poimen +spec: + podSelector: + matchLabels: + cnpg.io/cluster: memory-db + policyTypes: + - Ingress + ingress: + - from: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: poimen + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: cnpg-system + ports: + - protocol: TCP + port: 5432