rail-kubernetes/workplans/RAIL-K8S-WP-0003-private-by-default-networking.md
codex 29305d4bdf chore(registrar): assign State Hub identifiers
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
2026-08-22 13:01:29 +02:00

2.5 KiB

id type title domain repo status owner topic_slug created updated related state_hub_workstream_id
RAIL-K8S-WP-0003 workplan Private-by-default networking until an exposure grant exists financials rail-kubernetes finished codex railiance 2026-08-15 2026-08-22
RMASTER-WP-0023
ADR-0008
ADR-0006
55ab4f28-b6a8-53ad-8ea4-2dc8fe91b681

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

id: RAIL-K8S-WP-0003-T01
status: done
priority: high
state_hub_task_id: "8c4c7c80-0c5e-5498-8054-ec47acb5b4ba"

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.

Outcome (2026-08-22): generated overlays now render an explicit ClusterIP Service, a default-deny ingress NetworkPolicy, and no Ingress by default. The scaffold regression test renders the generated chart and asserts all three properties.

T02 — Gate public Ingress on the grant

id: RAIL-K8S-WP-0003-T02
status: done
priority: high
state_hub_task_id: "40f6f415-18f1-594e-ac21-35263b2aa532"

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.

Outcome (2026-08-22): Stage 2 renders the chart before server dry-run or apply and validates any Ingress/IngressRoute against both the rapp and reef declarations. Private is the fail-closed default; a public surface requires a matching grant and production-approved binding admission. Regression tests cover missing, mismatched, and valid grants.

Completion evidence

  • python3 -m unittest discover -s tests -v: 6 tests passed.
  • Generated overlay tests/stage2-template.sh: passed, including Helm render.
  • bash -n tools/create_railiance_overlay_repo.sh: passed.