From 1c6f58cdb87c617e50c143abc8bc5b63d1c074f6 Mon Sep 17 00:00:00 2001 From: Flegma Date: Thu, 2 Apr 2026 15:03:48 +0200 Subject: [PATCH 1/3] fix: add network policies and scope Vault permissions per service Network policies: - Default-deny ingress for 5stack namespace - Allow ingress controller to reach web, api, hasura, minio, typesense - TimescaleDB: only reachable from hasura and api - Redis: only reachable from api and connector - Hasura: only from api, web, and ingress - API: only from ingress and connector - Connector: only from api Vault: - Replace wildcard path "*" with explicit per-service read-only paths matching the kv/data/* paths used by migrate_secrets_to_vault - External-secrets can only read specific service secrets, not create/update/delete or access arbitrary vault paths Closes #413 --- base/kustomization.yaml | 3 +- base/network-policies/allow-ingress.yaml | 32 ++++++ base/network-policies/allow-internal.yaml | 119 ++++++++++++++++++++++ base/network-policies/default-deny.yaml | 9 ++ base/network-policies/kustomization.yaml | 7 ++ overlays/vault/scripts/setup-vault.sh | 37 ++++++- 6 files changed, 204 insertions(+), 3 deletions(-) create mode 100644 base/network-policies/allow-ingress.yaml create mode 100644 base/network-policies/allow-internal.yaml create mode 100644 base/network-policies/default-deny.yaml create mode 100644 base/network-policies/kustomization.yaml diff --git a/base/kustomization.yaml b/base/kustomization.yaml index da90a6b..e829f5b 100644 --- a/base/kustomization.yaml +++ b/base/kustomization.yaml @@ -13,4 +13,5 @@ resources: - web - volumes - nginx - - backups \ No newline at end of file + - backups + - network-policies \ No newline at end of file diff --git a/base/network-policies/allow-ingress.yaml b/base/network-policies/allow-ingress.yaml new file mode 100644 index 0000000..1f986a6 --- /dev/null +++ b/base/network-policies/allow-ingress.yaml @@ -0,0 +1,32 @@ +# Allow NGINX ingress controller to reach web, api, hasura, minio, typesense +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-ingress-to-services + namespace: 5stack +spec: + podSelector: + matchExpressions: + - key: app + operator: In + values: [web, api, hasura, minio, typesense] + ingress: + - from: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: ingress-nginx + ports: + - port: 3000 + protocol: TCP + - port: 5585 + protocol: TCP + - port: 8080 + protocol: TCP + - port: 9000 + protocol: TCP + - port: 9090 + protocol: TCP + - port: 8108 + protocol: TCP + policyTypes: + - Ingress diff --git a/base/network-policies/allow-internal.yaml b/base/network-policies/allow-internal.yaml new file mode 100644 index 0000000..b0070df --- /dev/null +++ b/base/network-policies/allow-internal.yaml @@ -0,0 +1,119 @@ +# TimescaleDB: allow from hasura and api only +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-timescaledb-ingress + namespace: 5stack +spec: + podSelector: + matchLabels: + app: timescaledb + ingress: + - from: + - podSelector: + matchLabels: + app: hasura + - podSelector: + matchLabels: + app: api + ports: + - port: 5432 + protocol: TCP + policyTypes: + - Ingress +--- +# Redis: allow from api and game-server-node-connector +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-redis-ingress + namespace: 5stack +spec: + podSelector: + matchLabels: + app: redis + ingress: + - from: + - podSelector: + matchLabels: + app: api + - podSelector: + matchLabels: + app: game-server-node-connector + ports: + - port: 6379 + protocol: TCP + policyTypes: + - Ingress +--- +# Hasura: allow from web, api, and ingress +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-hasura-ingress + namespace: 5stack +spec: + podSelector: + matchLabels: + app: hasura + ingress: + - from: + - podSelector: + matchLabels: + app: api + - podSelector: + matchLabels: + app: web + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: ingress-nginx + ports: + - port: 8080 + protocol: TCP + policyTypes: + - Ingress +--- +# API: allow from ingress and game-server-node-connector +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-api-ingress + namespace: 5stack +spec: + podSelector: + matchLabels: + app: api + ingress: + - from: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: ingress-nginx + - podSelector: + matchLabels: + app: game-server-node-connector + ports: + - port: 5585 + protocol: TCP + policyTypes: + - Ingress +--- +# Game server node connector: allow from api (Redis transport) +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-connector-ingress + namespace: 5stack +spec: + podSelector: + matchLabels: + app: game-server-node-connector + ingress: + - from: + - podSelector: + matchLabels: + app: api + ports: + - port: 8585 + protocol: TCP + policyTypes: + - Ingress diff --git a/base/network-policies/default-deny.yaml b/base/network-policies/default-deny.yaml new file mode 100644 index 0000000..856ca34 --- /dev/null +++ b/base/network-policies/default-deny.yaml @@ -0,0 +1,9 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: default-deny-ingress + namespace: 5stack +spec: + podSelector: {} + policyTypes: + - Ingress diff --git a/base/network-policies/kustomization.yaml b/base/network-policies/kustomization.yaml new file mode 100644 index 0000000..1811d9e --- /dev/null +++ b/base/network-policies/kustomization.yaml @@ -0,0 +1,7 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - default-deny.yaml + - allow-ingress.yaml + - allow-internal.yaml diff --git a/overlays/vault/scripts/setup-vault.sh b/overlays/vault/scripts/setup-vault.sh index 81cdae0..6c01236 100755 --- a/overlays/vault/scripts/setup-vault.sh +++ b/overlays/vault/scripts/setup-vault.sh @@ -70,8 +70,41 @@ fi echo "Creating Vault policy for external-secrets..." cat < Date: Thu, 2 Apr 2026 16:04:35 +0200 Subject: [PATCH 2/3] fix: allow game server pods to reach API for match events Game server pods (labeled app: game-server) need WebSocket access to the API for match event communication. Without this, match events would be blocked by the default-deny policy. --- base/network-policies/allow-internal.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/base/network-policies/allow-internal.yaml b/base/network-policies/allow-internal.yaml index b0070df..03d892f 100644 --- a/base/network-policies/allow-internal.yaml +++ b/base/network-policies/allow-internal.yaml @@ -73,7 +73,7 @@ spec: policyTypes: - Ingress --- -# API: allow from ingress and game-server-node-connector +# API: allow from ingress, connector, and game server pods apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: @@ -91,6 +91,11 @@ spec: - podSelector: matchLabels: app: game-server-node-connector + - podSelector: + matchExpressions: + - key: app + operator: In + values: [game-server] ports: - port: 5585 protocol: TCP From 9b0fa109e08f8f30e10215c3905d4b9ac6a3d1c7 Mon Sep 17 00:00:00 2001 From: Flegma Date: Thu, 2 Apr 2026 17:01:30 +0200 Subject: [PATCH 3/3] fix: add missing network policies for hasura, minio, typesense, backups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per code review — 4 critical/important missing policies: - Hasura → API: needed for auth/event/action webhooks - Backup CronJob → TimescaleDB + MinIO: needed for pg_dump + S3 upload - API → MinIO: needed for S3 operations (demos, assets) - API → Typesense: needed for player search indexing Also adds app: postgres-backup label to backup CronJob pod template so it can be selected by network policies. --- base/backups/postgres-backup-cronjob.yaml | 3 ++ base/network-policies/allow-internal.yaml | 63 ++++++++++++++++++++++- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/base/backups/postgres-backup-cronjob.yaml b/base/backups/postgres-backup-cronjob.yaml index d8d46a9..c2daf93 100644 --- a/base/backups/postgres-backup-cronjob.yaml +++ b/base/backups/postgres-backup-cronjob.yaml @@ -10,6 +10,9 @@ spec: jobTemplate: spec: template: + metadata: + labels: + app: postgres-backup spec: restartPolicy: Never containers: diff --git a/base/network-policies/allow-internal.yaml b/base/network-policies/allow-internal.yaml index 03d892f..1d8ab56 100644 --- a/base/network-policies/allow-internal.yaml +++ b/base/network-policies/allow-internal.yaml @@ -1,4 +1,4 @@ -# TimescaleDB: allow from hasura and api only +# TimescaleDB: allow from hasura, api, and backup jobs apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: @@ -16,6 +16,9 @@ spec: - podSelector: matchLabels: app: api + - podSelector: + matchLabels: + app: postgres-backup ports: - port: 5432 protocol: TCP @@ -73,7 +76,7 @@ spec: policyTypes: - Ingress --- -# API: allow from ingress, connector, and game server pods +# API: allow from ingress, hasura (webhooks), connector, and game server pods apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: @@ -88,6 +91,9 @@ spec: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: ingress-nginx + - podSelector: + matchLabels: + app: hasura - podSelector: matchLabels: app: game-server-node-connector @@ -102,6 +108,59 @@ spec: policyTypes: - Ingress --- +# MinIO: allow from api and backup jobs +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-minio-ingress + namespace: 5stack +spec: + podSelector: + matchLabels: + app: minio + ingress: + - from: + - podSelector: + matchLabels: + app: api + - podSelector: + matchLabels: + app: postgres-backup + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: ingress-nginx + ports: + - port: 9000 + protocol: TCP + - port: 9090 + protocol: TCP + policyTypes: + - Ingress +--- +# Typesense: allow from api and ingress +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-typesense-ingress + namespace: 5stack +spec: + podSelector: + matchLabels: + app: typesense + ingress: + - from: + - podSelector: + matchLabels: + app: api + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: ingress-nginx + ports: + - port: 8108 + protocol: TCP + policyTypes: + - Ingress +--- # Game server node connector: allow from api (Redis transport) apiVersion: networking.k8s.io/v1 kind: NetworkPolicy