New platform/network-policies/ Blueprint scaffold per design doc §3.9 row 8. Ships the cluster-wide zero-trust primitives that EPIC-5 (#1100) activates as part of the networking roll-out. What ships: - platform/network-policies/blueprint.yaml — bp-network-policies 1.0.0 - platform/network-policies/chart/Chart.yaml — Helm chart, no upstream sub-chart - platform/network-policies/chart/values.yaml — gate (enabled: false default) - platform/network-policies/chart/templates/default-deny.yaml — CCNP that denies all ingress + egress at endpointSelector: {} (full-cluster scope) - platform/network-policies/chart/templates/allow-system-namespaces.yaml — CCNP allowing full traffic for kube-system, flux-system, cilium, cert-manager, catalyst, openova-system, monitoring, ingress (set is parametric via .Values.allowSystemNamespaces — operator extends per Sovereign for gitea/harbor/loki etc.) - platform/network-policies/chart/templates/allow-egress-dns.yaml — CCNP permitting UDP/TCP/53 to CoreDNS from every Pod (without this the cluster is unbootable under default-deny — first DNS lookup fails) Why a separate Blueprint, not bp-cilium: - bp-cilium is foundational, installed on every cluster on day 0. Default-deny breaks every workload that hasn't been allowlisted, so it cannot ship in bp-cilium without operator opt-in semantics. - Separate Blueprint with enabled: false default preserves the safety boundary. EPIC-5 wires the activation when the rest of the zero-trust story is ready. Per-namespace intra-namespace allow is intentionally NOT in this slice: - Cilium CCNPs cannot express "same namespace as the source Pod" without listing every namespace, which contradicts dynamic Org provisioning. - That allow rule is rendered as a per-namespace CiliumNetworkPolicy (CNP, namespace-scoped) by organization-controller (slice C1 of #1095) at Organization creation time. README + values.yaml note this for downstream Implementers. Per docs/INVIOLABLE-PRINCIPLES.md #4, every policy parameter (allowSystemNamespaces list, dnsNamespace, dnsServiceName) is in values.yaml, not hardcoded. Validated: - helm template with default values: 0 resources rendered (gate works) - helm template with enabled=true: exactly 3 CCNPs rendered (default-deny, allow-system-namespaces, allow-egress-dns), all parse cleanly through python yaml.safe_load_all - CCNP CRD validation will happen on Sovereigns where bp-cilium is installed; local k3s here uses flannel so server-side dry-run is unavailable Refs: #1094, #1095, #1100, docs/EPICS-1-6-unified-design.md §3.9 row 8 + §8 (EPIC-5), ADR-0001 §2 (zero-trust). Co-authored-by: hatiyildiz <hatiyildiz@noreply.openova.io> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| chart | ||
| blueprint.yaml | ||
| README.md | ||
bp-network-policies
Status: Phase-0 scaffold (#1095 slice H8). Activated by EPIC-5 (#1100). Updated: 2026-05-08
Default-deny CiliumClusterwideNetworkPolicy baseline + a small set of allow-templates that turn the cluster zero-trust by default while keeping the Catalyst control plane operational.
This Blueprint is not in the bootstrap-kit. Installing it on a running cluster will sever every flow it doesn't explicitly allow — operators must install deliberately, per-Sovereign, with the allow-list adjusted for their workloads. EPIC-5 ships the wiring that turns it on as part of the zero-trust roll-out.
What it ships
| Template | Effect |
|---|---|
default-deny.yaml |
CiliumClusterwideNetworkPolicy 00-default-deny denies all ingress + egress at namespace selector level. Order 0 (highest priority for layer-1 catch-all). |
allow-system-namespaces.yaml |
Allows full ingress/egress for the Catalyst control-plane namespaces (kube-system, flux-system, cilium, cert-manager, catalyst, openova-system, plus monitoring and ingress namespaces) so the platform itself stays up. |
allow-egress-dns.yaml |
Allows egress to CoreDNS in kube-system from every namespace. Without this, every Pod fails on DNS lookup. |
Pod-to-Pod within the SAME namespace is intentionally NOT handled here.
Cilium CiliumClusterwideNetworkPolicy cannot express "same namespace as the
source Pod" without enumerating every namespace explicitly — that's a per-tenant
concern. The organization-controller (slice C1 of #1095) renders a
per-namespace CiliumNetworkPolicy (CNP, namespace-scoped) at Organization
creation time, with implicit same-namespace allow semantics.
Per-Application policies (allow app-X → app-Y cross-namespace, allow Org acme
egress to the public internet on port 443, etc.) are authored by the
application-controller (slice C4 in #1095) at install time from
Blueprint.spec.networking.egress declarations — they are not part of this
Blueprint.
Activation contract
# values.yaml override (or per-Sovereign overlay)
enabled: true
allowSystemNamespaces:
- kube-system
- flux-system
- cilium
- cert-manager
- catalyst
- openova-system
- monitoring
- ingress
When enabled: false (the default), no policies render — installing this chart
is a no-op until the operator opts in.
Verification
After installing with enabled: true:
# Two Pods in the same namespace — should reach each other
kubectl run -n acme test-a --image=busybox -- sleep 3600
kubectl run -n acme test-b --image=busybox -- sleep 3600
kubectl exec -n acme test-a -- wget -qO- test-b.acme.svc:80 # OK
# Two Pods in different namespaces — should NOT reach each other
kubectl run -n bank test-c --image=busybox -- sleep 3600
kubectl exec -n acme test-a -- wget -qO- test-c.bank.svc:80 # blocked
Cilium Hubble (turned on in EPIC-5) shows the deny events with the matching policy.
Why a separate Blueprint, not bp-cilium templates
bp-cilium is foundational infra installed on every cluster on day 0; default-deny
breaks every workload that hasn't been allowlisted. Shipping the policy as a
separate, opt-in Blueprint preserves the safety boundary: bp-cilium is always-on,
bp-network-policies is operator-on after the allowlist is sized.
References
- docs/EPICS-1-6-unified-design.md §3.9 row 8 + §8 (EPIC-5 Networking)
- ADR-0001 §2 (zero-trust)
- platform/cilium/README.md