Set up Tailscale (the connection wizard)
This is the question everyone asks before they buy: *how does your hub reach my machines without me opening my network to the world?* The answer is Tailscale — a private, encrypted, peer-to-peer network (a "tailnet") that only your devices can join. dev-mux rides on top of it. There are no inbound firewall holes, no public SSH port, and no VPN concentrator to run.
You do exactly one thing by hand: generate an auth key scoped to the tag tag:devmux-hub, and paste it into the dev-mux onboarding wizard. The wizard does the rest — your managed hub joins your tailnet and can reach your spokes over it.
This guide mirrors that wizard step by step.
Why Tailscale, and why it is safe
- Private by default. A tailnet is your own overlay network. Machines outside it cannot see or reach your hub or spokes. Nothing is exposed to the public internet.
- No inbound ports. Tailscale establishes connections outbound from each machine, so you never open port 22 (or anything else) to the internet. Your hub reaches a spoke because both are on *your* tailnet, not because the spoke is publicly reachable.
- Least privilege via tags. The auth key you generate is tagged
tag:devmux-hub. Tags are how Tailscale expresses "this node is a dev-mux hub, and here is exactly what it may talk to." The key authorizes precisely that role and nothing more. - We never hold your whole network. The auth key you paste authorizes a single hub node to join. It is stored encrypted (in Google Secret Manager on the managed side) and injected into your hub — it is not a standing credential to your Tailscale account.
Durability is not the network's job
A common misconception: people assume a special always-on tunnel is what keeps their agent sessions alive. It is not. Your sessions live on the hub inside tmux. dev-mux clients use tmux-backed sessions with automatic reconnect — so if your laptop sleeps, your Wi-Fi drops, or you roam from Wi-Fi to cellular, nothing is lost. You reconnect and land exactly where you left off, because the work was never running on your client.
Tailscale's job is *reach* (the hub can talk to your spokes); tmux on the hub is what provides *durability*. Keep those two ideas separate and the whole system makes sense.
Step 1 — Create your tailnet (once)
If you do not already have a Tailscale account, create one at tailscale.com and install Tailscale on the machines you want in your fleet. Signing in with your identity provider creates your tailnet automatically.
*The Tailscale admin console. This is where you will generate the auth key dev-mux needs.*
Step 2 — Open the auth keys page
In the Tailscale admin console, go to Settings → Keys (the auth keys page). This is where you mint the key you will paste into the dev-mux wizard.
!Tailscale admin console Settings, Keys tab, with a Generate auth key button highlighted.
*Settings → Keys. Click "Generate auth key" to start.*
Step 3 — Generate a tagged auth key
Click Generate auth key and configure it exactly as follows. Each option matters:
- Reusable — leave it single-use unless you are onboarding several hubs; a single-use key is the tighter default.
- Pre-approved — turn this on if you see it. This option only appears when your tailnet has device approval enabled (Settings → Device management); most tailnets have it off, and if yours does, Tailscale will not show the option at all — that is fine and nothing is missing. Where it does appear it matters: without it, your hub joins but sits unapproved and unreachable until you approve it by hand.
- Tags — add
tag:devmux-hub. This is the tag dev-mux expects; it declares the joining node as a dev-mux hub so your tailnet policy can grant it exactly the reach it needs. - Expiry — pick a short window (the key only needs to live long enough to paste it into the wizard). The key expiring does not disconnect your hub; it only stops the key from being reused.
*Generate the key with the tag tag:devmux-hub set — that tag is the whole trick. This tailnet has device approval off, so no "Pre-approved" option is shown; if yours has it on, turn it on here.*
> Note on tag ownership: the first time you use tag:devmux-hub, Tailscale asks you to declare who may apply it (in your tailnet's access controls / ACL policy). Add tag:devmux-hub to tagOwners for your own account. This is a one-time policy edit; after that you can mint tagged keys freely.
Step 4 — Copy the key
Tailscale shows the generated key once. Copy it now. It looks like tskey-auth-.... Treat it like a password: it authorizes a node to join your network.
*Copy the key immediately — Tailscale will not show it again.*
Step 5 — Paste it into the dev-mux onboarding wizard
Open the dev-mux onboarding wizard for your hub and find the Tailscale auth key field. Paste the tskey-auth-... value you just copied and continue.
*Paste the tag:devmux-hub key into the wizard. dev-mux stores it encrypted and injects it into your hub at provisioning time.*
Behind the scenes, dev-mux stores the key in a secret manager and injects it via the hub's instance metadata. You never place the key in a config file, a repo, or a log. The hub uses it exactly once — to join your tailnet — and then it is a normal, tagged node on your network.
Step 6 — Confirm the hub joined
Back in the Tailscale admin console, your hub now appears in the machines list, tagged tag:devmux-hub and connected. In the dev-mux cockpit, your hub shows as online and your spokes become reachable.
*The hub has joined your tailnet as a tagged node. Note Key expiry: No expiry — applying tag:devmux-hub disables node-key expiry automatically, so the hub will not silently drop off your network months from now. dev-mux can now reach your spokes over the private network.*
> Node key expiry is already handled. Tagged nodes do not expire — applying tag:devmux-hub disables node-key expiry for you (visible as Key expiry: No expiry above), so there is nothing to turn off by hand. This is one of the reasons the tag is not optional: an untagged hub would inherit the default expiry and drop off your network months later, in the middle of a working session.
What you did, in one sentence
You minted a tag:devmux-hub auth key, pasted it into the wizard, and your managed hub joined your private tailnet — giving the hub reach to your spokes with no inbound ports, while tmux on the hub (not the network) keeps your sessions durable through tmux-backed sessions with automatic reconnect.
Next steps
- Add spokes now that your hub is on your tailnet.
- Billing — note that a commercial Team tailnet is a paid Tailscale plan; see the pricing note there.
- Troubleshooting if a spoke shows
tailnet policy does not permit...or does not appear.