From c76b26587df042a61ac1072721e746cad2fabb6d Mon Sep 17 00:00:00 2001 From: claude-hdb <278054522+claude-hdb@users.noreply.github.com> Date: Fri, 17 Jul 2026 15:53:14 +0000 Subject: [PATCH] =?UTF-8?q?docs(design):=20server-class=20boxes=20?= =?UTF-8?q?=E2=80=94=20overlay=20joins=20and=20snapshot-before-join?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 Co-Authored-By: Claude Fable 5 --- docs/box-design.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/docs/box-design.md b/docs/box-design.md index 037e929..7f863bd 100644 --- a/docs/box-design.md +++ b/docs/box-design.md @@ -188,6 +188,39 @@ certificate) and asserts the absence afterwards. A failed `grant` backs its own group-add out on exit for the same reason: no half-granted user holding an un-narrowed socket. +## Server-class boxes: joining an overlay from inside + +"No inbound path" is a claim about the **host's network position**: box builds +no route in — no SSH, no forwarded port, no LAN listener beyond `expose`'s +loopback door. It was never a claim about what a guest may do with its own +outbound reach. A guest can deliberately join an overlay network (a tailnet) +from inside and invite management in over the tunnel it established — the +host-side stack only ever sees allowed outbound UDP, and every rule above +still holds: the box still cannot reach the host, the LAN, or a sibling box. +It is reachable *only* over the overlay. For a staging server that is not a +hole in the posture, it **is** the posture: tailnet-only, never LAN or public. + +The `staging` template is the sanctioned server-class use of that, and the +layering keeps each tool honest: + +- **box** mints the VM — docker + rig preinstalled, still strictly creds-free. +- **rig**, run *inside* the box (`box shell` → `sudo rig bootstrap workload`), + hardens sshd and joins the tailnet. rig holds the auth key in process + memory per its own contract; box never sees it. +- **cast** registers the box in the control plane by its tailnet address. + +Two template keys carry the server posture, and only those: `BOX_REQUIRE_VM` +(no container fallback — the VM is the trust boundary, and the guest runs +docker) and `BOX_AUTOSTART` (`boot.autostart`, so the box returns from a host +reboot without an operator). There is still no key for a network or a +`security.*` flag. + +**Snapshot before the join.** Clone from a snapshot taken *before* +`rig bootstrap` runs: a post-join clone carries its source's tailnet identity, +and two machines answering as one node is the overlay's version of the DHCP +collision `reset_identity` exists for. Mint → snapshot → bootstrap, in that +order. + ## Non-goals - Interactive-first: install and setup prompt by default (`BOX_YES=1` and the