blumeops/docs/how-to/update-tailscale-acls.md
Erich Blume e311b36b3c Add Phase 4: how-to guides documentation (#95)
## Summary
- Create `docs/how-to/` directory with index and four how-to guides
- deploy-k8s-service: Quick reference for Kubernetes deployments via ArgoCD
- add-ansible-role: Adding new Ansible roles for indri services
- update-tailscale-acls: Modifying Tailscale ACL policies via Pulumi
- troubleshooting: Diagnosing and fixing common issues
- Update exploring-the-docs to include How-to section links
- Update README.md to mark Phase 4 as complete

## Deployment and Testing
- [x] Pre-commit hooks pass (including doc-links validator)
- [ ] Build and deploy to docs.ops.eblu.me to verify rendering

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Reviewed-on: https://forge.ops.eblu.me/eblume/blumeops/pulls/95
2026-02-03 20:17:24 -08:00

2 KiB

title tags
update-tailscale-acls
how-to
tailscale
pulumi

Update Tailscale ACLs

How to modify Tailscale access control policies for the tailnet.

Prerequisites

  • Pulumi CLI installed (brew install pulumi)
  • Access to 1Password blumeops vault (for OAuth credentials)

Edit the Policy

The ACL policy lives in pulumi/policy.hujson (HuJSON format with comments).

Common changes:

Add a new ACL rule

{
  "acls": [
    // ... existing rules ...
    {
      "action": "accept",
      "src": ["autogroup:admin"],
      "dst": ["tag:newservice:*"]
    }
  ]
}

Add a new tag

{
  "tagOwners": {
    // ... existing tags ...
    "tag:newservice": ["autogroup:admin"]
  }
}

Add a new group

{
  "groups": {
    // ... existing groups ...
    "group:newgroup": ["user1@example.com", "user2@example.com"]
  }
}

Preview and Apply

# Preview changes (always do this first)
mise run tailnet-preview

# Apply changes
mise run tailnet-up

# Skip confirmation prompt
mise run tailnet-up -- --yes

Verify

Check the Tailscale admin console at https://login.tailscale.com/ to confirm changes.

Common Patterns

Service-specific access

Grant access to a specific service port:

{
  "action": "accept",
  "src": ["group:users"],
  "dst": ["tag:homelab:8080"]
}

SSH access

{
  "ssh": [
    {
      "action": "check",
      "src": ["autogroup:admin"],
      "dst": ["tag:servers"],
      "users": ["autogroup:nonroot"]
    }
  ]
}

All ports for admins

{
  "action": "accept",
  "src": ["autogroup:admin"],
  "dst": ["*:*"]
}

Troubleshooting

"Credential expired" error: Re-authenticate Pulumi with Tailscale. The OAuth token may need refreshing.

Changes not taking effect: ACL changes are applied immediately. If a device isn't following new rules, try tailscale down && tailscale up on that device.