openova/platform/network-policies/blueprint.yaml
e3mrah 68c68eaf7a
feat(bp-network-policies): land default-deny CCNP + system-namespace + DNS allow templates (slice H8, #1095) (#1116)
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>
2026-05-08 22:40:30 +04:00

66 lines
1.8 KiB
YAML

apiVersion: catalyst.openova.io/v1
kind: Blueprint
metadata:
name: bp-network-policies
labels:
catalyst.openova.io/section: pts-3-1-networking-and-service-mesh
spec:
version: 1.0.0
card:
title: Network Policies (zero-trust baseline)
summary: |
Default-deny CiliumClusterwideNetworkPolicy + allow-templates for
Catalyst control-plane namespaces, intra-namespace traffic, and DNS.
Activated by EPIC-5 #1100.
family: networking
documentation: ./README.md
visibility: unlisted
owner:
team: platform
contact: platform@openova.io
configSchema:
type: object
properties:
enabled:
type: boolean
default: false
description: Master gate. Default off — installing this Blueprint is a no-op until flipped.
allowSystemNamespaces:
type: array
description: Namespaces the Catalyst control plane needs full ingress/egress on.
items:
type: string
default:
- kube-system
- flux-system
- cilium
- cert-manager
- catalyst
- openova-system
- monitoring
- ingress
allowEgressDNS:
type: boolean
default: true
description: Allow egress to CoreDNS from every namespace. Without this, Pods break.
dnsNamespace:
type: string
default: kube-system
description: Namespace where CoreDNS lives.
dnsServiceName:
type: string
default: kube-dns
description: Service name CoreDNS publishes under (k3s default is kube-dns).
placementSchema:
modes: [single-region, active-active]
default: active-active
minRegions: 1
maxRegions: 5
manifests:
chart: ./chart
depends:
- blueprint: bp-cilium
version: ^1
upgrades:
from: ["0.x"]