Skip to content

Split octopus across two hostnames: public webhook + internal UI

Date: 2026-06-06 Status: Accepted Decision: hl-8g4 Deciders: Sean Brandt

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.

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.

  • 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_services Tunnel pattern and the router-hosts annotation are already proven in the cluster (argocd-wh, tandoor, dolt) — this reuses existing primitives with no new infrastructure.
  • 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_services Tunnel 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.
  • 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_URL pointing at the webhook host would silently break OAuth callbacks.
  • Neutral: the exact tunnel service_url target (direct Service vs. via Traefik websecure) mirrors the argocd-wh entry and is confirmed at plan time.