mrkeyoor.com_
Tue 01 Sept 17:45 UTC
Open Source7 min read

Tailcat Packs Tailscale's Data Plane Into a 50-Byte Token

Tailcat creates encrypted, NAT-traversing links without a Tailscale account. Its tiny connection token also makes the missing access-control layer impossible to ignore.

A typical Tailcat connection token is around 50 bytes. Inside it are a server's WireGuard public key and enough relay information for another machine to find it, which lets two peers establish an encrypted link without joining a Tailscale network. That unusually compact exchange helped Tailcat's Hacker News submission reach 467 points and 90 comments within hours. The score tracks developer curiosity alone. The source does explain the interest: Tailscale has separated much of its hard networking work from the account, device registry and policy system that usually coordinates it.

Tailcat describes itself as netcat rebuilt over Tailscale's data plane. One side starts a listener and prints a connection token. The other supplies that token to the client. Both sides first meet through a DERP relay, then Tailscale's magicsock transport tries UDP hole punching to establish a direct peer-to-peer path. WireGuard encrypts the traffic whether it remains relayed or goes direct.

For a developer trying to reach a service behind NAT, that removes a familiar pile of setup. The project documentation says Tailcat needs no Tailscale account, administrator privileges, routing-table changes or DNS configuration. It runs as a userspace process and exposes a Go library as well as a command-line program. The trade is equally direct: there is no managed identity directory or central access policy waiting behind the token. Users have to decide how the token is exchanged and who should be allowed to connect.

What the token replaces

A normal Tailscale deployment has a control plane and a data plane. The control plane knows which devices belong to a tailnet, distributes peer information and applies access rules. The data plane moves encrypted packets between peers. Tailcat keeps the packet-moving pieces and replaces control-plane coordination with an out-of-band token, according to the project's technical explanation.

The token, called a ConnBlob in the code, starts with tc and contains CBOR data encoded as base64. Its smallest documented form carries the server's Curve25519 public key and a numeric DERP region identifier. A longer, self-contained form can embed a custom relay's hostname and address details. The client therefore learns whom to authenticate and where to rendezvous from one string, without asking a central service for a network map.

That is the design connection to netcat. Traditional netcat can pipe standard input and output over a TCP or UDP socket, but the operator still needs a reachable address and port. Tailcat lets the listener sit behind NAT and gives the connecting peer a capability-like address. The repository's basic pipe example is only two commands: run tailcat on the server, then pipe data into tailcat TOKEN on the client.

tailcat
printf 'hello\n' | tailcat tcXXXXXXXXX

Installation currently assumes a recent Go toolchain or Nix. The documented Go command is go install github.com/tailscale/tailcat/cmd/tailcat@latest; the module declares Go 1.26.5. There are no platform routing changes because gVisor's userspace TCP/IP stack terminates connections inside the process.

More than a pipe between terminals

The netcat comparison understates the CLI's present scope. A listener can forward selected TCP ports to localhost with --serve=8080,8443, while the client names the desired port after the token. Linux and macOS users can also start a built-in SSH server with --serve=no-auth-ssh, or proxy port 22 to the machine's existing SSH service when conventional SSH authentication is wanted. These modes are documented in the Tailcat README.

The no-auth SSH option deserves careful reading. An ephemeral server creates a fresh key in memory, prints a new token and discards the key when the process exits. Anyone who receives that token can try to connect for the life of that run, as the key-management notes make clear. This can be convenient for a short support session or a disposable development machine, but the token distribution becomes part of the security boundary. Posting it in a public issue or a logged chat would defeat the assumption that only the intended peer knows the address.

Saved server keys change the risk. They keep the same address across restarts, so every previous recipient can return whenever that key is used again. Tailcat offers an --allow option that restricts a saved server to named client public keys. Its DNS example also supports publishing stable tokens in TXT records, paired with a fixed DERP region so the same name continues to resolve after a restart. In that configuration, client-key allowlisting matters far more than obscurity of the DNS record.

This is where Tailcat stops resembling a miniature managed VPN. Tailscale accounts, device approval, ACLs, tags and revocation workflows are absent from the documented connection flow. A team can build an access model with saved client keys and its own token distribution, but Tailcat will not supply the employee offboarding or policy audit trail. That narrower boundary makes sense for one-off links and embedded applications. It needs deliberate supporting machinery when a connection becomes permanent.

Direct when possible, relayed when necessary

DERP gives Tailcat a dependable meeting place even when both peers are hidden behind restrictive networks. After the initial exchange, each side advertises possible UDP endpoints and attempts NAT traversal. If that succeeds, packets take the direct path. If it fails, DERP remains the encrypted fallback. Tailscale's connection-type documentation says the security property is the same for direct and DERP paths because both use WireGuard end to end; latency and throughput are the practical differences.

Tailcat's ping documentation says the command reports whether replies travel directly or through DERP, and --until-direct waits up to a timeout for a direct route. That distinction matters for large transfers or interactive services. Tailscale warns in its general documentation that relayed connections are usually slower, and Tailcat applies an additional warning to its public relay service: the free relays are rate limited, have no uptime commitment or throughput target, and access may be withdrawn.

Operators can remove that hosted dependency by running their own DERP server. A Tailcat token can embed the custom relay hostname, so clients do not have to contact Tailscale's relay-map endpoint. Self-hosting transfers availability, TLS certificate handling and capacity planning to the operator. It also leaves the main benefit intact: the peers can still attempt a direct path after using the relay to meet.

One documented rough edge concerns stable names. When a token is published in DNS, the project recommends fixing its DERP region during key generation. Automatic region selection can choose a different rendezvous point on a later start, while the old token still points clients elsewhere. The README links to an open issue to make clients more tolerant when the relay map changes. This is a small implementation detail with an outsized operational effect: a short token is only useful while both sides interpret its relay reference the same way.

The Go library may be the larger release

The CLI is an immediately legible demo, but the importable Go package opens a wider set of uses. A program can start a Tailcat server with a callback for incoming TCP ports, print the resulting token and handle connections without creating a TUN device. A client constructed with that token can dial a chosen TCP port lazily. That gives developers a way to add encrypted, NAT-traversing connectivity to a tool without requiring every user to install and enroll a system-wide VPN client.

The cost is dependency weight and change risk. Tailcat draws on Tailscale's networking stack, gVisor, WireGuard and the DERP protocol rather than implementing a toy tunnel. Its go.mod therefore pulls in a broad set of networking packages. The stability policy makes no promise that the Go API, CLI flags, output or wire format will remain compatible. A product that stores tokens or automates command output should pin a commit and treat upgrades as migrations, even though the current install example points at @latest.

The code is under the BSD 3-Clause license, which permits redistribution and modification while retaining the copyright and license notices. The repository says the tool began as derpcat in 2023, repeatedly fell out of sync inside a fork of Tailscale's main codebase, and was later refactored into a standalone Go module. Tailscale open sourced it at its August 2026 TailscaleUp conference. That history explains both the mature transport underneath and the explicit lack of interface stability around it.

Tailcat is most convincing today as a sharp component: an encrypted pipe, temporary port bridge or library primitive where participants already have a safe way to exchange keys. Its published stability limits provide the next evidence to watch: wire-format decisions, tagged releases, clearer relay service limits and fixes for persistent-token rendezvous will show whether developers can build durable systems on it. Until then, the 50-byte token is a clever replacement for coordination in small settings, while every missing control-plane function remains the operator's job.

We reviewed this

  1. usage — our honest review
  2. fresh — our honest review
  3. gvisor — our honest review

Sources

  1. tailscale/tailcat repository
  2. Hacker News: Tailcat
  3. Tailscale connection types
  4. Tailcat issue 7: handle changed DERP maps
  5. Tailcat BSD 3-Clause license