P3.8: Restrict llm-serving ingress to api-gateway only #15

Merged
rock merged 1 commits from p3.8/networkpolicy-audit into main 2026-09-08 16:56:39 +00:00
Owner

Summary

Replaces hand-applied llm-serving-default-deny NetworkPolicy with a git-managed, namespace-scoped policy that only allows traffic from the api-gateway.

Issue: #13

Problem

Old policy used llm-client: true pod label with namespaceSelector: {} (any namespace). Any pod in the cluster could add that label and bypass the restriction. LLM inference engines (vLLM, Ollama, TEI) have zero auth — NetworkPolicy is the only access control.

Changes

File Change
k8s/apps/llm-serving/networkpolicy.yaml New: ingress from api ns + monitoring ns + intra-namespace only
k8s/apps/llm-serving/kustomization.yaml Added networkpolicy.yaml to resources list

Ingress Rules

Source Ports Why
api namespace 8080, 80, 8000, 11434 Gateway proxies all inference requests
monitoring namespace 8080, 9000 Prometheus scrapes /metrics
intra-namespace (llm-serving) 8080 Pod-to-pod

Testing (live cluster, all verified with busybox pods)

Test Method Result
Gateway -> qwen (Ollama) curl api.riotpiao.com/v1/chat/completions 200
Gateway -> reasoning (vLLM) curl api.riotpiao.com/v1/chat/completions 200
Gateway -> embeddings (TEI) curl api.riotpiao.com/v1/embeddings 200
api ns (labeled pod) -> llm-serving kubectl run -n api --labels=app=api-gateway 200
monitoring ns -> llm-serving /metrics kubectl run -n monitoring 200 (uvicorn)
intra-namespace -> ornith kubectl run -n llm-serving --labels=... 200
default ns -> llm-serving kubectl run -n default timeout (blocked)
portfolio ns -> llm-serving kubectl run -n portfolio timeout (blocked)
poimen ns -> llm-serving kubectl run -n poimen timeout (blocked)

Old hand-applied policy llm-serving-default-deny deleted from cluster after new policy verified.

Not in scope (tracked separately)

  • poimen-memory NetworkPolicy (managed in rock/poimen repo)
  • sqs management-service NetworkPolicy (managed in rock/kmsvc-manage repo)
  • storage/MinIO NetworkPolicy (has own OIDC auth)
## Summary Replaces hand-applied `llm-serving-default-deny` NetworkPolicy with a git-managed, namespace-scoped policy that only allows traffic from the api-gateway. **Issue:** #13 ## Problem Old policy used `llm-client: true` pod label with `namespaceSelector: {}` (any namespace). Any pod in the cluster could add that label and bypass the restriction. LLM inference engines (vLLM, Ollama, TEI) have **zero auth** — NetworkPolicy is the only access control. ## Changes | File | Change | |------|--------| | `k8s/apps/llm-serving/networkpolicy.yaml` | New: ingress from `api` ns + `monitoring` ns + intra-namespace only | | `k8s/apps/llm-serving/kustomization.yaml` | Added `networkpolicy.yaml` to resources list | ## Ingress Rules | Source | Ports | Why | |--------|-------|-----| | `api` namespace | 8080, 80, 8000, 11434 | Gateway proxies all inference requests | | `monitoring` namespace | 8080, 9000 | Prometheus scrapes /metrics | | intra-namespace (`llm-serving`) | 8080 | Pod-to-pod | ## Testing (live cluster, all verified with busybox pods) | Test | Method | Result | |------|--------|--------| | Gateway -> qwen (Ollama) | `curl api.riotpiao.com/v1/chat/completions` | ✅ 200 | | Gateway -> reasoning (vLLM) | `curl api.riotpiao.com/v1/chat/completions` | ✅ 200 | | Gateway -> embeddings (TEI) | `curl api.riotpiao.com/v1/embeddings` | ✅ 200 | | api ns (labeled pod) -> llm-serving | `kubectl run -n api --labels=app=api-gateway` | ✅ 200 | | monitoring ns -> llm-serving /metrics | `kubectl run -n monitoring` | ✅ 200 (uvicorn) | | intra-namespace -> ornith | `kubectl run -n llm-serving --labels=...` | ✅ 200 | | default ns -> llm-serving | `kubectl run -n default` | ❌ timeout (blocked) | | portfolio ns -> llm-serving | `kubectl run -n portfolio` | ❌ timeout (blocked) | | poimen ns -> llm-serving | `kubectl run -n poimen` | ❌ timeout (blocked) | Old hand-applied policy `llm-serving-default-deny` deleted from cluster after new policy verified. ## Not in scope (tracked separately) - poimen-memory NetworkPolicy (managed in `rock/poimen` repo) - sqs management-service NetworkPolicy (managed in `rock/kmsvc-manage` repo) - storage/MinIO NetworkPolicy (has own OIDC auth)
rock added 1 commit 2026-09-08 16:18:24 +00:00
Replace hand-applied llm-serving-default-deny NetworkPolicy that used
llm-client=true pod label selector (any pod in any namespace could
self-grant access) with a proper namespace-scoped policy.

Ingress now restricted to:
- api namespace (gateway) on ports 8080/80/8000/11434
- monitoring namespace (Prometheus) on ports 8080/9000
- intra-namespace (pod-to-pod within llm-serving)

Tested live:
- Gateway -> reasoning/ornith/embeddings/reranker: 200 OK
- default namespace -> llm-serving: timeout (blocked)
- portfolio namespace -> llm-serving: timeout (blocked)

Closes #13
rock added the area/downstreampriority/mediumstatus/reviewtype/infra labels 2026-09-08 16:18:48 +00:00
rock merged commit 9fe867e84f into main 2026-09-08 16:56:39 +00:00
rock deleted branch p3.8/networkpolicy-audit 2026-09-08 16:57:40 +00:00
Sign in to join this conversation.