Replaces hand-applied llm-serving-default-deny NetworkPolicy with a git-managed, namespace-scoped policy that only allows traffic from the api-gateway.
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)
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
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Replaces hand-applied
llm-serving-default-denyNetworkPolicy with a git-managed, namespace-scoped policy that only allows traffic from the api-gateway.Issue: #13
Problem
Old policy used
llm-client: truepod label withnamespaceSelector: {}(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
k8s/apps/llm-serving/networkpolicy.yamlapins +monitoringns + intra-namespace onlyk8s/apps/llm-serving/kustomization.yamlnetworkpolicy.yamlto resources listIngress Rules
apinamespacemonitoringnamespacellm-serving)Testing (live cluster, all verified with busybox pods)
curl api.riotpiao.com/v1/chat/completionscurl api.riotpiao.com/v1/chat/completionscurl api.riotpiao.com/v1/embeddingskubectl run -n api --labels=app=api-gatewaykubectl run -n monitoringkubectl run -n llm-serving --labels=...kubectl run -n defaultkubectl run -n portfoliokubectl run -n poimenOld hand-applied policy
llm-serving-default-denydeleted from cluster after new policy verified.Not in scope (tracked separately)
rock/poimenrepo)rock/kmsvc-managerepo)