Skip to content

feat(lab): Enforce traffic policy in the containerlab lab - #871

Merged
privateip merged 1 commit into
feat/traffic-policy-routerfrom
feat/traffic-policy-lab
Oct 15, 2026
Merged

privateip merged 1 commit into
feat/traffic-policy-routerfrom
feat/traffic-policy-lab

Conversation

@privateip

Copy link
Copy Markdown
Collaborator

Summary

Traffic policy can be enforced end to end, but nothing yet exercises it on real traffic, and no guide says how to turn it on in a cell.

The containerlab lab now enforces it from the start, binding every tenant in both directions to grants for only the traffic its checks send, and a new lab check proves an allowed and a denied, counted flow on private, NAT and public service traffic and on the built-in default. A rollout guide covers install order, writing grants, auditing with the counters, enforcing and backing out.

Production stays off, and this has not run on a live lab yet, because the only lab available belongs to another session; until it does, the PR stays a draft.

Test plan

  • On a fresh lab, deploy succeeds and the full verify suite passes with enforcement on
  • The new lab check passes, including each denial and its counter
  • Fixture tests reject an invalid lab policy and an unbound tenant interface
  • Build, lint, unit and e2e tests pass

Stacked on #870. Related to #691

🤖 Generated with Claude Code

@privateip privateip self-assigned this Oct 15, 2026
@privateip

Copy link
Copy Markdown
Collaborator Author

Detail for reviewers.

Review order: deploy/containerlab/Taskfile.yaml (new build:galactic-controller, deploy:traffic-policy between cert-manager and the router, each deploy:nsNN now policy then pods then attachments, verify:traffic-policy last), then resources/galactic-controller/ (host network, ports 10261-10263, one replica, Recreate, no PDB, for the reasons in its comments), resources/tenants/policies/ and each tenant's policy/, the three new scripts, and verify-traffic-policy.sh.

Grant sets: private-nat (ns10, ns20, ns30, ns71) grants Private and PublicNAT both ways, with Private ingress denying TCP 9 for the negative check; private (ns40) grants Private only; public-service (ns60) grants PublicService only. Neighbor discovery and RA toward the workload are link operations, outside the rules. publish-attachments.sh replaces publish-ns60-attachments.sh: it creates any missing VPCAttachment from its NAD and writes status including hostInterface (G%09s%03sH, the same as intf.GenerateInterfaceNameHost, checked for 60a and 30/31).

Two existing scripts change: verify-gateway-ingress.sh --node now skips sites without the named gateway (it previously failed every other site's backends, and nothing used the flag), and verify-nat-active-active.sh leaves ns60's backends out of its tenant set, since their egress grants only PublicService.

Validation on 0d7ce46 (base 870e5a1): task build test:unit test:e2e pass; golangci-lint clean; yamlfmt clean on every new and changed YAML; bash -n and shellcheck clean on the scripts; TestLabPoliciesAreValid and TestLabTenantsAreBound pass and fail when a set gains an invalid rule or a NAD loses its binding. Against the running lab, read only: the attachment discovery found every computed host interface on its node, the TCP probe connects to a listener and fails without one, and each worker's router metrics port answers.

Gap: no live deploy or task verify with enforcement on. The running lab is another session's, so it was not redeployed. A pre-push review found three blockers, all fixed here: NAT active-active would have included ns60, the gateway check's --node failed other sites, and a rolling update of a one-replica host-network Deployment could never place its surge pod.

@privateip
privateip added this pull request to stack #872 October 15, 2026 17:15
@privateip
privateip marked this pull request as ready for review October 15, 2026 17:16
@privateip
privateip requested a review from a team as a code owner October 15, 2026 17:16
ecv
ecv previously approved these changes Oct 15, 2026
scotwells
scotwells previously approved these changes Oct 15, 2026
The containerlab lab now runs interface traffic policy end to end, in
enforce mode, while production stays off. It installs the
galactic.datumapis.com CRDs and galactic-controller (on the host network,
since the control plane cannot reach worker pod addresses, like
cert-manager's webhook), turns on the router's reconciler, and binds every
tenant attachment, in both directions, to a policy set granting only the
paths that tenant's checks use. A generic attachment publisher replaces the
ns60-only one and writes every attachment's status, including the host
interface the bindings attach to.

verify:traffic-policy proves each binding is installed and, for the
Private, PublicNAT and PublicService paths and the built-in default, that a
grant forwards and a denial drops and is counted. Two envtest-backed tests
keep the fixtures valid and every tenant NAD bound. docs/traffic-policy/
rollout.md is the operator guide for turning policy on in a cell.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@privateip
privateip dismissed stale reviews from scotwells and ecv via 221ea1a October 15, 2026 18:17
@privateip
privateip force-pushed the feat/traffic-policy-lab branch from 0d7ce46 to 221ea1a Compare October 15, 2026 18:17
@privateip
privateip requested review from ecv and scotwells October 15, 2026 18:23
@privateip
privateip merged commit 2c562cf into main Oct 15, 2026
21 checks passed
@privateip
privateip deleted the feat/traffic-policy-lab branch October 15, 2026 18:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants