Split octopus across two hostnames: public webhook + internal UI
Date: 2026-06-06 Status: Accepted Decision: hl-8g4 Deciders: Sean Brandt
Context
Section titled “Context”Octopus serves two distinct trust contexts from one application: a GitHub webhook endpoint that must be internet-reachable and is secured by HMAC signature, and an admin UI that must not be internet-exposed and is secured by Better Auth (GitHub OAuth + ADMIN_EMAILS). A single hostname forces a choice between exposing the UI or blocking the webhook. The cluster already has the argocd-wh.fzymgc.net webhook_services pattern and the router-hosts annotation for LAN/Tailscale-only internal services.
Decision
Section titled “Decision”Deploy one ClusterIP Service. Expose the webhook via a Cloudflare Tunnel webhook_services entry (octopus-wh.fzymgc.net) and the admin UI via a Traefik IngressRoute with the router-hosts.fzymgc.house/enabled annotation (octopus.fzymgc.house). Set BETTER_AUTH_URL/NEXT_PUBLIC_APP_URL to the internal host. Do not apply blanket forward-auth.
Rationale
Section titled “Rationale”- The webhook trust boundary is the GitHub HMAC signature (
GITHUB_WEBHOOK_SECRET), not a session/SSO token — the proxy must not intercept it. - The admin-UI trust boundary is Better Auth (GitHub OAuth gated by
ADMIN_EMAILS), sufficient for a single-admin homelab without an extra Authentik layer. - Both the
webhook_servicesTunnel pattern and therouter-hostsannotation are already proven in the cluster (argocd-wh, tandoor, dolt) — this reuses existing primitives with no new infrastructure.
Alternatives Considered
Section titled “Alternatives Considered”- Single public hostname for webhook + UI — simpler ingress, but exposes the admin UI to the internet (wider attack surface even behind Better Auth); contradicts the cluster principle of keeping admin UIs off the internet.
- Single internal hostname + a Cloudflare Worker/proxy forwarding the webhook — UI stays internal, but adds a new external component; the
webhook_servicesTunnel entry is already the correct primitive. - Blanket Authentik forward-auth on the internal host — centralized SSO, but forward-auth intercepts
/api/github/webhook, breaking HMAC-signed delivery; Better Auth already suffices.
Consequences
Section titled “Consequences”- Positive: the admin UI is never internet-reachable regardless of Better Auth misconfiguration; webhook delivery works without session/SSO interception; both ingress patterns are proven and maintained.
- Negative: two hostnames serve one app — documentation is needed to avoid confusion; a
BETTER_AUTH_URLpointing at the webhook host would silently break OAuth callbacks. - Neutral: the exact tunnel
service_urltarget (direct Service vs. via Traefikwebsecure) mirrors theargocd-whentry and is confirmed at plan time.