SSD Nodes Learn 🎉 VPS from $5.50/mo
Guides Matt ConnorBy Matt Connor · Updated 2026-08-21

Is Tailscale secure? The trust model

Tailscale never holds the keys that encrypt your traffic. The real question is what a compromised coordination server or a stolen identity account can do.

Is Tailscale secure? The short answer

Is Tailscale secure? For the part most people worry about, yes: the coordination server that runs your tailnet never holds the private keys that encrypt your traffic, so it cannot read what your devices send each other. Tailscale's security page states it directly: "Private keys never leave the device. All traffic is end-to-end encrypted, always." The useful question is a different one. A coordination server that is compromised, or compelled by a legal order, does not need to read your packets. It decides which public keys your devices trust, so it could enrol a device you never approved.

That is the trust model in one sentence: encryption protects the data, and the control plane decides membership. Each section below names one party you have to trust, says what that party can actually do, and gives the control that limits it. If the product itself is new to you, start with what Tailscale is and how its mesh works.

The control plane and the data plane are separate

Tailscale is a mesh VPN (virtual private network) built on WireGuard, the same protocol you would configure by hand on a self-hosted WireGuard VPS. Every device generates its own WireGuard key pair locally. Tailscale's how it works post calls the coordination server "a shared drop box for public keys" and says "The private key never, ever leaves its node."

The data plane is the encrypted traffic between your devices. It travels device to device, direct whenever the network allows it. The control plane is everything else: which devices belong to the tailnet, which public key belongs to which device, the access policy, the DNS settings, and the relay list. Tailscale runs the control plane as a hosted service. You run the data plane on your own machines.

Keep those two apart and every security question here becomes answerable. Encryption is a property of the data plane. Membership is a decision of the control plane. No amount of encryption tells you who is allowed to be a peer.

What could a compromised coordination server do?

It cannot decrypt your traffic. The keys that perform the encryption are generated on your devices and never uploaded, so there is nothing to seize or leak that would open the tunnel. This holds for relayed traffic too, which is covered further down.

It could enrol a node. When Tailscale announced tailnet lock, the company described the risk in its own words: a malicious server could "use a secretly-added node to send or receive traffic to your existing nodes", and at that point "it wouldn't matter that the traffic is encrypted because the peer itself would be malicious". Your device trusts a peer because the control plane told it that key belongs in the tailnet.

It could change what your devices are allowed to reach. The access policy lives in the control plane and is distributed to the nodes. Tailscale's tailnet lock white paper says tailnet lock "does not prevent a compromised control plane from breaking connectivity in your network, such as by failing to distribute new node keys, or distributing an access control policy which denies access to all nodes."

It sees connection metadata either way. Tailscale's network flow logs record open and close events for every machine to machine connection. The documentation states those logs "strictly do not contain any information about client operations or contents of network traffic". So the control plane can know which of your devices talked to which, and when. It does not know what they said.

Only one item on that list is about encryption. The others are about who is a member and what the policy says, which is why the controls worth your attention are the ones that govern enrolment.

Your identity provider is the root of trust for the tailnet

Tailscale runs no password database of its own. Its documentation says plainly that there are no Tailscale passwords, and sign-in is delegated to an identity provider (IdP): Apple, Google, GitHub, Microsoft, Okta, OneLogin, or a custom OpenID Connect provider.

Read that as a security statement, because it is one. Whoever can sign into your Google or Microsoft account can sign into your tailnet. Your multi-factor authentication (MFA) is whatever the IdP enforces. Your offboarding is whatever the IdP does when a person leaves. A phished IdP account is a tailnet account, and the attacker never has to attack WireGuard: they add a device and inherit whatever your policy grants that user.

Two controls stand between a stolen identity account and a working device inside your tailnet: device approval and key expiry. Tailnet lock is a third, and it aims at the control plane rather than at the account.

Device approval: nothing joins until a person says yes

Tailscale's documentation describes device approval as a feature that "lets Tailscale network administrators review and approve new devices before they can join your Tailscale network". An Owner, Admin, or IT admin can approve. A new device shows a "Needs approval" badge on the Machines page until somebody acts on it.

Turn it on and the stolen-account story changes shape. The attacker signs in, the device registers, and then it waits, unable to reach anything, next to a badge in your admin console telling you that a machine you do not recognise is asking to join. Automation still works, because an auth key can be marked pre-approved when you generate it, and devices can be approved through the API.

Auth keys are the other way in, so treat them as credentials. Tailscale's documentation is blunt about the risky kind: "Be very careful with reusable keys! These can be very dangerous if stolen. They're best kept in a key vault product specially designed for the purpose." As of August 2026 the documented key expiry range is 1 to 90 days, and an unspecified expiry defaults to the 90 day maximum. Prefer one-off keys, mark them ephemeral for machines that come and go, and keep any reusable key encrypted with Ansible Vault or in a secrets manager rather than in a shell script.

Key expiry: the timer that limits every other mistake

Node keys expire, which is what turns a stolen or forgotten device into a temporary problem. Tailscale's documentation states that "By default, new domains are set with an expiry period of 180 days", and that "If reauthentication does not occur, keys expire and connections to/from the given endpoint will stop working." You can reauthenticate a device yourself:

tailscale up --force-reauth

The documentation warns that this "might bring down the tailnet connection and thus should not be done remotely over SSH or RDP without an alternate means to log in if the connection is lost." Run it with console access open, or from a second path into the machine, because you are about to interrupt the network you are using.

Servers are where this control gets bent. A machine that must reauthenticate every 180 days will fall off the tailnet at 3am when nobody is watching, so administrators disable key expiry on it. That removes the timer that would eventually cut off a stolen key. A tagged device is the better answer for a server, because a tag owns the machine instead of a person, so the machine survives that person leaving the company. Whatever you decide, keep a list of which machines have expiry disabled: those keys stay valid until you delete the device.

Tailnet lock: taking the coordination server out of the trust chain

Tailnet lock attacks the enrolment problem directly. Tailscale's tailnet lock documentation explains the mechanism: "When a new node joins the tailnet, its public node key requires a signature from a Tailnet Lock key. The coordination server distributes the signed public node key to peer nodes." Your existing devices verify that signature before they accept a peer, so a node key that the control plane invented on its own is refused.

tailscale lock status
tailscale lock sign nodekey:1abddef1 tlpub:abcdef12

tailscale lock init enables the feature, and you nominate your signing nodes at that moment. Tailscale requires at least two signing nodes at initialisation and allows at most 20 in a tailnet. After that, every new device needs a signature from one of them, which is a real operational cost: adding a phone means running a command on a laptop.

The limits are documented, and they matter more than the feature description:

  • Lose the disablement secret and there is no recovery. The documentation says "If you lose your disablement secrets, and you did not provide one to Tailscale support, the tailnet cannot be recovered."
  • The signing key lives on a device you own, so it inherits that device's security. The documentation is explicit: "If the device is compromised, the key can be obtained."
  • You cannot run both controls. Tailscale states that tailnet lock and device approval are mutually exclusive, so enabling one means giving up the other.
  • It is trust on first use (TOFU). The initial setup still passes through the control plane, and the anchor of trust moves into your own network only after that first step.

Tailnet lock protects membership. It does not protect availability, and the white paper says so.

Does a relayed connection expose my traffic?

No. When two devices cannot reach each other directly, traffic falls back to a DERP server (Designated Encrypted Relay for Packets). Tailscale's documentation states the property without hedging: "Because Tailscale private keys never leave the local device that generated them, it's impossible for a DERP server to decrypt your traffic. A DERP server blindly forwards already-encrypted traffic from one device to another."

A relay still costs you speed, and it observes metadata: two encrypted endpoints, plus the timing and the volume of what passes between them. Find out which kind of connection you actually have:

tailscale status
tailscale netcheck

tailscale status marks every peer as either direct, printed as direct 203.0.113.10:41641, or relayed, printed as relay followed by the relay name, with byte counters after it. A peer that stays on a relay means the two ends could not build a direct path, usually because UDP is blocked somewhere or because both sides sit behind strict NAT (network address translation). tailscale netcheck reports whether UDP works at all from that machine, how your NAT maps ports, and the latency to the nearest relays, which tells you which of those two causes you are looking at.

An exit node moves your egress, it does not remove it

An exit node routes all of a device's public internet traffic through another device on the tailnet, using the default routes 0.0.0.0/0 and ::/0. On Linux the machine offering the service advertises it, and each client opts in:

sudo tailscale set --advertise-exit-node
sudo tailscale set --exit-node=100.101.102.103
sudo tailscale set --exit-node=100.101.102.103 --exit-node-allow-lan-access=true
sudo tailscale set --exit-node=

An exit node has to be approved by an Owner, Admin, or Network admin in the admin console, and your policy has to grant autogroup:internet before a client may use it. Both steps are deliberate: an unapproved machine cannot quietly become the way out for your whole tailnet.

Now the trust question. Traffic is encrypted from your laptop to the exit node. It then leaves that machine as ordinary internet traffic, carrying that machine's IP address. So the exit node's operator sees your destinations, and so do that machine's hosting provider and its upstream network. You moved the observation point rather than deleting it. That is a good trade when you control the far end, which is the argument for running your own exit node on a VPS, and a poor one when you do not.

The default policy is a flat network

A new tailnet ships permissive. Tailscale's access control documentation says the default policy file "enables communication between all devices within the tailnet". Every device can reach every other device on every port. That is a flat network. You moved it inside the tunnel, which helps against outsiders and does nothing against a laptop that gets infected.

Tighten it in the tailnet policy file, which accepts access control lists (ACLs) or the newer grants, both written in a JSON dialect that allows comments:

{
  "acls": [
    {"action": "accept", "src": ["group:eng"], "dst": ["tag:prod:22"]},
    {"action": "accept", "src": ["autogroup:member"], "dst": ["autogroup:internet:*"]}
  ]
}

That policy lets one group reach SSH on production servers, lets members use an exit node, and denies everything else by omission. Tailscale lists which rule targets are available on which plan, so check that before you design around tags or autogroups, and see what the free plan actually includes. For a device that should never accept incoming connections at all, such as a personal phone, tailscale set --shields-up blocks them at the client.

What self-hosting the control plane with Headscale changes

Headscale is "An open source, self-hosted implementation of the Tailscale control server." Its README sets the scope honestly: "It implements a narrow scope, a single Tailscale network (tailnet), suitable for a personal use, or a small open-source organisation." Its feature list covers ACLs and grants, subnet routers, exit nodes, an embedded DERP server, Tailscale SSH, and Taildrop. If that narrow scope is the sticking point, NetBird is the other mesh that ships a self-hostable control plane, and running the NetBird server on your own VPS moves the same enrolment decision onto hardware you own.

What changes is the identity of the party that could enrol a rogue node. With Headscale, the key directory and the policy live on your server. No third party ever holds the list of your device public keys, and no third party can be compelled to hand one over or to sign one in.

What does not change is the data plane. It is the same WireGuard with the same end-to-end encryption, and the same relay fallback when a direct path is impossible. You also inherit the jobs Tailscale was doing: uptime, patching, backups, and the physical security of the box. A compromised Headscale host gives an attacker exactly what a compromised coordination server would give them, which is the power to enrol a node and to distribute policy. Tailnet lock is not on the Headscale feature list, so the compensating control for that specific risk is not available there. If the ownership question is the one that decides it for you, self-hosting the control plane with Headscale walks through the setup.

What Tailscale protects against

  • Public listening ports. A service bound to a tailnet address is not reachable from the internet, so the scanners that hit every VPS on port 22 never see it. The exception is one you switch on yourself, because Funnel publishes a tailnet service to the open internet on purpose, which is why it is worth knowing where serve ends and funnel begins before you run either command. Keep the host firewall anyway, because a published Docker port writes its own rules and bypasses ufw on the public interface.
  • Password guessing against exposed logins. There is nothing to spray when the port only answers inside the tunnel. That is a stronger position than rate limiting an open port, though fail2ban on Ubuntu 24.04 is still worth running on anything that has to stay public.
  • Untrusted networks in the path. Traffic between your machines is encrypted end to end over a café network or a shared provider LAN, and it stays encrypted when it is relayed.
  • Hand-managed key distribution. Every peer added by hand to a WireGuard config is a chance to reuse an address or paste the wrong key. The mesh does that bookkeeping for you, which is most of the practical difference in WireGuard against Tailscale.

What Tailscale does not protect against

  • A compromised endpoint. The tailnet trusts devices. Malware on an approved laptop gets the tunnel, the tailnet addresses, and whatever your policy grants that user. This is the largest gap, and no VPN closes it.
  • A malicious or careless administrator. Anyone who can edit the policy file can grant themselves access to anything, and anyone who can take over an Owner's identity account can do the same. Review policy changes the way you review code.
  • Traffic analysis. Your ISP (internet service provider) sees encrypted UDP flowing to an endpoint, plus timing and volume. Tailscale's flow logs see which peers talked and when. Neither sees contents, but the fact of a connection is not hidden, so read how Tor and a VPN differ before choosing a tool for that job.
  • A device you have already lost. Key expiry is a slow backstop at a 180 day default. Removing the device in the admin console is the fast one, so know where that button is before you need it.

Check your own tailnet

  1. Run tailscale status on a device and read the peer list. A machine you cannot name is the exact situation device approval exists to prevent.
  2. Run tailscale lock status to see whether tailnet lock is enabled, then decide whether the cost of signing every new device is worth it for your tailnet.
  3. Open the admin console and note every machine with key expiry disabled, plus every reusable auth key that still exists. Both are credentials without a timer.
  4. Read your policy file. If it is still the default, every device can reach every other device on every port, and one infected laptop reaches all of them.

Tailscale earns its reputation on the data plane, where the design leaves the operator no way to read your traffic. Take that claim as the vendor documents it, then audit the parts that are yours: the identity accounts, the approval setting, the expiry list, and the policy file. Tailscale's security page reports a SOC 2 Type II certification and ongoing security work with Latacora, which is evidence about their process rather than a statement about your configuration.

FAQ

Can Tailscale read my traffic?

No. Traffic is encrypted with WireGuard keys that are generated on your devices, and Tailscale's security page states that "Private keys never leave the device. All traffic is end-to-end encrypted, always." This also applies to connections that fall back to a DERP relay, because the relay "blindly forwards already-encrypted traffic from one device to another" and holds no key that would let it decrypt. What Tailscale's infrastructure does see is metadata: which devices exist, plus which of them connected to which and when.

What could a compromised Tailscale coordination server actually do?

It could enrol a node. Tailscale's own tailnet lock announcement describes the risk of a secretly added node that could "send or receive traffic to your existing nodes", where encryption does not help "because the peer itself would be malicious". A compromised control plane could also distribute a policy that changes what your devices reach, and the tailnet lock white paper notes it could break connectivity by failing to distribute new node keys. What it could not do is decrypt traffic between your existing devices, because it has never held their private keys.

Does an exit node hide my browsing from my ISP?

It hides the destinations from the network you are sitting on, including your home or café ISP, because everything leaves your device as encrypted traffic addressed to the exit node. It does not make you anonymous. The exit node sees those destinations instead, and so do its hosting provider and upstream network, while the sites you visit see the exit node's IP address. You chose a different observer, so pick one you actually trust.

Is Headscale more secure than Tailscale's coordination server?

It is a different trust decision rather than a strictly safer one. With Headscale you hold the key directory and the policy, so no outside party can be compelled to enrol a device in your tailnet. You also take on running that server: patching, uptime, backups, and the security of the host itself. A compromised Headscale host offers an attacker the same enrolment power a compromised coordination server would, and tailnet lock is not in Headscale's feature list, so protect that host accordingly.

Do I still need a firewall on a VPS that is in my tailnet?

Yes. The public network interface still exists, and any service bound to 0.0.0.0 stays reachable from the internet whether or not Tailscale is running. Bind services to the tailnet address, keep a default deny policy on the public interface, and check your published container ports, because Docker inserts its own rules and can expose a port you believed was closed.