Tailtab README

The project's README from github.com/Stocist/Tailtab. As one markdown file: README.md.

Tailtab

Tailtab

A Tailscale node for each browser profile. Different profiles can sit on completely different tailnets at the same time.

CI License: BSD-3-Clause Go 1.27 tailscale.com v1.102.3 Platform: macOS · Edge · Zen Status: experimental

Tailtab popup, dark theme    Tailtab popup, light theme

What it does

How it works

flowchart LR
  B[Browser profile] -->|proxy rules| E[Tailtab extension]
  E <-->|native messaging| H[tailtab host<br/>Go + tsnet]
  E -->|127.0.0.1:port<br/>with credential| P[Loopback proxy<br/>HTTP + SOCKS5]
  P --> H
  H -->|WireGuard| T((Tailnet))

The basic setup is pretty simple.

The extension talks to a small Go host through native messaging. That host embeds tsnet, which means the host itself becomes the Tailscale node. It then exposes an authenticated HTTP/SOCKS5 proxy over loopback for the browser to use.

Chromium gets pointed at the proxy through a PAC script. Firefox decides whether to proxy each request itself. Both browsers use the same routing rules, with a shared fixture there to make sure the implementations do not slowly drift apart.

More detail is in docs/architecture.md.

Install

One command installs the host under your home directory and registers it with the browsers on the machine. No root or admin.

macOS / Linux:

curl -fsSL https://raw.githubusercontent.com/Stocist/Tailtab/main/scripts/install.sh | sh

Windows (PowerShell):

irm https://raw.githubusercontent.com/Stocist/Tailtab/main/scripts/install.ps1 | iex

When upgrading on Windows, close all browsers that use Tailtab before rerunning the installer. It refuses to replace a running host rather than stopping your browser connections.

Both download the latest release, verify it against SHA256SUMS, and run tailtab install. Set TAILTAB_VERSION to pin a release. Then add the extension:

The host binary is not notarised or code-signed yet, so macOS may need a right-click Open the first time and Windows may show a SmartScreen warning. Linux and Windows hosts pass the same end-to-end smoke test in CI as macOS but have had less real use; reports welcome.

Chrome Flatpak on Linux needs both artifacts inside its sandbox. Use the opt-in Chrome Flatpak installation, not the native-browser one-liner above.

Build from source

You will need Go 1.27, Node 22, and either Microsoft Edge or Zen.

git clone https://github.com/Stocist/Tailtab.git && cd Tailtab
./scripts/build.sh
bin/tailtab install

build.sh builds the host binary and an unpacked extension for each browser.

install then writes the native-messaging manifests for Edge, Zen/Firefox and Chrome, pointing them at that binary.

If you move the repo afterwards, just run install again. bin/tailtab uninstall removes the files Tailtab added.

Load the extension in Edge
  1. Open edge://extensions.
  2. Turn on Developer mode.
  3. Click Load unpacked and select extension/dist/chromium/.
  4. Check that the extension ID is kejfineblfbjfolkgjkancapnpknomod. This is fixed by the key in the manifest.
  5. After rebuilding Tailtab, reload the extension from this page.

Edge likes to keep the old background worker around even after the browser restarts, so the popup shows a warning if the extension and host are out of sync.

Load the extension in Zen / Firefox
  1. Download tailtab-<version>.xpi from the latest release. It is signed by Mozilla for self-distribution, so it installs permanently.
  2. Open it in the browser (drag it onto a window, or File > Open File…) and accept the install prompt.
  3. If you want Tailtab in private windows, enable Run in Private Windows from about:addons.

For development, load extension/dist/firefox/manifest.json from about:debugging#/runtime/this-firefox with Load Temporary Add-on… instead. Firefox removes temporary extensions when the browser closes, so that one has to be loaded again after a restart.

Once that is done, open the popup and hit Connect.

Tailtab opens the normal Tailscale login page in a tab. Approve the node and the popup should switch to Connected, showing the tailnet, device name and assigned address.

From there:

http://wiki/ can reach a machine called wiki on your tailnet.

https://github.com still goes straight to the internet.

That is basically the idea.

A closer look

Account switcher   Exit node selected   Machine search

Security

There is a more complete write-up in docs/security.md, but the important bits are:

Status

Tailtab is still experimental, but it is at the point where I can actually daily drive it on macOS with Edge and Zen.

It is not in an extension store yet, so setup is still manual.

Chrome and Firefox should work with the existing implementations, but I have not properly tested them yet.

Chrome Flatpak on Bazzite has a contributor-tested setup; this is not comprehensive browser coverage.

Known limitations and security gaps are tracked in docs/security.md#known-gaps.

Development

./scripts/test.sh        # gofmt-clean Go, vet, tests, and the extension suite
./scripts/build.sh       # bin/tailtab + extension/dist/{chromium,firefox}

The extension tests load background.js and popup.js as-is into a stubbed browser environment with fake timers.

That lets the test suite cover things like proxy setup and teardown, reconnect backoff, split-tunnel routing and popup behaviour without needing to launch a real browser every time.

The host can also be driven manually. Native messaging is just 4-byte little-endian length-prefixed JSON over stdin/stdout.

Acknowledgements

The original idea and native-messaging structure are based on Tailscale's own ts-browser-ext experiment. Two files adapt code from it under the same BSD-3-Clause licence.

tailchrome takes a similar approach and was also useful to look through while building this.

Thanks to @Hajfi for reporting the Chrome Flatpak installation gap and documenting a working sandbox-compatible layout in #2.

License

BSD-3-Clause.

Tailtab (Stocist/Tailtab)

Searching Database…

What is this?Tailtab gives every browser profile its own Tailscale node, so different profiles (or even different Tailscale/Headscale accounts) can sit on completely separate tailnets at the same time, while the rest of the machine is untouched.
Is this a browser extension or a standalone app?It is a pair: a small browser extension for Chrome, Edge, Firefox or Zen, plus a tiny Go background host installed on your machine. The host embeds Tailscale's tsnet library and becomes the actual tailnet node; the extension just talks to it over native messaging.
How do I get it running?Run the one-line installer (shell script on macOS/Linux, PowerShell on Windows) which downloads the host, verifies it against SHA256SUMS and registers native-messaging manifests with no root or admin needed, then load the matching extension: the signed .xpi for Firefox/Zen, or the unpacked zip for Chrome/Edge via developer mode.
Do I need anything besides the installer, like a Tailscale account?You need a Tailscale account (or a Headscale/other coordination server you point it at) to log in from the popup; building from source instead of using release binaries additionally requires Go 1.27 and Node 22.
Any install pitfalls or rough edges?The host binary isn't notarised or code-signed yet, so macOS needs a right-click Open the first time and Windows shows a SmartScreen warning; Chrome and Firefox haven't been as thoroughly tested as macOS/Edge, and Chrome Flatpak on Linux needs a separate sandbox-aware install path.
Does any of this data leave my machine in ways I can't control?Yes, one piece: the embedded tsnet library uploads its own logs to Tailscale and there's currently no supported way to turn that off.
What does split tunneling by default actually mean here?Only traffic bound for your tailnet (MagicDNS names, .ts.net, the tailnet's CGNAT ranges, and routes peers announce) goes through Tailtab; every other request from that browser profile leaves the machine normally, so regular browsing never depends on Tailtab being connected.
How do per-profile exit nodes work?You pick an exit node for one browser profile from the popup, and that profile's public web traffic routes through it while private ranges stay local. If the exit node disappears, Tailtab blocks the traffic instead of letting it leak out directly.
Why not just use the regular Tailscale app?The standard Tailscale client gives the whole machine one identity. Tailtab lets each browser profile carry its own node key, state and tailnet, so you can run several accounts or tailnets side by side without touching anything else on the computer.
Can I use my own control server instead of Tailscale's?Yes, the settings page lets you point Tailtab at a Headscale (or any compatible) coordination server, and the next login will use it.
Creator
Stocist
Size
1.4 MB
Stars
216
Age
1mo
Commits · 90 Days