Upstream, unmodified
The official Tailscale clients on every device. Headscale for control, and derper built from the locked Tailscale source. No forks and no patches.
Open-source overlay network
Tailgate runs the official Tailscale apps against your own Headscale server and your own DERP relays. It adds the rest: checked config, pinned builds, private HTTPS, and a console that decides which device reaches which service.

Watch it work
The stock app signs in to your server. Three devices, all yours. From the public internet: nothing.
# the stock app signs in to your server
tailscale login --login-server=https://tailgate.example.com
Success.
# three devices, all yours
tailscale status
100.120.0.7 laptop macOS
100.120.0.10 homelab linux
100.120.0.11 nas linux
# a private app with a real certificate
curl -sI https://photos.apps.example.com
HTTP/2 200
# from the public internet: nothing
curl -m 5 https://photos.apps.example.com
curl: (28) Connection timed out after 5001 ms
What changes
Your devices run the official Tailscale app, unchanged. What changes is where it connects. Sign-in, keys and policy come from your own Headscale coordination server. When two devices cannot reach each other directly, traffic goes through your own DERP relays.
| Aspect | Hosted Tailscale | Tailgate |
|---|---|---|
| App on devices | The official Tailscale app | The same official Tailscale app, unmodified |
| Coordination server | Tailscale's hosted coordination service | Headscale, on a host you run |
| Relays (DERP) | Tailscale's worldwide DERP fleet, plus any custom servers you add | Your own DERP servers, built from locked source. No Tailscale relay map. |
| Network metadata | Devices, peers and policy live on Tailscale's service | Devices, peers and policy live on your host |
| Sign-in | Your tailnet's login, through Tailscale's service | Google sign-in (OIDC) to your own Headscale |
| Access policy | Edited in Tailscale's admin console | Starts deny-all. You grant device, service and port in your console. |
| Private HTTPS | Certificates on ts.net names | Trusted certificates for your own domain, served only on the overlay |
You run it, so you keep it up, patched and backed up. If your relays are down, devices with no direct path cannot connect.
The cost
Tailgate is free and open source. Running it is not free. You pay for the hosts and for your time. We run ours on VMs we already had.
What it costs to run
Tailgate
Software license$0
Headscale VMone you have
DERP relay hostsones you have
Updates, backups, uptimeyour time
Why upstream
The hard parts already exist. Tailgate does not rewrite them. It runs them as they ship, pins the exact versions and checks the checksums. You only have to read the code Tailgate adds, and there is not much of it.

The official Tailscale clients on every device. Headscale for control, and derper built from the locked Tailscale source. No forks and no patches.
The control plane and the relays run on hosts you choose. There is no hosted coordinator, and no relay map is fetched from Tailscale.
Validated config, pinned and checksummed artifacts, private HTTPS, and a small console for access. No networking code. No crypto.
Deploy
Write down what you want in one file. Tailgate checks it before it touches anything. Then it puts the pieces on your host.

Name your domain, relays, devices and services in one file, and Tailgate tells you whether it holds together.
$ python3 tools/tailgate.py validate tailgate.json
Headscale, the relays, the certificates and the console go onto the host you chose.
Installer coming soon Until then, the bundle is rendered and installed by hand.
You bring a host, a domain, and DNS that can answer a certificate challenge.
# describe it and check it
python3 tools/tailgate.py validate examples/pilot.json
Input valid
# render the bundle; nothing is installed
python3 tools/tailgate.py render examples/pilot.json \
--output build/pilot
Bundle rendered
ls build/pilot
README.txt headscale.json records.json
controller.nginx.conf manifest.json tailgate.service
derp.json policy.json tailgate-exit.service
Private apps
Each service listens on its overlay address, port 443, with a publicly trusted certificate from a DNS challenge. Browsers trust it and the public internet cannot reach it. There is no public listener to find.

# check the app list, then render it
python3 tools/applications.py validate \
examples/application.json \
examples/application-platform.json
Valid application and platform
python3 tools/applications.py render … \
--output build/sample-app
95b4b222363fdc099c34306202a1c62c…
# same input, same plan hash
ls build/sample-app
README.txt plan.json private-service.json
compose.yaml private-nginx.conf
Connection path
Devices talk to each other directly, encrypted with WireGuard under the Tailscale client. When there is no direct road, the packets go through your own DERP relay, still encrypted. The relay cannot read them. The control plane makes introductions. It does not carry traffic.
# first through your own relay
tailscale ping homelab
pong from homelab via DERP(tg-fra) in 41ms
pong from homelab via DERP(tg-fra) in 39ms
# then the two devices find each other
pong from homelab via 203.0.113.24:41641 in 6ms

Access
A device that joins gets an address and nothing else. You grant it each service and port in the console. Signing in with Google proves who you are. It does not open anything.
{"grants":[]}.Coexistence
A server can stay on hosted Tailscale and run a second Tailgate client in its own network namespace, and the two stay apart. An optional gateway bridges only the users you list. An empty list means nobody.
Open source
Tailgate is open source. The part it adds is small, and it is meant to be read.

Safety
The parts that keep your network safe were written and reviewed by other people. Tailgate runs them as they ship, with no forks and no patches.
Tunnels and WireGuard encryption run in the official Tailscale apps, unmodified.
Device keys are made on the device. Headscale passes on the public half. Tailgate never touches them.
The relays are derper, built from the locked Tailscale source. They carry packets they cannot read.
lego gets the certificates from the CA. Nginx serves them. Tailgate only says where they go.
One exception: the optional console checks your Google sign-in itself. It is short, and it is the place to start reading.