Give the Tailscale ACL step a working policy file #53

Merged
sulthan merged 2 commits from docs/tailscale-acl into main 2026-08-09 16:12:03 +07:00
Owner

Follow-up to #52, which merged before this landed. Docs only — no code, no compose changes.

DEPLOY.md §7 told the operator to "tag the two machines" and showed a bare acls fragment. Following it literally does not work and is actively harmful:

  • the fragment references tag:bookmark-api / tag:bookmark-browser without a tagOwners section, so the policy is rejected on save;
  • it never says how a tag gets onto a device (tailscale up --advertise-tags=..., which re-authenticates);
  • replacing the tailnet's default allow-all with only that one rule removes the operator's own SSH access to the browser machine.

Replaced with a complete, saveable policy file: tagOwners, the CDP rule, a second rule preserving own-device access including :22, and a tests block so a later edit that widens 9222 is rejected rather than silently applied.

Also records two things that were assumed rather than stated:

  • Why tagging is load-bearing. Tailscale has no deny, so restricting 9222 means removing the blanket accept and enumerating what remains. That is only expressible if the browser machine falls outside a selector that still covers your own devices — which is exactly what a tag does, since a tagged device has no user and stops matching autogroup:member / autogroup:self. Without that, the whole step reads as arbitrary ceremony.
  • Tagging replaces a device's user identity, so it suits a dedicated box and disrupts a daily driver. Both paths are now written down.

Finally, separates two checks the old text conflated: the existing curl runs on the home machine and proves only the bind, because node-local traffic is not filtered. Proving the ACL needs a third device, so that check is now its own step.

Verified: tailscale.com/docs/reference/syntax/policy-file and /docs/features/tags (validated Apr 2026 / Dec 2025) for tagOwners, autogroup:self semantics vs tagged devices, --advertise-tags re-auth and key-expiry behaviour. Markdown fences balanced.

Follow-up to #52, which merged before this landed. Docs only — no code, no compose changes. `DEPLOY.md` §7 told the operator to "tag the two machines" and showed a bare `acls` fragment. Following it literally does not work and is actively harmful: - the fragment references `tag:bookmark-api` / `tag:bookmark-browser` without a `tagOwners` section, so the policy is rejected on save; - it never says how a tag gets onto a device (`tailscale up --advertise-tags=...`, which re-authenticates); - replacing the tailnet's default allow-all with only that one rule **removes the operator's own SSH access to the browser machine**. Replaced with a complete, saveable policy file: `tagOwners`, the CDP rule, a second rule preserving own-device access including `:22`, and a `tests` block so a later edit that widens 9222 is rejected rather than silently applied. Also records two things that were assumed rather than stated: - **Why tagging is load-bearing.** Tailscale has no `deny`, so restricting 9222 means removing the blanket accept and enumerating what remains. That is only expressible if the browser machine falls outside a selector that still covers your own devices — which is exactly what a tag does, since a tagged device has no user and stops matching `autogroup:member` / `autogroup:self`. Without that, the whole step reads as arbitrary ceremony. - **Tagging replaces a device's user identity**, so it suits a dedicated box and disrupts a daily driver. Both paths are now written down. Finally, separates two checks the old text conflated: the existing `curl` runs on the home machine and proves only the **bind**, because node-local traffic is not filtered. Proving the **ACL** needs a third device, so that check is now its own step. Verified: `tailscale.com/docs/reference/syntax/policy-file` and `/docs/features/tags` (validated Apr 2026 / Dec 2025) for `tagOwners`, `autogroup:self` semantics vs tagged devices, `--advertise-tags` re-auth and key-expiry behaviour. Markdown fences balanced.
sulthan added 1 commit 2026-08-09 16:01:29 +07:00
The DEPLOY §7 snippet was a bare `acls` fragment: it named tags without
declaring tagOwners, without saying how tags get applied, and without the rule
that keeps the operator's own SSH access once the blanket accept is gone.
Following it literally locks you out of the browser machine.

Also records why tagging is load-bearing rather than stylistic - Tailscale has
no deny, so excluding CDP from a selector that still covers your own devices
requires the destination to fall outside autogroup:member/self, which is
exactly what a tag does - and separates the bind proof from the ACL proof,
which the old text conflated.
sulthan added 1 commit 2026-08-09 16:05:17 +07:00
The console ships a grants-based default policy, so an acls example forces the
operator to translate before they can use it - and the two differ in exactly
the place that matters: grants carry ports in `ip` (`tcp:9222`) rather than
suffixed onto `dst`.

Adds the three things dropping the blanket grant silently takes away: an ssh
block, since tagged devices leave `autogroup:self` and Tailscale SSH stops
resolving them; a commented `autogroup:internet` grant for exit-node users;
and `tcp:22` to the browser machine, without which tagging locks you out.
sulthan merged commit 8081a0a5d8 into main 2026-08-09 16:12:03 +07:00
Sign in to join this conversation.