Policy
Write a Tailscale-style policy file with grants or ACLs: allow-all and deny-all starting points, supported autogroups, node attributes and IP pools.
Slopscale implements a large portion of Tailscale’s policy features, most notably access control based on ACLs and Grants or Tailscale SSH. See limitations to learn about missing features and notable implementation differences between Slopscale and Tailscale.
Slopscale uses the same huJSON based file format as Tailscale. By default, no
policy is loaded which means that Slopscale allows all traffic between nodes. To start using a policy file1, specify
its path in the policy.path key in the configuration file.
Slopscale needs to be reloaded to pick up changes to the policy file. Either reload Slopscale via its systemd service
(sudo systemctl reload slopscale) or by sending a SIGHUP signal (sudo kill -HUP $(pidof slopscale)) to the main
process. Slopscale logs the result of policy processing after each reload.
Tailscale’s policy documentation covers the format:
- Tailscale policy file: A description of supported sections within the policy file along with links to syntax references for each section.
- ACLs: How to configure access control using ACLs.
- Grants: Introduction to Grants with links to syntax reference, examples and a migration guide from ACLs to Grants.
Getting started
Slopscale supports both ACLs and Grants to write an access control policy. We recommend the use of Grants since ACLs are considered legacy and will not receive new features by Tailscale.
Allow All
If you define a policy file but completely omit the "acls" or "grants" section, Slopscale will default to an allow
all policy. This means all devices connected
to your tailnet will be able to communicate freely with each other.
{}
Deny All
To prevent all communication within your tailnet, you can
include an empty array for the "grants" section in your policy file.
{
"grants": []
}
More examples
- See our documentation on subnet routers and exit nodes to learn how to restrict their use or how to automatically approve them.
- The Tailscale documentation provides a large collection of configuration examples:
Limitations
- Device postures are supported through
postures,srcPostureanddefaultSrcPosture; see Device trust. Postures in the file have no schedule. - IP sets aren’t supported.
- A subset of Autogroups are available.
- A service is a destination,
svc:web, andautoApprovers.servicesnames who may host one.
Autogroups
Slopscale supports several Autogroups that automatically include users, destinations, or devices with specific properties. Autogroups provide a convenient way to write policy rules without manually listing individual users or devices.
autogroup:internet
Allows access to the internet through exit nodes. Can only be used in policy destinations.
{
"grants": [
{
"src": ["alice@"],
"dst": ["autogroup:internet"],
"ip": ["*"]
}
]
}
autogroup:member
Includes all personal (untagged) devices.
{
"grants": [
{
"src": ["autogroup:member"],
"dst": ["tag:prod-app-servers"],
"ip": ["80,443"]
}
]
}
autogroup:tagged
Includes all devices that have at least one tag.
{
"grants": [
{
"src": ["autogroup:tagged"],
"dst": ["tag:monitoring"],
"ip": ["9090"]
}
]
}
autogroup:owner, autogroup:admin, autogroup:network-admin, autogroup:it-admin, autogroup:auditor
Include the personal (untagged) devices of every user holding that
role. Usable wherever autogroup:member is.
{
"grants": [
{
"src": ["autogroup:admin"],
"dst": ["tag:prod-app-servers"],
"ip": ["22"]
}
]
}
autogroup:shared
For each destination node, the personal devices of the users the node has been shared with. Can only be used in policy sources. The destination is narrowed to the shared node itself, so the rule below lets sharees reach the nodes shared with them and nothing else.
{
"grants": [
{
"src": ["autogroup:shared"],
"dst": ["autogroup:member"],
"ip": ["*"]
}
]
}
autogroup:self
Includes devices where the same user is authenticated on both the source and destination. Does not include tagged devices. Can only be used in policy destinations.
{
"grants": [
{
"src": ["autogroup:member"],
"dst": ["autogroup:self"],
"ip": ["*"]
}
]
}
autogroup:nonroot
Used in Tailscale SSH rules to allow access to any user except root. Can only be used in the users field of SSH rules.
{
"ssh": [
{
"action": "accept",
"src": ["autogroup:member"],
"dst": ["autogroup:self"],
"users": ["autogroup:nonroot"]
}
]
}
autogroup:danger-all
This autogroup resolves to all IP addresses (0.0.0.0/0 and ::/0) which also includes all IP addresses outside the
standard Tailscale IP ranges. This autogroup can only be used as source.
Node Attributes
Node attributes allow for device-specific configuration and attributes. At least the following node attributes are currently supported by Slopscale2:
drive:access,drive:share: Taildrive support.suggest-exit-node,suggest-exit-node-ui: Automatic exit node selection. Slopscale stampssuggest-exit-nodeon approved exit nodes on its own, so the policy only needs these to narrow or widen what the client is offered.nextdns:<profile>,nextdns:no-device-info: NextDNS integration. Be sure to set NextDNS as global resolver in the configuration.magicdns-aaaa: Respond to AAAA queries on the local MagicDNS resolver at 100.100.100.100.disable-ipv4: Selectively disable IPv4 for specific nodes. This may be useful to work around CGNat conflicts.randomize-client-port: Allocate a random port for WireGuard traffic instead of the static default port 41641.disable-captive-portal-detection: Disable automatic captive portal detection.disable-relay-server: keep the node from acting as a peer relay, whatever its own--relay-server-portsetting says.
{
"nodeAttrs": [
{
// Enable MagicDNS AAAA records for all nodes
"target": ["*"]
"attr": ["magicdns-aaaa"]
}
]
}
An entry’s app field carries application capabilities with
data: each key is a domain-qualified
capability name and its values are JSON objects the targets receive verbatim in their node capability map. This is how
app connectors are defined: the tailscale.com/app-connectors
entries name the connector tags and the domains they serve, and a client that carries them routes those domains through
the connector, which learns and advertises the routes. Approve the connector’s routes with an
auto approver for its tag or by hand.
{
"nodeAttrs": [
{
"target": ["autogroup:member"],
"app": {
"tailscale.com/app-connectors": [
{ "name": "github", "connectors": ["tag:appc"], "domains": ["github.com", "*.github.com"] }
]
}
}
]
}
IP pools
ipPool numbers new nodes from a range of your choosing, as Tailscale’s
IP pools do. The target must be a
user, group, tag or autogroup, because the pool is chosen before the node has
an address. The first grant that names the node’s user or tags wins, the
first listed pool with a free address is used, and a node keeps its address
when the policy changes later. Pools must lie within the CGNAT range, outside
the ranges Tailscale reserves, and within prefixes.v4; a full pool refuses
the registration instead of falling back to the default range. Only IPv4 is
pooled.
{
"nodeAttrs": [
{ "target": ["group:dev"], "ipPool": ["100.85.0.0/16"] },
{ "target": ["tag:server"], "ipPool": ["100.86.0.0/24", "100.87.0.0/24"] }
]
}
Network-wide policy options
The following options are applied for the entire tailnet. Consider node attributes for a more fine-grained configuration instead.
randomizeClientPort: Allocate a random port for WireGuard traffic instead of the static default port 41641.
{
// Use a random WireGuard port for the entire tailnet
"randomizeClientPort": true
}
Footnotes
-
Slopscale also allows to store the policy in the database. This is typically only required in case the admin console is used. ↩
-
Other key-only node attributes can be used as well. Find them in the client source code with
grep -E '^\s+NodeAttr\w+' tailcfg/tailcfg.goor by using GitHub code search (requires login). ↩