feat: Tailscale ACL tightening — replace *:*:* with scoped grants #78

Closed
opened 2026-03-15 04:30:07 +00:00 by forgejo_admin · 0 comments

Lineage

plan-pal-e-platform → Phase 8 (Network Security Hardening) → Phase 8b (Tailscale ACL Tightening)

Repo

forgejo_admin/pal-e-platform

User 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.this resource (lines 39-74 of terraform/main.tf) has a single grant src=* dst=* ip=* that allows any device to reach any other on any port. The SSH, nodeAttrs, and tagOwners blocks are already properly scoped — only the grants block 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)
  • Future stub: group:developers with 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 the grants block in tailscale_acl.this resource (lines 41-47)

Files the agent should NOT touch:

  • terraform/main.tf SSH block (lines 49-56) — already scoped
  • terraform/main.tf nodeAttrs block (lines 58-63) — already scoped
  • terraform/main.tf tagOwners block (lines 65-67) — already scoped
  • Any other Terraform resources — out of scope

Acceptance Criteria

  • tailscale_acl no longer grants *:*:*
  • autogroup:admin retains full *:* access (SSH, kubectl, all UIs)
  • tag:k8s gets only the access it needs (funnel ports, coordination)
  • tofu plan -lock=false shows only the ACL change, no other drift
  • tofu fmt and tofu validate pass clean

Test Expectations

  • tofu validate passes
  • tofu plan -lock=false shows expected ACL diff (grants block only)
  • No other resources affected in plan output
  • Run command: cd terraform && tofu plan -lock=false -var-file=k3s.tfvars

Constraints

  • Only modify the grants block — do NOT touch SSH, nodeAttrs, or tagOwners
  • Run tofu fmt before committing
  • Run tofu plan -lock=false — do NOT run apply
  • Include tofu plan output in the PR description
  • Follow existing HCL style in main.tf

Checklist

  • PR opened with Closes #N
  • tofu plan output included in PR
  • No unrelated changes
  • plan-pal-e-platform — Platform Hardening plan
  • phase-pal-e-platform-network-security — Phase 8 parent
  • doc-network-traffic-map — traffic flows reference
### Lineage `plan-pal-e-platform` → Phase 8 (Network Security Hardening) → Phase 8b (Tailscale ACL Tightening) ### Repo `forgejo_admin/pal-e-platform` ### User 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.this` resource (lines 39-74 of `terraform/main.tf`) has a single grant `src=* dst=* ip=*` that allows any device to reach any other on any port. The SSH, nodeAttrs, and tagOwners blocks are already properly scoped — only the `grants` block 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) - Future stub: `group:developers` with 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 the `grants` block in `tailscale_acl.this` resource (lines 41-47) Files the agent should NOT touch: - `terraform/main.tf` SSH block (lines 49-56) — already scoped - `terraform/main.tf` nodeAttrs block (lines 58-63) — already scoped - `terraform/main.tf` tagOwners block (lines 65-67) — already scoped - Any other Terraform resources — out of scope ### Acceptance Criteria - [ ] `tailscale_acl` no longer grants `*:*:*` - [ ] `autogroup:admin` retains full `*:*` access (SSH, kubectl, all UIs) - [ ] `tag:k8s` gets only the access it needs (funnel ports, coordination) - [ ] `tofu plan -lock=false` shows only the ACL change, no other drift - [ ] `tofu fmt` and `tofu validate` pass clean ### Test Expectations - [ ] `tofu validate` passes - [ ] `tofu plan -lock=false` shows expected ACL diff (grants block only) - [ ] No other resources affected in plan output - Run command: `cd terraform && tofu plan -lock=false -var-file=k3s.tfvars` ### Constraints - Only modify the `grants` block — do NOT touch SSH, nodeAttrs, or tagOwners - Run `tofu fmt` before committing - Run `tofu plan -lock=false` — do NOT run apply - Include `tofu plan` output in the PR description - Follow existing HCL style in `main.tf` ### Checklist - [ ] PR opened with `Closes #N` - [ ] `tofu plan` output included in PR - [ ] No unrelated changes ### Related - `plan-pal-e-platform` — Platform Hardening plan - `phase-pal-e-platform-network-security` — Phase 8 parent - `doc-network-traffic-map` — traffic flows reference
forgejo_admin 2026-03-15 04:37:10 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
forgejo_admin/pal-e-platform#78
No description provided.