Greenfield spec set for a GitOps-driven PaaS+IaaS home platform: vision & requirements (R-* IDs), architecture, 14 domain specs, 11 ADRs, roadmap (phases + workstreams), and AI-agent coordination (roles, protocol, definition-of-done, task board). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2.5 KiB
2.5 KiB
ADR-0008 — VPN egress model: Gluetun sidecar (default) + Cilium Egress Gateway
- Status: Accepted
- Date: 2026-08-15
- Serves: R-NET-05, R-NET-06, R-NET-07
- Supersedes: —
Context
A subset of services (sonarr, radarr, jackett, qbittorrent) must egress only through a commercial
VPN, with a kill-switch guaranteeing no leak to the plain internet if the tunnel drops. Egress
class must be a declarative service property (egress: vpn) that doesn't force a workload rewrite.
Decision
Adopt a two-pattern model behind the single egress: vpn contract, with Gluetun sidecar as the
default for the initial catalog:
- Default — Pattern A: Gluetun sidecar per pod. A Gluetun container holds the WireGuard/OpenVPN tunnel; the app shares its network namespace. Gluetun's built-in firewall kill-switch blocks all non-tunnel egress by default — satisfying R-NET-06 intrinsically and per-service.
- Available — Pattern B: central VPN egress gateway + Cilium Egress Gateway. One (HA) gateway
holds the tunnel; Cilium Egress Gateway steers
vpn-labeled pods through it, with policy denying any fallback to the internet path. Use when tunnel count must be minimized.
The service-facing contract is identical for both: declare egress: vpn; the platform wires the
chosen pattern. Kill-switch behavior is a hard acceptance gate for both.
Alternatives considered
- Central gateway only — fewer tunnels but a shared failure domain and more complex kill-switch guarantees across the fabric; kept as Pattern B, not the default.
- Node-level policy routing / per-node VPN — couples egress to node identity, harder to reason about per-service; rejected as the primary model.
- App-native VPN config — rejected: not declarative, not uniform, easy to misconfigure and leak.
Consequences
- Per-service isolation and an intrinsic kill-switch out of the box (Pattern A).
- More sidecars/tunnels at scale (Pattern A) — Pattern B is the escape hatch if the VPN provider limits concurrent tunnels/egress IPs (OQ-3).
- Kill-switch must be fault-tested (tunnel forced down ⇒ zero internet egress) as a standing acceptance gate, not a one-time check (03, R-NET-06).
- VPN credentials are SOPS-encrypted (ADR-0007). WireGuard preferred over OpenVPN where supported.
Open questions
- OQ-3 — VPN provider/protocol and concurrent-tunnel/egress-IP limits (drives Pattern A vs B and gateway HA).