Tailscale - ACL file
Structure
The policy file uses HuJSON format (JSON with comments) and includes several key sections:
1. Groups
Define groups of users for easier access management:
{
"groups": {
"group:devops": [
"alice@example.com",
"bob@example.com"
],
"group:developers": [
"charlie@example.com",
"diana@example.com"
]
}
}2. Tag Owners
Define which users or groups can assign specific tags to devices. Tags are used to identify and group connectors:
{
"tagOwners": {
"tag:terraform": [], // Only OAuth clients can create
"tag:k8s": ["tag:terraform"], // Only terraform-tagged devices can create
"tag:production-eks-example-com": ["tag:terraform"],
"tag:staging-eks-example-com": ["tag:terraform"]
}
}3. Auto Approvers
Automatically approve route advertisements from tagged devices. This eliminates manual approval for trusted connectors:
{
"autoApprovers": {
"routes": {
"10.0.0.0/8": ["tag:k8s"], // All RFC1918 10.x networks
"172.16.0.0/12": ["tag:k8s"], // All RFC1918 172.16-31.x networks
"192.168.0.0/16": ["tag:k8s"] // All RFC1918 192.168.x networks
}
}
}4. Grants
Define access permissions using the grants system. Grants are more flexible than traditional ACLs:
{
"grants": [
{
"src": ["group:devops"], // Source: who can access
"dst": ["*"], // Destination: all devices
"ip": ["*"] // All ports
},
{
"src": ["group:developers"],
"dst": ["tag:staging-eks-example-com"],
"ip": ["*"]
}
]
}5. App Connectors
Configure app connectors to expose specific services (like Kubernetes API servers or internal applications) through Tailscale:
{
"nodeAttrs": [
{
"target": ["*"],
"app": {
"tailscale.com/app-connectors": [
{
"name": "eks-production",
"connectors": ["tag:production-eks-example-com"],
"domains": [
"ABCD1234.gr7.eu-west-1.eks.amazonaws.com", // EKS API endpoint. Note: the domain needs to be in capitals
"grafana.example.com",
"prometheus.example.com"
]
}
]
}
}
]
}Example Complete Policy File
Here’s a simplified example for a customer setup:
{
"groups": {
"group:admins": [
"admin@example.com"
],
"group:developers": [
"dev1@example.com",
"dev2@example.com"
]
},
"tagOwners": {
"tag:terraform": [],
"tag:k8s": ["tag:terraform"],
"tag:production-eks-example-com": ["tag:terraform"],
"tag:staging-eks-example-com": ["tag:terraform"]
},
"autoApprovers": {
"routes": {
"10.0.0.0/8": ["tag:k8s"],
"192.168.0.0/16": ["tag:k8s"]
}
},
"grants": [
{
"src": ["group:admins"],
"dst": ["*"],
"ip": ["*"]
},
{
"src": ["group:developers"],
"dst": ["tag:staging-eks-example-com"],
"ip": ["*"]
}
],
"nodeAttrs": [
{
"target": ["*"],
"app": {
"tailscale.com/app-connectors": [
{
"name": "eks-production",
"connectors": ["tag:production-eks-example-com"],
"domains": [
"ABC123.gr7.eu-west-1.eks.amazonaws.com"
]
},
{
"name": "eks-staging",
"connectors": ["tag:staging-eks-example-com"],
"domains": [
"DEF456.gr7.eu-west-1.eks.amazonaws.com"
]
}
]
}
}
]
}Setting Up ACL Management with GitHub Actions
- Add the policy file as
tailscale/policy.hujsonin the repository - Configure GitHub Actions with the GitHub OAuth Client credentials:
- Add
TAILSCALE_OAUTH_CLIENT_IDas a GitHub secret - Add
TAILSCALE_OAUTH_CLIENT_SECRETas a GitHub secret
- Add
- Create a workflow to automatically push policy changes to Tailscale on commits
- Disable manual ACL editing in the Tailscale admin console to enforce GitOps practices: https://login.tailscale.com/admin/settings/policy-file-management and set the External reference to the URL of your repository: https://github.com/skyscrapers/
/blob/master/tailscale/policy.hujson
Example GitHub Actions workflow:
name: Update Tailscale ACL
on:
push:
branches: ["master", "main"]
paths:
- 'tailscale/policy.hujson'
pull_request:
branches: ["master", "main"]
paths:
- 'tailscale/policy.hujson'
jobs:
acls:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Deploy ACL
if: github.event_name == 'push'
id: deploy-acl
uses: tailscale/gitops-acl-action@v1
with:
oauth-client-id: ${{ secrets.TS_OAUTH_ID }}
oauth-secret: ${{ secrets.TS_OAUTH_SECRET}}
tailnet: ${{ secrets.TS_TAILNET }}
action: apply
policy-file: tailscale/policy.hujson
- name: Test ACL
if: github.event_name == 'pull_request'
id: test-acl
uses: tailscale/gitops-acl-action@v1
with:
oauth-client-id: ${{ secrets.TS_OAUTH_ID }}
oauth-secret: ${{ secrets.TS_OAUTH_SECRET}}
tailnet: ${{ secrets.TS_TAILNET }}
action: test
policy-file: tailscale/policy.hujsonImportant Notes
- Tag Naming: Tags should follow the pattern
tag:<cluster-name>for consistency - Route Approval: Auto-approvers eliminate the need for manual route approval in the Tailscale admin console
- App Connectors: Required for accessing Kubernetes API servers and internal services through Tailscale
- Testing: Always test ACL changes in a non-production environment first
- Version Control: Keep your ACL policy file in version control for audit history and easy rollback
Last updated on