Skip to content

docs: design for BYOC public HTTP ingress#730

Open
hsinatfootprintai wants to merge 2 commits into
mainfrom
docs/byoc-public-ingress
Open

docs: design for BYOC public HTTP ingress#730
hsinatfootprintai wants to merge 2 commits into
mainfrom
docs/byoc-public-ingress

Conversation

@hsinatfootprintai

Copy link
Copy Markdown
Contributor

Why

A box on a tunnel-joined BYOC host runs fine but its public subdomain returns an empty page — only the control path (peer-proxy /peer/<id>/…) is wired; public app HTTP never crosses the tunnel to the box. (Surfaced while validating the hosted agent-workspace: the box on the lab host is healthy + its in-box auth proxy works locally, but the cloud-minted subdomain hits the edge with no path to the box.)

Key finding — the transport already exists

  • The tunnel already forwards :443 (pool join --ports 22,8080,443).
  • The sentinel SNI router already DialTunnel(spotID, port)s into a host — but only for hosts promoted to primary.

So BYOC ingress is mostly routing metadata, not new transport: teach the SNI router to resolve a BYOC box's subdomain → its host's tunnel and pass TLS through to the host's Caddy, which already terminates TLS and reverse-proxies to the box.

Missing links (designed in the doc)

  1. An authoritative subdomain → host map pushed cloud→sentinel (the cloud is the authority; hosts must not self-announce → anti-hijack), proto-first.
  2. Cert story — Phase 1: operator-host DNS-01 (lab/operator hosts only); Phase 2: central cert sync, or sentinel TLS-terminate + plaintext forward (gated on whether third-party BYOC ingress is in scope).

Phasing

Phase 1 is a path-only validation on an operator-owned lab host with zero new control APIs — proves SNI pass-through + tunnel:443 + host Caddy end to end before any sentinel code change.

Doc only — no code changes. Anonymized per repo conventions.

🤖 Generated with Claude Code

hsinhoyeh and others added 2 commits June 19, 2026 14:03
A box on a tunnel-joined BYOC host runs fine but its public subdomain returns
an empty page — only the control path (peer-proxy) is wired; public app HTTP
never crosses the tunnel to the box. This documents the gap and a phased design.

Key finding: the transport already exists. The tunnel forwards :443 by default
(pool join --ports 22,8080,443) and the sentinel SNI router already DialTunnels
into a host for tunnel-PROMOTED primaries. BYOC ingress = teach the SNI router
to resolve a BYOC box's subdomain to its host's tunnel and pass TLS through to
the host's Caddy (which already terminates + routes the box). Missing links:
an authoritative cloud→sentinel subdomain→host map (cloud is the authority, no
host self-announce → anti-hijack), and a cert story (Phase 1: operator-host
DNS-01; Phase 2: central cert sync or sentinel TLS-terminate + plaintext
forward, gated on whether third-party BYOC ingress is in scope).

Phase 1 is a path-only validation on an operator-owned lab host with zero new
control APIs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…minate

Walking the path on the lab BYOC host confirmed transport is fine (tunnel
carries :443; host:443→box-Caddy is a trivial incus proxy device) but the box
host's Caddy has no cert for the managed wildcard (no DNS-01 token, no public
:80) → public TLS aborts. Terminating TLS on the host needs a cert/token per
BYOC host — a credential leak for third-party hosts. So the primary model flips
to: sentinel terminates TLS (holds the wildcard) + plaintext-forwards to the box
port over the tunnel (8080 already forwarded); host stays cert-free.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

2 participants