Skip to content

Multi-device access (Tailscale)

The goal: reach Pluma from your phone, tablet, or another laptop without exposing it to the open internet. Pluma embeds a Tailscale node (tsnet) so it registers as its own tailnet device at https://<hostname>.<tailnet>.ts.net/ with magic-cert HTTPS.

No port forwarding, no reverse proxy, no cert renewal. One sign-in on first enable, then it just works.

Prerequisites

  • A Tailscale account (free for personal use up to 100 devices).
  • The Tailscale app installed + signed in on every device you want to reach Pluma from.

You don't need tailscaled running on the Pluma host. Pluma's tsnet is a separate embedded node — it shares no state with a host-level tailscaled.

Enable

Settings → Privacy → Tailnet (Tailscale).

  1. Pick a hostname (default pluma). Becomes the leftmost label in the magic-cert URL.
  2. Click Enable Tailscale.
  3. The panel transitions through starting → needs_auth. A Sign in to Tailscale button appears.
  4. Click it. Sign in to Tailscale in the popup. Approve the device.
  5. The panel transitions to running. Pluma's URL appears: https://<hostname>.<tailnet>.ts.net.

State persists under <datadir>/tsnet/. Subsequent boots reattach silently — no re-auth needed.

First passkey on the tailnet URL

The loopback URL (http://localhost:8787) and the tailnet URL are different origins. Pluma's auth gate uses per-origin grace: hitting the tailnet URL for the first time, you'll see the Pair prompt to enrol a passkey for that origin.

The RPID collapses to the tailnet parent on *.ts.net hosts. So a passkey enrolled at pluma.alice.ts.net works on every tailnet subdomain at *.alice.ts.net. Enrol once per device + tailnet pair.

See Passkeys for the full enrolment flow.

Disable

Settings → Privacy → Disable Tailscale. Wipes the local state under <datadir>/tsnet/. The device row in the Tailscale admin console stays (tsnet has no API to self-deregister) — remove it manually from https://login.tailscale.com/admin/machines if you care.

Things to know

  • Hostname is fixed at first enable. To rename: disable, re-enable with the new hostname.
  • The tsnet listener bypasses allowed_hosts. Tailnet membership is itself an auth gate; making users mirror their tailnet topology into the allowlist would be redundant. Restrict tailnet access via Tailscale ACLs if needed.
  • Magic-cert can take a minute on first auth. Tailscale's cert backend provisions on demand; the URL might show a TLS warning for ~30 seconds, then resolve cleanly.
  • No DNS overrides. Pluma uses your normal Tailscale DNS settings; if you've got MagicDNS on, the FQDN just works on every tailnet peer.

Why not Tailscale Serve / Cloudflared / ngrok

You can run Pluma behind any of those. They're tracked as future plugin axes (smelt-aia). The embedded tsnet is the recommended path because:

  • One config (the hostname).
  • No external process to keep alive.
  • No port forwarding.
  • The auth gate (Tailscale ACLs + Pluma's passkeys) is already cohesive.

If you do front Pluma with a reverse proxy, set trusted_proxies in config.toml so the host allowlist sees the real client IP. See config.toml → trusted_proxies.