Skip to content

Connecting Tailscale

Updated View as Markdown

A session running in an environment with Tailscale reaches the same private services your team reaches: an internal API, a staging database, anything behind a subnet router.

Each computer joins your tailnet as a tag-owned, ephemeral node. Your access control policy decides what it reaches. Tailscale removes the node about an hour after it goes offline.

A session suspends when it’s been idle, which takes its computer offline. A session suspended for long enough loses its node and rejoins your tailnet with a new address when it resumes.

Requirements

  • Owner, Admin, IT admin, or Network admin access to your tailnet.
  • An environment for the repository your sessions run in.

Prepare your tailnet

Create a tag

Add tag:indent to tagOwners in your access control policy.

"tagOwners": {
  "tag:indent": ["autogroup:admin"],
},

Grant the tag access

A computer reaches nothing until a grant names its tag.

"grants": [
  {
    "src": ["tag:indent"],
    "dst": ["tag:staging"],
    "ip": ["tcp:443", "tcp:5432"],
  },
],

Create an OAuth credential

On the Trust credentials page, generate an OAuth credential with Keys → Auth Keys → Write and the tag tag:indent.

Copy the client secret. Tailscale shows it once.

An OAuth client secret doesn’t expire. An auth key expires after at most 90 days.

Configure the environment

Open the environment from Settings → Environments and select the Configure step.

Ask Indent to install Tailscale

Indent writes the Dockerfile, so ask it to install Tailscale from tailscale.com/install.sh. The Dockerfile gains a line like this one:

RUN curl -fsSL https://tailscale.com/install.sh | sh

The Tailscale daemon starts when the computer boots.

Add the client secret to Runtime variables

Select Add variable, enter TS_AUTHKEY as the key, and paste the client secret as the value. Indent sees the key, never the value.

Use Runtime variables rather than Environment variables. The latter applies to the build, and the secret is needed while the computer is running.

Add a process that joins the tailnet

Under Processes, select Add process, name it tailscale, and set its Command to:

while true; do sudo tailscale status >/dev/null 2>&1 || sudo tailscale up --auth-key="${TS_AUTHKEY}?ephemeral=true&preauthorized=true" --advertise-tags=tag:indent --hostname="indent-${COMPUTER_ID}" --accept-routes --shields-up; sleep 30; done

ephemeral=true registers a node that Tailscale removes on its own. preauthorized=true skips device approval. --shields-up blocks inbound connections, so the computer reaches your tailnet and your tailnet does not reach the computer. --accept-routes picks up the routes your subnet routers advertise. Names resolve through MagicDNS when your tailnet has it enabled.

COMPUTER_ID is set on every computer, so each node gets its own name. The loop rejoins the tailnet after a suspension long enough to have removed the node.

Confirm it works

Select Build + Verify, then Publish. Start a session in the environment and ask Indent to run tailscale status, or to reach one of the services you granted. The node appears on your Machines page as indent-<computer id>.

Revoke access

Revoke the credential on the Trust credentials page to stop new computers from joining. Computers already on your tailnet keep their access. Delete their nodes on the Machines page, or ask Indent to run tailscale logout, which removes a node immediately.

Troubleshooting

Ask Indent to read ~/.indent/background-processes/tailscale.log.

  • API token invalid — the secret in TS_AUTHKEY is wrong or revoked.
  • requested tags are invalid or not permitted — the credential doesn’t own tag:indent.
  • The node joins and reaches nothing — no grant names tag:indent.
  • A tailnet with Tailnet Lock enabled rejects node keys that a signing node hasn’t signed. This setup doesn’t sign them.

Next steps

Navigation

Type to search…

↑↓ navigate↵ selectEsc close