Source on GitHub

buildbox

Let your agent think inside the box.

Spin up a disposable cloud machine for your coding agent, reachable only over Tailscale.

go install github.com/hkluke/buildbox@latest

For macOS and Linux. Needs Go 1.27 or later, Tailscale, and a Hetzner Cloud account.

One command makes a box. One throws it away.

buildbox talks to Hetzner only to create and delete servers. Everything else, your logins included, goes over your tailnet.

  1. buildbox init

    Once. Writes the config, adds the lines your tailnet policy needs after showing you each change, and creates the firewall.

  2. buildbox create dev

    An Ubuntu server on Hetzner Cloud joins your tailnet, tagged, with the agent’s tools installed. It’s ready in a few minutes.

  3. ssh dev

    You’re in as agent. scp, rsync, and remote-SSH editors work the same way, and ssh agent@dev works from any of your devices.

  4. buildbox delete dev

    The server and its SSH entry are gone. A box is billed by the hour until you delete it.

[ ~ ] buildbox create dev
buildbox create dev · cx23 · fsn1 · ubuntu-26.04
✓ Firewall buildbox-tailscale-only
✓ Auth key minted for tag:buildbox, one-time
✓ Server created 8s
✓ Tailnet 100.87.212.79 2m 21s
✓ SSH reachable
✓ cloud-init done 5s
✓ Docker rootless, running
✓ Git Ada Lovelace <ada@example.com> 1s
✓ SSH config Host dev added
dev is ready in 2m 36s
ssh dev connect as agent, projects in ~/projects
ssh admin@dev with sudo
buildbox delete dev delete it when you are done
[ ~ ]
buildbox create, sped up.

A machine of its own

The agent works on its own server, out of reach of your files, your browser sessions, and your cloud credentials.

Inside the box

agent
The user your coding agent works as. It has no sudo.
Rootless Docker
Runs as agent, never as root.
Git, a C toolchain, and Python 3
The agent installs the language runtime a project needs in its own home, or builds in a container.
The coding tools you choose
OpenCode, Claude Code, Codex, or Grok Build, installed but not signed in. You sign in on the box, so buildbox never sees those credentials.
Your Git key
Ideally a dedicated one, such as a deploy key. init can generate it.
admin
For you, with sudo.

Out of its reach

The internet
Hetzner’s Cloud Firewall and a firewall on the box both admit only Tailscale. create refuses a firewall that allows more.
Your other devices
No rule in your tailnet policy lets a box reach them, once the default allow-all rule is narrowed. init offers to narrow it.
Keys for logging in
OpenSSH is off. You log in through Tailscale SSH, and your tailnet policy decides who gets in, by the device you connect from.
Lasting secrets
The box gets a single-use auth key, spent when it joins your tailnet. The OAuth client that mints those keys stays on your machine, in a file only you can read.

Commands

buildbox help <command> describes each one. list --json and price --json keep their keys stable for scripts.

buildbox init
Write the config, set up your tailnet policy, and create the firewall.
buildbox create [NAME]
Create a box.
buildbox list
List your boxes and their Tailscale addresses.
buildbox price
Show what each server type costs in each location, or the cheapest one that fits your cores, memory, and disk.
buildbox forward NAME PORT...
Bring a port on the box, such as the agent’s dev server, to localhost here, until Ctrl-C.
buildbox delete NAME
Delete a box and its local SSH entry. A server without the buildbox=true label is refused unless you pass --force.