Files
jakman85andClaude Opus 5.5 92944486d1
gate / gate (pull_request) Successful in 45s
gate / conformance (pull_request) Skipped
feat(dns): publish public names as proxied CNAMEs to the Cloudflare Tunnel
Gateway target -> fc81938b-...cfargotunnel.com, --cloudflare-proxied globally,
L4 service publishers (unifi, crafty-mc) pinned DNS-only, Plex web UI and
Headlamp disowned (LAN/VPN-only). L0 internal-services-publish-no-public-dns
gains assertion (9) tying the Gateway target to the tunnel UUID, requiring
cloudflare-proxied=false on every service-source publisher, and keeping the
tunnel's 404 list and the unpublished set consistent. L2 dns-exposure fixture
opts out of proxying.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-08 17:55:41 -06:00

39 lines
2.3 KiB
Markdown

# platform/gateway
**Gateway API** (north-south ingress) implemented by **Cilium** + the shared HTTPS Gateway and the
wildcard TLS certificate.
- **Governing ADRs:** [ADR-0002 — Cilium + Gateway API](../../../home-network-k3s/decisions/adr-0002-cni-cilium.md),
[ADR-0006 — cert-manager/Let's Encrypt](../../../home-network-k3s/decisions/adr-0006-tls-cert-manager-letsencrypt.md)
- **Spec:** [docs/09 — DNS & Ingress](../../../home-network-k3s/docs/09-dns-and-ingress.md)
- **Serves:** R-DNS-01, R-TLS-01
- **Owner:** WS-NET (+ WS-SEC for the cert)
## What this stub is
- **`GatewayClass` `cilium`** — Gateway API implemented by Cilium; no separate ingress controller
(ADR-0002).
- **`Gateway` `shared`** — HTTPS listener on `*.home.keithjackson.dev`, TLS terminated with the
wildcard cert. App HTTPRoutes attach cross-namespace via a namespace label + ReferenceGrant
(rendered by WS-APPS from each ServiceDefinition's `exposure`).
- **`Certificate` `wildcard-home`** — `*.home.keithjackson.dev` issued by `${ACME_CLUSTER_ISSUER}`
(staging in dev, prod in prod — R-ENV-02). Makes onboarding certificate-free (ADR-0006 default).
## Contract (Issuer + Gateway TLS)
The "Issuer + Gateway TLS" interface (`roadmap/workstreams.md`): this Gateway + wildcard cert are what
every service's HTTPRoute attaches to. ExternalDNS ([`../externaldns`](../externaldns)) publishes the
`public` records for hostnames routed here. Ingress opens **north-south** only — it does **not** relax
east-west default-deny (docs/09).
## TODO (later phases)
- **Phase 2 (WS-NET):** pin the L2-announced ingress VIP / IP pool (Cilium L2 announcement, docs/09);
add the HTTP→HTTPS redirect route; confirm the cross-namespace ReferenceGrant pattern with WS-APPS.
- **Public exposure** is via the **Cloudflare Tunnel** (2026-11-08, `platform/cloudflared`): the
Gateway's `external-dns.alpha.kubernetes.io/target` is `<tunnel-uuid>.cfargotunnel.com`, so every
published name is a proxied CNAME to the tunnel and cloudflared forwards to this Gateway's
ClusterIP. No inbound WAN 80/443 forward is needed (the old manual edge port-forward is retired —
runbooks/cloudflare-tunnel.md). LAN/VPN-only names (internal apps, plex, headlamp) carry
`controller: none` on their route and are 404'd by the tunnel.