Machines inside your own network

Every boxd machine is reachable from the internet by default. For a team inside a company, that might not be what you want. Enable Tailscale for the org and the same machines answer only inside your tailnet.

Michiel VoortmanMichiel Voortman5 min readProduct
A cutaway of a small warm office at night: creatures at their desks, a machine plugged into the wall among them, a small card with the Tailscale dot mark pinned to the notice board, and one creature sliding the bolt across the front door while a lone figure stands outside on a cold blue street looking in.
On this page · 5 min

Every boxd machine is on the internet from the moment it exists. This includes a public hostname, a TLS certificate for it, and an SSH port on a public address. If you are building on your own, that is exactly what you want.

An engineering team inside a company already has a network, with a staging database, internal APIs, a security policy and Tailscale on every laptop. Its machines belong inside that network.

So we built the Tailscale integration. Turn it on for your organization and the same machines, same names, same certificates, answer only inside your tailnet.

Set up Tailscale for your boxd organization

The setup happens on boxd's edge servers, so there is nothing to install on your machines.

  1. Create an auth key and send it to boxd. In the Tailscale admin console under Settings, Keys: Reusable on, Ephemeral off, Tags empty. Reusable, because boxd adds one device per edge server. Send it to contact@boxd.sh or your shared Slack channel with your organization name. We turn Tailscale on for the organization and store the key encrypted. Self-service setup from the console is coming soon.
  2. Approve the devices. boxd's edge servers appear in your tailnet as boxd-proxy-*. Allow your users to reach them in your ACL and disable key expiry on each, since Tailscale expires untagged devices after 180 days.
  3. Join the tailnet on your laptop and carry on.
Terminal
curl https://myapp.boxd.sh     # HTTPS, same certificate as before
boxd connect myapp             # through the boxd API, works on or off the tailnet

Public by default

Every machine gets the same things at birth: a hostname, <name>.boxd.sh, a wildcard certificate so api.<name>.boxd.sh works, a port on the edge server's public IP for SSH, and any raw ports you expose.

Some companies require that nothing engineering touches sits on the public internet. IP allow-lists do not work here: the edge IP is shared by every boxd customer, and your engineers are not behind one office address. A bastion is one more machine to run, and a VPN into boxd is one more VPN. Tailscale is the network the team already has. That is why we decided a Tailscale integration was the right solution.

What changes when it is on

Who can reach your machines. DNS answers with a 100.x address that only exists inside your Tailscale network. On the tailnet you get the machine. Off it, an address that goes nowhere. Against boxd's public IP, a 404.

Everything else stays: myapp.boxd.sh, the subdomain proxies, your organization's wildcard domain, the certificates you had yesterday. HTTPS and SSH move to the tailnet together, and exposed raw ports leave the public path with them. Management does not move. The CLI, console and SDKs talk to the boxd API, which stays reachable from anywhere.

How the Tailscale integration works

boxd's edge servers terminate TLS, accept SSH and are what DNS points at. The edge is what your traffic hits, so the edge is what joins your tailnet.

Each edge server joins your tailnet. Each edge server runs one Tailscale node per enabled organization, inside the proxy process, through a small Rust shim over Tailscale's tsnet library, with no TUN device. The node is the boxd-proxy-* device in your admin console. Every edge server joins, even one holding none of your machines, so a machine placed on a fresh server has an address the moment it exists. Node state persists on disk, so a deploy reconnects the same device instead of adding one. Nodes are untagged, and their logs are not sent to Tailscale.

The listener identifies the organization. One node per organization means the listener that accepted a connection knows whose it is, and every connection carries that as a type:

Rust
enum Origin {
    Public,
    Tailnet { org_id: String },
}

Every lookup from a hostname or port to a machine takes an Origin, and a tailnet origin only finds machines in its own organization. The listener sets it, so nothing on the wire can fake it, and because it is an enum, a lookup that forgets to handle it does not compile. The usual owner and sharing checks still apply on top.

The public path is closed in three places. SSH and HTTPS refuse once the port or server name resolves to a tailnet machine. Exposed raw ports are a kernel firewall rule that never reaches our code, so that rule is simply never installed. All three answer 404, not 403, so a hidden machine does not confirm it exists.

DNS points the name at the tailnet. Each edge server records its tailnet address in boxd's replicated state, and boxd's nameservers answer a machine's name with the address of its edge server in that organization's tailnet. Never both addresses, and never the public IP as a fallback.

Names and certificates do not change. Machines keep their real names and the certificates they already have. Issuance uses DNS-01 challenges, which are TXT records, so where the A record points makes no difference.

Before you flip it

Everyone needs to be on the tailnet. Members outside it lose the hostnames. Tell the team first.

Custom domains, org-wide only. Your organization's wildcard domain follows the tailnet because boxd serves its DNS. A per-machine domain cannot, because its apex record lives in your DNS and points at boxd's public IP. boxd refuses the combination in both directions.

Auth keys expire within 90 days. It only matters when boxd adds an edge server. Mint a fresh key and send it over.

Some corporate resolvers strip the answer. DNS rebinding protection can drop 100.64.0.0/10 addresses, so a name resolves on one network and fails on another. Use a resolver that keeps them, or Tailscale's own DNS.

Who this is for

The machine, its name and its certificate stay the same. What changes is who can reach it.

This is for teams that want dev workspaces, preview environments and agents on boxd next to their staging database rather than on the public internet. It is included in Pay as you go. The Tailscale guide has the setup in full. Send your auth key to contact@boxd.sh and we will turn it on.

Michiel VoortmanMichiel Voortman
PostShare
Published
Sep 14, 2026
Reading time
5 min
Words
1,027
Topic
Product

Read next

Field notes

Subscribe for release notes and architecture write-ups

No spam, ever. Unsubscribe anytime.

Your inbox