feat: Tailscale ACL tightening — replace *:*:* with scoped grants #78
Labels
No labels
domain:backend
domain:devops
domain:frontend
status:approved
status:in-progress
status:needs-fix
status:qa
type:bug
type:devops
type:feature
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
forgejo_admin/pal-e-platform#78
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Lineage
plan-pal-e-platform→ Phase 8 (Network Security Hardening) → Phase 8b (Tailscale ACL Tightening)Repo
forgejo_admin/pal-e-platformUser Story
As a platform operator
I want Tailscale ACL grants scoped by role instead of
*:*:*So that a compromised tailnet device cannot reach every service on every port
Context
Phase 8a deployed 15 NetworkPolicies across 15 namespaces (pod-level isolation). Phase 8b is the next layer — device-to-device access control on the tailnet.
The current
tailscale_acl.thisresource (lines 39-74 ofterraform/main.tf) has a single grantsrc=* dst=* ip=*that allows any device to reach any other on any port. The SSH, nodeAttrs, and tagOwners blocks are already properly scoped — only thegrantsblock needs changing.Design target:
autogroup:admin→*:*(full access — SSH, kubectl, all web UIs)tag:k8s→ scoped to what the k8s node actually needs outbound on the tailnet (funnel capability is already in nodeAttrs)group:developerswith limited access (Forgejo + Woodpecker only)Safety net: Tailscale admin console has full ACL history — instant revert if the new ACL breaks anything.
7 funneled services in this repo: Grafana, Alertmanager, Forgejo, Woodpecker, Harbor, MinIO console, Keycloak. 1 tailnet-only: MinIO S3 API. ~6 more from pal-e-deployments.
File Targets
Files the agent should modify:
terraform/main.tf— update thegrantsblock intailscale_acl.thisresource (lines 41-47)Files the agent should NOT touch:
terraform/main.tfSSH block (lines 49-56) — already scopedterraform/main.tfnodeAttrs block (lines 58-63) — already scopedterraform/main.tftagOwners block (lines 65-67) — already scopedAcceptance Criteria
tailscale_aclno longer grants*:*:*autogroup:adminretains full*:*access (SSH, kubectl, all UIs)tag:k8sgets only the access it needs (funnel ports, coordination)tofu plan -lock=falseshows only the ACL change, no other drifttofu fmtandtofu validatepass cleanTest Expectations
tofu validatepassestofu plan -lock=falseshows expected ACL diff (grants block only)cd terraform && tofu plan -lock=false -var-file=k3s.tfvarsConstraints
grantsblock — do NOT touch SSH, nodeAttrs, or tagOwnerstofu fmtbefore committingtofu plan -lock=false— do NOT run applytofu planoutput in the PR descriptionmain.tfChecklist
Closes #Ntofu planoutput included in PRRelated
plan-pal-e-platform— Platform Hardening planphase-pal-e-platform-network-security— Phase 8 parentdoc-network-traffic-map— traffic flows reference