--- id: RAIL-K8S-WP-0003 type: workplan title: "Private-by-default networking until an exposure grant exists" domain: financials repo: rail-kubernetes status: ready owner: codex topic_slug: railiance created: "2026-08-15" updated: "2026-08-15" related: - RMASTER-WP-0023 - ADR-0008 - ADR-0006 --- # RAIL-K8S-WP-0003 — private-by-default networking Intake from `RMASTER-WP-0023-T05`. Until this rail owns live networking, `railiance-cluster` may implement the same controls and back-link here. ## Goal Enforce ADR-0008 on the Kubernetes rail: ClusterIP is the paved Service; default-deny NetworkPolicy; no public Ingress unless the rapp has `exposure.posture: public`, a grant, `binding_admission: production-approved`, and the reef has granted a public surface. Do not define what production-safe means (ADR-0006). Do not open `6443`. ## T01 — Pave ClusterIP and default-deny ```task id: RAIL-K8S-WP-0003-T01 status: todo priority: high ``` Templates and overlays emit ClusterIP and default-deny NetworkPolicy. Document the operator/tunnel path for debug. Missing `exposure` means `private`. **Done when:** a new rapp on this rail has no public listener unless a grant exists. ## T02 — Gate public Ingress on the grant ```task id: RAIL-K8S-WP-0003-T02 status: todo priority: high ``` A public Ingress class is emitted only when the declaration carries a valid grant. An Ingress object is not itself a grant. **Done when:** an ungranted rapp cannot obtain a public Ingress from the paved path.