box/templates/staging/box.env
dan-claude-bot f4f25016d6 feat(templates): thin creds-free seeds — box mints, rig converges (#81)
The tenant content that lived in claude/codex/grok's cloud-init — agent CLI
installs, docker, node, the per-template agent-context heredocs — moves to
rig's bootstrap roles (rig#31), where it is convergent, idempotent and
testable end to end. What remains per template is a thin seed: the tenant
user, tmux (#65), and rig preinstalled — nothing that joins a tailnet or
admits credentials.

- BOX_BOOTSTRAP_ROLE: a template names the creds-free rig role cmd_new
  auto-runs inside the guest after cloud-init settles. The value is a role
  NAME by allowlist — anything shell-shaped dies at parse time, on the
  host. A failed role leaves the box up and names the re-run.
- render_userdata: the seed's ONE substitution. @RIG_REPO@/@RIG_REF@
  resolve from the mint environment (default heavy-duty/rig @ main —
  unpinned, the honest rig#29 treatment, until rig#32's releases); values
  are whole-string-validated before touching the YAML, because they land
  inside a runcmd shell line.
- templates/staging: the re-cut of #69's layering — user ops,
  BOX_REQUIRE_VM=1, BOX_AUTOSTART=1, role staging. The tailnet workload
  join holds a key and stays operator-run; cmd_new prints it as the next
  step and box never sees the key.
- blank stays a box with nobody home: no rig, no role, nothing auto-runs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 20:51:27 +00:00

24 lines
1.3 KiB
Bash

# The staging template — a thin, creds-free, server-class seed (#81, the
# re-cut of #69's layering): Debian 13, the 'ops' user, tmux and rig. The
# server posture — docker, sshd hardening — is rig's job: box auto-runs
# 'rig bootstrap staging' after mint (heavy-duty/rig#31). The tailnet
# workload join holds a key and therefore STAYS operator-run:
# box shell <name> # then: sudo rig bootstrap workload --hostname <name>
# KEY="value" only. Parsed against an allowlist, never sourced; there is no
# key for a network or a security flag, on purpose — the shared box-net
# profile is the placement contract and no template can weaken it.
# The two boot demands (#68): the VM is this box's trust boundary and its
# guest runs docker, so no container fallback (BOX_REQUIRE_VM); and a server
# must return from a host reboot without an operator (BOX_AUTOSTART).
# BOX_USER must match the user user-data.yaml creates (the duplication is
# deliberate and by hand) — and it is the tenant user the rig role converges
# (rig dies loudly if the seed did not create it).
BOX_DESCRIPTION="Server-class Debian 13, creds-free — box mints, rig converges, the join stays yours"
BOX_IMAGE="images:debian/13/cloud"
BOX_USER="ops"
BOX_CPU="4"
BOX_MEMORY="8GiB"
BOX_DISK="60GiB"
BOX_REQUIRE_VM="1"
BOX_AUTOSTART="1"
BOX_BOOTSTRAP_ROLE="staging"