Compare commits

..
Author SHA1 Message Date
rock 9f15e4eb3c feat(poimen): restrict the GraphQL server to the memory proxy
poimen-graphql is already ClusterIP on 8090 with no Ingress, so it is off the
internet. It had no NetworkPolicy, so every pod in the cluster could reach it.

The only caller is poimen-memory, which forwards its /graphql route to
MEM_GQL_PORT=8090. No other workload references the service.

Allows 8090 from poimen-memory pods only.
2026-11-04 05:38:26 +08:00
rock 9e004ccb9b feat(poimen): restrict the memory database to its own namespace (#103)
Co-authored-by: rock <[email protected]>
2026-11-03 21:34:04 +00:00
rock 4e684b2ee2 chore(kyverno): drop the two Application manifests from 00-substrate (#102)
Co-authored-by: rock <[email protected]>
2026-11-03 21:33:27 +00:00
3 changed files with 74 additions and 0 deletions
+28
View File
@@ -0,0 +1,28 @@
---
# Keep the GraphQL server reachable only from the one service that proxies it.
#
# poimen-graphql is already off the internet: its Service is ClusterIP on 8090 and
# no Ingress names it. What it lacked is in-cluster isolation — a ClusterIP answers
# every pod in the cluster.
#
# The only caller is poimen-memory, whose /graphql route forwards the request body
# to MEM_GQL_PORT (8090). No other workload references this service.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: poimen-graphql-ingress
namespace: poimen
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: poimen-graphql
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app.kubernetes.io/name: poimen-memory
ports:
- protocol: TCP
port: 8090
+4
View File
@@ -6,6 +6,10 @@ 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
# Only poimen-memory's /graphql proxy calls 8090.
- graphql-netpol.yaml
- poimen-sandbox-namespace.yaml
- poimen-sandbox-quota.yaml
- pi-session-netpol.yaml
+42
View File
@@ -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