ACL syntax
Tailscale access control rules are expressed as a single "human JSON" (HuJSON) tailnet policy file. HuJSON is a superset of JSON that allows comments, making the tailnet policy file easy to maintain while staying human readable.
The tailnet policy file has several top-level sections relating to ACLs, which we explore in detail below:
acls
, the access rules themselves.groups
, collections of users, to avoid repeating yourself in access rules.hosts
, human readable shorthands for IP addresses.postures
, assertions based on device posture attributes.tagOwners
, to define which users can assign tags to a device.autoApprovers
, to define which users can advertise routes or exit nodes without further approval.ssh
, to define which users can establish a Tailscale SSH connection on which devices, and as which SSH users.nodeAttrs
, to define which devices can use certain features.tests
, which let you check the behavior of ACLs and avoid accidentally breaking an important permission.sshTests
, which let you check the behavior of Tailscale SSH access rules.
The tailnet policy file also contains network-wide policy settings unrelated to access control: derpMap
, disableIPv4
, and randomizeClientPort
.
Access rules (acls
)
The acls
section of the tailnet policy file is a list of access rules for your network. Each rule is a HuJSON object that grants access from a set of sources to a set of destinations.
Access rules can make use of groups to grant access to many users at once, and make use of tags to assign role accounts to nodes. Putting these together, you can build powerful role-based access control (RBAC) policies.
All rules eventually boil down to allowing traffic from a particular source IP address to a destination IP address and port. While you can write rules that reference IP addresses directly, it's more common to use higher-level specifiers like users, groups, and tags, which Tailscale automatically translates to the right low-level rules.
Each access rule looks like this:
{
"action": "accept",
"src": [ list-of-sources... ],
"proto": "protocol", // optional
"dst": [ list-of-destinations... ],
}
Previously we used users
and ports
, instead of src
and dst
, respectively. While both sets of terms are currently supported, we are using src
and
dst
going forward.
action
Tailscale access rules are default deny, so the only possible action
is accept
, to allow traffic that would otherwise be denied.
src
The src
field specifies a list of sources to which the rule applies. Each element in the list can be one of the following:
Type | Example | Meaning |
---|---|---|
Any | * | No restriction on the source |
User | shreya@example.com | All devices currently signed in as the given user |
Group | group:example | Same as listing every user in the group explicitly |
Tailscale IP | 100.101.102.103 | Only the device that owns the given Tailscale IP. IPv6 addresses must follow the format [1:2:3::4]:80 . |
Subnet CIDR Range | 192.168.1.0/24 | Any IP within the given subnet |
Host | my-host | Looks up the Tailscale IP or CIDR in the hosts section |
Tag | tag:production | All devices currently tagged with the given tag |
Autogroup | autogroup:member | Devices of users, destinations, or usernames with the same properties or roles |
An optional srcPosture
field can be used to further restrict src
devices to the ones matching a set of device posture conditions.
proto
The proto
field is optional, and specifies the protocol to which the rule applies. (If no protocol is specified, then the access rule applies to all TCP and UDP traffic.)
A proto
field can only be included in an access rule for Tailscale version v1.18.2 or later. Older clients will fail closed, blocking traffic for access rules with protocols, unless it is otherwise allowed.
If traffic is allowed for a given pair of IPs, then ICMP will also be allowed.
proto
can be specified as either an IANA IP protocol number 1-255 (for example, "16"
) or one of the following named aliases (for example, "sctp"
):
Protocol | proto | IANA protocol number |
---|---|---|
Internet Group Management (IGMP) | igmp | 2 |
IPv4 encapsulation | ipv4 , ip-in-ip | 4 |
Transmission Control (TCP) | tcp | 6 |
Exterior Gateway Protocol (EGP) | egp | 8 |
Any private interior gateway | igp | 9 |
User Datagram (UDP) | udp | 17 |
Generic Routing Encapsulation (GRE) | gre | 47 |
Encap Security Payload (ESP) | esp | 50 |
Authentication Header (AH) | ah | 51 |
Stream Control Transmission Protocol (SCTP) | sctp | 132 |
Only TCP, UDP, and SCTP traffic support specifying ports. For all other protocols, the port specified needs to be *
.
dst
The dst
field specifies a list of destination devices and ports to which the rule applies. Each element in the list is of the form host:ports
. host
is one of the following:
Type | Example | Meaning |
---|---|---|
Any | * | No restriction on the destination |
User | shreya@example.com | Any device currently signed in as the given user |
Group | group:example | Same as listing every user in the group explicitly |
Tailscale IP | 100.101.102.103 | Only the device that owns the given Tailscale IP |
Hosts | my-host | Looks up the Tailscale IP in the hosts section |
Subnet CIDR Range | 192.168.1.0/24 | Any IP within the given subnet |
Tags | tag:production | Any device currently tagged with the given tag |
Internet access via an exit node | autogroup:internet | Access to the internet through exit nodes |
Own devices | autogroup:self | Access to devices where the same user is authenticated on both the src and the dst . This does not include devices the user has ACL tags. |
Tailnet devices | autogroup:member | Access to devices on the tailnet where the user is a direct member (not a shared user) of the tailnet |
Admin devices | autogroup:admin | Access to devices where the user is an Admin |
Network admin devices | autogroup:network-admin | Access to devices where the user is a Network admin |
IT admin devices | autogroup:it-admin | Access to devices where the user is an IT admin |
Billing admin devices | autogroup:billing-admin | Access to devices where the user is a Billing admin |
Auditor devices | autogroup:auditor | Access to devices where the user is an Auditor |
Owner devices | autogroup:owner | Access to devices where the user is the tailnet Owner |
ports
is one of the following:
Type | Example |
---|---|
Any | * |
Single | 22 |
Multiple | 80,443 |
Range | 1000-2000 |
Subnet routers and exit nodes
ACLs can only allow connections, not reject them. ACLs don't limit discovery of routes. So, you can restrict access to a node separately from access to a subnet that node routes to, if it's a subnet router; or public IP, if it's an exit node.
To restrict access to a subnet, ensure that no ACL allows access to those routes. You can enforce this with a test, which will fail if any rule accidentally allows access, like so:
"tests": [
{
"src": "not-allowed@example.com",
"accept": ["100.101.102.103:22"], // allow access to the tailscale IP
"deny": ["192.168.0.7:22"], // does not allow access to the subnet
}
],
To restrict access to all exit nodes, only grant access to autogroup:internet
to those who you wish to use exit nodes. You can enforce this with a test, which will fail if any rule accidentally allows access to a public IP, like so:
"tests": [
{
"src": "not-allowed@example.com",
"accept": ["100.101.102.103:22"], // allow access to the tailscale IP
"deny": ["8.8.8.8:22"], // does not allow access to a public IP
}
],
Right now, there is no way to restrict use of specific exit nodes using ACLs. Subscribe to this GitHub issue for updates.
Taildrop precedence
Taildrop permits you to share files between devices that you are logged in to, even if ACLs are used to restrict access to the devices.
Referencing users
Users can be specified in both the source (src
) and destination (dst
) fields of an access rule. Users must be referenced using the full email address they use to sign into Tailscale.
If you sign into your network with GitHub, use the form username@github
. For example, the GitHub user alice
should be written as alice@github
.
If you've invited a user to your Tailscale network or shared a device with someone outside your Tailscale network, you can use their Tailscale login email in ACLs to further restrict what they can access on the shared device.
Referencing multiple users
Access rules for sets of users can be defined using groups. This lets you define role-based access controls, so that users in different roles have different access rules.
Groups in ACLs can be:
- Autogroups, to reference all entities with the same property
- Defined in the
groups
section of the tailnet policy file, as a specific list of users - Provisioned in the identity provider and synced through user & group provisioning
Autogroups
An autogroup is a special group that automatically includes users, destinations, or usernames with the same properties, which you can then use in access rules.
Where allowed | Autogroup | Meaning | Availability by plan |
---|---|---|---|
As a dst | autogroup:internet | Used to allow access for any user through any exit node in your tailnet. You cannot restrict access to only some exit nodes. | Available on all plans |
autogroup:self | Used to allow access for any user that is authenticated as the same user as the source. Does not apply to tags. | ||
As a src or dst , tagOwner , or autoApprover | autogroup:owner | Used to allow access for the tailnet Owner. | Available on all plans |
autogroup:admin | Used to allow access for any user who has the role of Admin. | ||
autogroup:member | Used to allow access for any user who is a direct member (including all invited users) of the tailnet. Users from shared nodes are not included. | ||
autogroup:tagged | Used to allow access for any node which is tagged. | ||
autogroup:auditor | Used to allow access for any user who has the role of Auditor. | Available on the Personal, Premium, and Enterprise plans | |
autogroup:billing-admin | Used to allow access for any user who has the role of Billing admin. | ||
autogroup:it-admin | Used to allow access for any user who has the role of IT admin. | ||
autogroup:network-admin | Used to allow access for any user who has the role of Network admin. | ||
user:*@<domain> | Used to allow access for any user whose login is in the specified domain and who is a direct member (including all invited users) of the tailnet. Users from shared nodes are not included. More details. | Available on the Starter, Premium, and Enterprise plans | |
As a src | autogroup:shared | Used to allow access for any user who accepted a sharing invitation to your network. This lets you write rules without knowing sharee email addresses in advance. | Available on all plans |
As an SSH user | autogroup:nonroot | Used to allow Tailscale SSH access to any user that is not root . | Available on the Personal, Premium, and Enterprise plans |
localpart:*@<domain> | Used to allow Tailscale SSH access to the user whose name matches the local-part of the user's login. More details. | Available on the Premium and Enterprise plans |
autogroup:self
only applies to user-owned nodes, not also tagged nodes. You cannot use autogroup:self
with autogroup:tagged
.
Previously we used autogroup:members
instead of autogroup:member
. While both are currently supported, we are using autogroup:member
going forward. You
cannot use both autogroup:member
and autogroup:members
in the same tailnet policy file.
Here's an example ssh
rule that allows all users to have Tailscale SSH access to their own devices, as non-root:
"ssh": [
{
// All users can SSH to their own devices, as non-root
"action": "accept",
"src": ["autogroup:member"],
"dst": ["autogroup:self"],
"users": ["autogroup:nonroot"]
},
]
Important note about autogroup:nonroot
In the default ACL, the ssh
rule uses autogroup:self
for the dst
field andautogroup:nonroot
in the users
field. If you change the dst
field fromautogroup:self
to some other destination, such as an ACL tag, also consider replacing autogroup:nonroot
in the users
field. If you don't removeautogroup:nonroot
from the users
field, then anyone permitted by the src
setting will be able to SSH in as any nonroot user on the dst
device.
Domain Based Autogroups (domainbased
)
Some autogroups incorporate a specific domain name into the autogroup, for example user:*@example.com
or localpart:*@example.com
. Such autogroups are scoped to users who are both members of the tailnet and whose login is in the autogroup domain. For example, if the tailnet example.com
uses the autogroup user:*@altostrat.com
, this group will include all members of the example.com
tailnet who log in as a user at @altostrat.com
such as laura@altostrat.com
.
The following restrictions apply to the domains used in such autogroups:
- The given domain must not be a known shared domain. For example,
gmail.com
. - If a tailnet uses domain aliases, the aliased domains have to be explicitly specified in the ACL. For example, if
example.io
is aliased toexample.com
and you want to include users from bothexample.com
andexample.io
, your would need to use bothuser:*@example.com
anduser:*@example.io
. - Although the expressions use the wildcard
*
, it does not support arbitrary wildcards. For example,user:b*b@example.com
will not matchbob@example.com
.
Groups (groups
)
The groups
section lets you define a shorthand for a group of users, which you can then use in access rules instead of listing users out explicitly. Any change you make to the membership of a group is automatically propagated to all the rules that reference that group.
A groups
definition looks like this:
"groups": {
"group:engineering": [
"dave@example.com",
"laura@example.com",
],
"group:sales": [
"brad@example.com",
"alice@example.com",
],
},
Every group name must start with the prefix group:
. Each member of a group is specified by their full email address, as explained in the users section above. To avoid the risk of obfuscating group membership, groups cannot contain other groups.
You can add or remove a user's group membership by editing the tailnet policy file, as shown in the example groups
definition above, and directly from the Users page of the admin console.
Editing a user's group membership from the Users page
You need to be an Owner, Admin, or Network admin to edit a user's group membership from the Users page, same as for editing ACLs in general.
- Open the Users page in the admin console.
- Find the user by name.
- Click the menu and then click Edit group membership.
- In the Edit group membership dialog:
- To add a group, click Add to a group and select the group to add.
- To remove a group, click the X next to the group to delete.
- When you are done editing the groups for the user, click Save.
Provisioned groups
You can create groups in your identity provider and sync them for use in Tailscale's ACLs with user & group provisioning.
You can use the same human-readable group names you have in your identity provider to refer to groups in your tailnet policy file, for example, an access rule that manages access for the “security-team” group would look like:
{
"acls": [
{
"action": "accept",
"src": ["group:security-team@example.com"],
"dst": ["tag:logging:*"]
}
],
"tagOwners": {
"tag:logging": ["group:security-team@example.com"]
}
}
You can edit only groups that are defined in ACLs. That is, while you can use groups that are synced from a System for Cross-domain Identity Management (SCIM) integration or tailnet autogroups, you cannot edit them.
Referencing multiple devices
Access rules for sets of devices can be defined in multiple ways. Tags let you define role-based access controls, so that different services have different access rules. Hosts let you define controls based on a reference to an IP address.
Devices can be referenced in ACLs using:
- Tags, to reference non-user devices which need to be accessed together. For example, all servers in a particular data center, or all applications belonging to the DevOps team.
- Hosts, to reference IP ranges both on and beyond the tailnet.
Tags should be used to reference applications or servers. Hosts should be used to address applications with fixed IP addresses, and which you may not be able to modify.
Tags
Tags are a substitute for a human identity on a device. That is, rather than a device being authenticated as a particular user, the device's identity on the Tailscale network is the set of tags assigned to it. This is the combination of all of its tags (not the intersection).
The tag must be defined in the tagOwners
section of the tailnet policy file before it can be used. To tag a device, authenticate as the tag on the device.
Hosts (hosts
)
The hosts
section lets you define a human-friendly name for an IP address or CIDR range, to make access rules more readable.
A hosts
definition looks like this:
"hosts": {
"example-host-1": "100.100.100.100",
"example-network-1": "100.100.101.100/24",
},
The human-friendly name cannot include the character @
.
Postures (postures
)
The postures
section of the tailnet policy file defines a set of assertions that a device must meet as part of a specific access rule, as part of device posture management.
A postures
definition looks like this:
"postures": {
"posture:latestMac": [
"node:os IN ['macos', 'linux']",
"node:tsReleaseTrack == 'stable'",
"node:tsVersion >= '1.40'",
],
},
Each posture must start with the prefix posture:
followed by a name, and lists a set of posture attributes and their allowed values, given as a list of strings.
See device posture management for more information.
Tag Owners (tagOwners
)
The tagOwners
section of the tailnet policy file defines the tags that can be applied to devices, and the list of users who are allowed to assign each tag.
A tagOwners
definition looks like this:
"tagOwners": {
"tag:webserver": [
"group:engineering",
],
"tag:secure-server": [
"group:security-admins",
"president@example.com",
],
"tag:corp": [
"autogroup:member",
],
}
Every tag name must start with the prefix tag:
. A tag owner can be a user's full login email address (as defined in the users section above), a group name, an autogroup, or another tag.
A shorthand notation, []
, is available for autogroup:admin
. That is, the following are equivalent:
"tag:monitoring": [
"autogroup:admin",
],
"tag:monitoring": [],
autogroup:admin
and autogroup:network-admin
can assign any tags, so []
implicitly means that only autogroup:admin
and autogroup:network-admin
are allowed.
Auto Approvers (autoApprovers
)
The autoApprovers
section of the tailnet policy file defines the list of users who can perform certain actions without requiring further approval from the admin console. This is because some actions in Tailscale require double opt-in: they need to both enabled in the Tailscale admin console by a tailnet admin, and enabled on the device running Tailscale. This includes advertising a specified set of routes as a subnet router or advertising an exit node. For routes, this also permits the auto approvers to advertise a subnet of the specified routes.
An Owner, Admin, or Network admin can still disable the route or exit node from the admin console. To avoid the same route being advertised and auto-approved again, consider modifying autoApprovers
.
If the device is re-authenticated by a different user who cannot advertise the route or exit node, or the user who advertised it is suspended or deleted, the route or exit node is no longer advertised. To avoid this, consider making an ACL tag an auto approver.
An autoApprovers
definition looks like this:
"autoApprovers": {
"routes": {
"10.0.0.0/24": ["group:engineering", "alice@example.com", "tag:foo"],
},
"exitNode": ["tag:bar"],
}
The auto approver of a route or exit node can be a user's full login email address (as defined in the users section above), a group name, an autogroup or a tag.
Tailscale SSH (ssh
)
The ssh
section of the tailnet policy file defines the lists of users and devices that can use Tailscale SSH, and as which SSH users. For a connection to be permitted, the tailnet policy file must contain rules permitting both network access and SSH access:
- An access rule to allow connections from the source to the destination on port 22.
- An SSH access rule to allow connections from the source to the destination and the given SSH users. This is used for Tailscale SSH, to distribute keys for authenticating SSH connections.
An ssh
definition looks like this:
{
"action": "check", // "accept" or "check"
"src": [ list-of-sources... ],
"dst": [ list-of-destinations... ],
"users": [ list-of-ssh-users... ],
"checkPeriod": "20h", // optional, only for check actions. default 12h
},
action
Specifies whether to accept the connection or to perform additional checks on it.
accept
accepts connections from users already authenticated on the tailnet.check
requires users to periodically reauthenticate according to thecheckPeriod
.
src
The source where a connection originates from. This can be a user, group, tag, autogroup:member
, user:*@<domain>
, or autogroup:tagged
. This cannot be a bare wildcard *
.
Granting access to autogroup:members
also allows access to external invited users if the destination node is shared with them,
even if they have no nodes in your tailnet.
dst
The destination where the connection goes. This can be a user, tag, or autogroup. Note that unlike ACLs, a port cannot be specified. Only port 22 is allowed, and does not need to be specified as it is used by default. This cannot be a bare wildcard *
.
users
The set of allowed usernames on the host. As with other SSH clients, Tailscale will only use user accounts that already exist on the host, not create new accounts.
- Specify
autogroup:nonroot
to allow any user that is notroot
. - Specify
localpart:*@<domain>
to allow the user on the host whose name matches the local-part of the user's login, if and only if the user's login email is in<domain>
. Tailscale does not do any special processing on the local-part. For example, if the login is dave+sshuser@example.com, Tailscale will map this to the ssh userdave+sshuser
. - If no user is specified, Tailscale will use the local host’s user. That is, if the user is logged in as
alice
locally, then connects with SSH to another device, Tailscale SSH will try to log in as useralice
.
checkPeriod
When action
is check
, checkPeriod
specifies the time period for which to allow a connection before requiring a check. This can be specified in minutes or hours, with a minimum of one minute and a maximum of 168 hours (one week).
- If not specified, the default is 12 hours.
- You may also specify
always
to require check mode on every connection. Choosing to always require check mode may cause unexpected behavior with automation tools that open many SSH connections in a short time span, such as Ansible.
SSH access rules are evaluated considering the most restrictive policies first:
- Check policies
- Accept policies
For example, if you have an access rule allowing the user alice@example.com to access a resource with an accept
rule, and a rule allowing group:devops
which alice@example.com belongs to, to access a resource with a check
rule, then the check
rule applies.
New tailnets or existing tailnets that have not modified their ACLs have a default SSH policy allowing users to access their own devices using check mode.
The only kinds of connections that are allowed are:
- From a user to their own devices, as any user including
root
. - From a user to a tagged device, as any user including
root
. - From a tagged device to another tagged device, for any tags. Note that an SSH access rule from a tagged device cannot be in check mode.
- From a user to a device that has been shared with them, as long as the destination host has Tailscale configured with SSH and the destination’s ACL allows the user to connect over SSH.
That is, the broadest policy allowed would be:
{
"acls": [
{
"action": "accept",
"src": ["*"],
"dst": ["*:*"]
}
],
"ssh": [
{
"action": "accept",
"src": ["autogroup:member"],
"dst": ["autogroup:self"],
"users": ["root", "autogroup:nonroot"]
},
{
"action": "accept",
"src": ["autogroup:member"],
"dst": ["tag:prod"],
"users": ["root", "autogroup:nonroot"]
},
{
"action": "accept",
"src": ["tag:logging"],
"dst": ["tag:prod"],
"users": ["root", "autogroup:nonroot"]
}
]
}
To allow a user to only SSH to their own devices, as non-root
:
{
"acls": [
{
"action": "accept",
"src": ["*"],
"dst": ["*:*"]
}
],
"ssh": [
{
"action": "accept",
"src": ["autogroup:member"],
"dst": ["autogroup:self"],
"users": ["autogroup:nonroot"]
}
]
}
To allow group:sre
to access devices in the production environment tagged tag:prod
:
{
"groups": {
"group:sre": ["alice@example.com", "bob@example.com"]
},
"acls": [
{
"action": "accept",
"src": ["group:sre"],
"dst": ["tag:prod:*"]
},
],
"ssh": [
{
"action": "accept",
"src": ["group:sre"],
"dst": ["tag:prod"],
"users": ["ubuntu", "root"],
},
]
"tagOwners": {
// users in group:sre can apply the tag tag:prod
"tag:prod": ["group:sre"]
}
}
It may be useful to match host users with login emails. For example, you can allow dave@example.com
to authenticate as the host user dave
. To allow any tailnet member in the login domain example.com
to access devices in the production environment that are tagged tag:prod
, as a user that matches their login email local-part:
{
"acls": [
{
"action": "accept",
"src": ["user:*@example.com"],
"dst": ["tag:prod:*"]
}
],
"ssh": [
{
"action": "accept",
"src": ["user:*@example.com"],
"dst": ["tag:prod"],
"users": ["localpart:*@example.com"]
}
]
}
Node attributes (nodeAttrs
)
The nodeAttrs
section of the tailnet policy file defines additional attributes that apply to certain devices in your tailnet. You can use this to set different NextDNS configurations for different devices in your tailnet.
A nodeAttrs
definition looks like this:
"nodeAttrs": [
{
"target": ["my-kid@my-home.com", "tag:server"],
"attr": [
"nextdns:abc123",
"nextdns:no-device-info",
],
},
],
target
The target
field specifies which nodes the attributes apply to. This can be a tag (tag:server
), user (alice@example.com
), group (group:kids
), or *
.
attr
The attr
field specifies which attributes apply to those nodes. For this example, the attributes are:
nextdns:abc123
, for a NextDNS configurationabc123
. If this is used, the attribute overrides the global NextDNS configuration.nextdns:no-device-info
, to disable sending device metadata to NextDNS.
This example allows members of the tailnet to use Tailscale Funnel on their nodes:
"nodeAttrs": [
{
"target": ["autogroup:members"],
"attr": ["funnel"],
},
],
Tests (tests
)
The tests
section lets you write assertions about your access rules, which are checked whenever the tailnet policy file is changed. Failing assertions cause the new tailnet policy file to be rejected, with an error detailing which test assertion wasn't met.
Just like writing tests for software, ACL tests let you ensure that an important permission isn't accidentally revoked later on, or that a critical system in your network isn't exposed more than expected.
A tests
definition looks like this:
"tests": [
{
"src": "dave@example.com",
"srcPostureAttrs": {
"node:os": "windows",
},
"proto": "tcp",
"accept": ["example-host-1:22", "vega:80"],
"deny": ["1.2.3.4:443"],
},
],
src
The src
field specifies the user identity being tested, which can be a user's email address, a group, an ACL tag, or a host that maps to an IP address. The test case will be run from the perspective of a device signed in as that user, with that group membership, with that tag, or as that host, respectively.
srcPostureAttrs
The srcPostureAttrs
field specifies Device Posture attributes as key-value pairs to be used when evaluating posture conditions in your access rules. This field is only needed if your access rules contain device posture conditions.
proto
The optional proto
field specifies the IP protocol for accept
and deny
rules, similar to the proto
field in ACL rules. When omitted, the test checks for either TCP or UDP access.
accept
and deny
destinations
The accept
and deny
fields specify destinations that the access rules should accept or deny, respectively.
Previously we used allow
, instead of accept
, in ACL tests. While both terms are currently supported, we are using accept
going forward.
Each destination in the list is of the form host:port
, where port
is a single numeric port and host
is one of the following:
Type | Example | Meaning |
---|---|---|
Tailscale IP | 100.101.102.103 | The Tailscale IP of the device. IPv6 addresses must follow the format [1:2:3::4]:80 . |
Host | my-host | Looks up the Tailscale IP in the hosts section |
User | shreya@example.com | The Tailscale IP of a device currently signed in as the given user |
Group | group:security@example.com | The Tailscale IP of a device currently signed in as a representative member of the given group |
Tag | tag:production | The Tailscale IP of a device currently tagged with the given tag |
Sources in src
and destinations in accept
and deny
must refer to specific entities and do not support *
wildcards. For example, an accept
destination cannot be tags:*
.
SSH Tests (sshTests
)
The sshTests
section lets you write assertions about your Tailscale SSH access rules and function similarly to ACL tests, but for Tailscale SSH.
SSH tests are checked whenever the tailnet policy file is changed. Failing assertions cause the new tailnet policy file to be rejected, with an error detailing which test assertion wasn't met.
An sshTests
definition looks like this:
"sshTests": [
{
"src": "dave@example.com",
"dst": ["example-host-1"],
"accept": ["dave"],
"check": ["admin"],
"deny": ["root"],
},
],
src
The src
field specifies the user identity that's attempting to connect as SSH, which can be a user's email address, a group, an ACL tag, or a host that maps to an IP address. The test case will be run from the perspective of a device signed in as that user, with that group membership, with that tag, or as that host, respectively.
dst
The dst
field specifies one or more destinations to which the src
user is connecting, which can be a user's email address, a group, an ACL tag, or a host that maps to an IP address.
accept
The accept
field specifies zero, one or more usernames which are allowed on the dst
host without requiring an additional check. See action accept
.
check
The check
field specifies zero, one or more usernames which are allowed on the dst
host if the src
user passes an additional check. See action check
.
deny
The deny
field specifies zero, one or more usernames which are not allowed on the dst
host under any circumstances.
Network policy options
In addition to access rules, the tailnet policy file includes a few network-wide policy settings for specialized purposes. Most networks should never need to specify these.
derpMap
The derpMap
section lets you add custom DERP servers to your network, which your devices will use as needed to relay traffic. You can also use this section to disable the use of Tailscale-provided DERP servers, for example to meet corporate compliance requirements. The derpMap
section is detailed in the article on running custom DERP servers.
disableIPv4
The disableIPv4
field, if set to true
, stops assigning Tailscale IPv4 addresses to your devices. All devices in your network will receive exclusively IPv6 Tailscale addresses, and devices that do not support IPv6 (for example, systems that have IPv6 disabled in the operating system) will be unreachable. This option is intended for users who have a pre-existing conflicting use of the 100.64.0.0/10
carrier-grade NAT address range.
OneCGNATRoute
The OneCGNATRoute
field controls the routes that Tailscale clients will generate.
Tailscale clients can have either:
- One large
100.64/10
route to avoid churn in the routing table as nodes go online and offline. (The churn is disruptive to Chromium-based browsers on macOS.) - Fine-grained /32 routes.
The possible values for OneCGNATRoute
are:
- An empty string or not provided: Use default heuristics for each platform.
- On macOS (for Tailscale v1.28 or later), Tailscale will prefer to add one large
100.64/10
route. Tailscale will not do this if there are other interfaces that also route IP addresses in that range. - On other platforms, Tailscale will add fine-grained /32 routes for each node.
- On macOS (for Tailscale v1.28 or later), Tailscale will prefer to add one large
"mac-always"
: macOS clients will always add one100.64/10
route."mac-never"
: macOS clients will always add fine-grained /32 routes.
randomizeClientPort
The randomizeClientPort
field, if set to true
, makes devices prefer a random port for WireGuard traffic over the default static port 41641. This option is intended as a workaround for some buggy firewall devices, and should only be enabled after consulting with Tailscale (contact support).