Codify Tailscale ACL with tag:homelab scaffolding - #7
Merged
Conversation
Brings the tailnet policy file under OpenTofu management. Keeps the existing default-allow stance and SSH/Funnel defaults intact while adding forward-looking structure that no-ops until devices wear the new tag: - `tagOwners` for `tag:homelab` (only autogroup:admin can apply it) - SSH rule `autogroup:member -> tag:homelab` for `nickv` and `root` Phase 2 (separate PR after gandalf advertises tag:homelab) will replace the `*:*` acls rule with restrictive admin/tag-scoped rules. Tightening in the same change as introducing tagging would leave the operator unable to reach gandalf via Tailscale. OAuth client `opentofu-homelab` needs the `acl` (read+write) scope — added in the Tailscale admin UI before this lands. Applied locally with `tofu import tailscale_acl.main acl` followed by in-place update: 0 added, 1 changed, 0 destroyed.
|
5 tasks
nickvigilante
added a commit
that referenced
this pull request
May 12, 2026
Phase 2 of the Tailscale ACL codification (Phase 1 was PR #7). Gandalf now wears `tag:homelab`, so the policy can drop the allow-all rule: - `autogroup:member -> tag:homelab:*`: your tailnet devices reach Jellyfin, Pi-hole, Uptime Kuma on gandalf - `tag:homelab -> tag:homelab:*`: future cluster nodes can talk to each other (k3s agent join, kubelet API) SSH and Funnel rules unchanged. The `*:*` allow-all rule is gone — a device that isn't a tailnet member and isn't tagged `tag:homelab` can't reach anything on the homelab side. Verified with `curl -v http://100.92.2.25/` from a tailnet macbook: Traefik returned the expected 404 (no IngressRoute matches a bare-IP Host), proving the Tailscale layer routed the connection through.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Brings the tailnet policy file under OpenTofu management. No functional behavior change in this PR.
What lands:
tailscale_acl.mainresource — imports the current ACL into Tofu state and re-serializes it viajsonencode. The comments and example scaffolding from the starter template go away; the actual rules are preserved verbatim.tagOwnersfortag:homelab— onlyautogroup:admincan apply the tag, so a random tailnet member can't spoof a homelab node.autogroup:member -> tag:homelabfornickvandroot— no-op today because no device wears the tag.Phase 2 (intentionally separate PR)
After this lands:
sudo tailscale up --advertise-tags=tag:homelab*:*allow-all rule with restrictive admin/tag-scoped rulesWhy split: doing both at once leaves the operator unable to reach gandalf if anything's off — the
*:*rule disappears before any device has the tag the new rules grant access to.OAuth scope dependency
The
opentofu-homelabOAuth client now needs theacl(read+write) scope (added in the admin UI before this PR was opened — the apply step would fail without it).Test plan
tofu import tailscale_acl.main aclbrings the existing ACL into statetofu planshows0 to add, 1 to change, 0 to destroy— change is the comments-to-JSON reserialization plus the two additive piecesacls,ssh, ornodeAttrsrule loses content in the difftofu applysucceedsacls,ssh,nodeAttrs,tagOwners)tofu planafter apply is a no-op