Server role accounts using ACL tags

Tags let you assign an identity to a device that is separate from human users, and use that identity as part of an ACL to restrict access. This should be used when adding servers to your Tailscale network, so that their access is based on their purpose, not based on which member of your operations team enrolled them.

ACL tags are available for all plans.

What are ACL tags?

Some services have a “role account” or “service account” which is based on an entity’s or service’s role, rather than a human identity.

ACL tags are similar to role accounts, but more flexible: you can assign many tags to a device, whereas a device can only be signed in as a single user.

When should you use ACL tags?

You should use an ACL tag when authenticating servers in your network, and use user authentication when authenticating end user devices.

Authentication and authorization

Tags are authenticated as a user, but authorized as a tag—so unlike service accounts, aren’t a new identity for authentication, but rely on existing user identities from your identity provider. When an ACL tag is added to a device, it replaces the prior user authentication on that device.

Once a device has been tagged, it loses the access permissions of the human user who tagged it, and acquires any access permissions granted to its tags. In other words, if you log into a device as dave@tailscale.com and then tag it with tag:server, the device no longer has any of the network permissions granted to dave@tailscale.com, and instead is subject to the access rules for tag:server. If the user who added the device is deleted, the device will remain.

The user currently signed into Tailscale on the device must be a tag owner of all the tags you assign. That is, if you previously ran tailscale up and signed in as dave@tailscale.com, you can only assign tags that are owned by dave@tailscale.com.

When re-tagging a device, including adding, changing, or removing tags, you may be asked to re-authenticate.

If your device is not currently signed in, you’ll be asked to authenticate as usual as part of the tailscale up operation.

ACLs

A device’s identity is the combination of all its tags (not the intersection). For example, you might have a device that is both a tag:server and part of your tag:prod network. You could assign both tags to the device to manage permissions for these tags separately.

You can use these tags as part of access control lists (ACLs) in your tailnet, to make it easier to manage which types of devices should be able to communicate. For example, you might tag a production server tag:prod and a production database tag:prod, and allow all tag:prod devices to communicate with each other in your network, rather than having to specify each device individually.

For example, here’s a tailnet policy file for letting all devices tagged tag:prod to communicate with each other:

{
  "acls": [
    {
      "action": "accept",
      "src": ["tag:prod"],
      "dst": ["tag:prod:*"],
    },
  ],
  // (other tailnet policy entries here)
}

Key expiry for tagged devices

Effective March 10, 2022, when you apply a tag to a device for the first time and authenticate it, the tagged device will have key expiry disabled by default.

If you re-authenticate an existing device that you tagged prior to March 10, 2022, its expiry will also be disabled by default.

If you change the tags on the device via the admin console, CLI, or API, the device’s key expiry will not change unless you are asked to re-authenticate. That is, if it is enabled, it stays enabled; and if it is disabled, it stays disabled. Once you re-authenticate, the device’s key expiry will be disabled.

You can enable or disable key expiry on a device via the admin console and via API.

Defining a tag

Before you can assign a tag to a device, you have to create the tag in the tailnet policy file, and define who can use that tag.

For example, here’s a tailnet policy file that creates the tag tag:server on a tailnet, and assigns dave@tailscale.com as the single owner who can apply the tag tag:server:

{
  // (other tailnet policy file entries here)

  "tagOwners": {
    "tag:server": ["dave@tailscale.com"]
  }
}

ACL tags are parsed lowercased in the tailnet policy file. Any casing is ignored.

Defining tag owners

Tags are meant to be referenced in ACLs, so the ability to assign a tag to a device translates to granting new access permissions to that device. As such, Tailscale requires you to explicitly define who is allowed to use a tag to grant its permissions on a device.

Tag owners are defined in the tailnet policy file.

A tag can be the owner of another tag, for example tag:deployment can own tag:prod and tag:test, so that a deployment tool can restrict infrastructure as appropriate as part of a deployment.

A tag can also have empty owners. This still allows the tag to be applied in the admin console and as part of an auth key.

Applying a tag to a device

Devices can be tagged in the admin console, using the CLI, or using the API.

When you re-authenticate and tag a device, this generates a new node key for the device. The Tailscale IP for the device does not change.

Applying a tag to a device in the admin console

You need to be an Owner, Admin, or Network admin of a tailnet in order to tag a machine from the admin console. This does not require re-authentication, as the logged in user is automatically used to authenticate the device.

To tag a device from the admin console:

  1. Open the Machines page in the admin console.
  2. Find the row corresponding to the device you are interested in.
  3. Click on the ellipsis icon menu at the far right and select the Edit ACL tags option.
  4. Add, change, or remove desired tags. Recall that to apply a tag, it must already exist in the tailnet policy file.
  5. Click Save to apply tags.

Owners, Admins and Network admins can apply any tag from the admin console, without being a tag owner.

You cannot remove all tags from a tagged device in the admin console. This is because the device must have an identity. Either assign the device a new tag, or re-authenticate to Tailscale from the device.

Applying a tag to a device with the CLI

Only Linux, macOS, and Windows devices can be tagged using the CLI. To tag other devices, use the admin console.

Assign tags to a device by adding the --advertise-tags option to tailscale up. That is, if you initially added the device to your network by running…

sudo tailscale up

… then you would convert that device to a tagged device by running:

sudo tailscale up --advertise-tags=tag:server

If you want to assign multiple tags to a device, comma-separate them like this:

sudo tailscale up --advertise-tags=tag:server,tag:development

To undo the tagging operation and revert the device to being identified by its authenticated user, use the --advertise-tags flag without any value:

sudo tailscale up --advertise-tags=

If you are using an auth key with ACL tags, you cannot remove tags using the --advertise-tags flag without any value. Instead, generate a new auth key with the desired set of tags.

If the device is already logged in, and you need to change the signed-in user because the current user doesn’t have tag ownership, add the --force-reauth flag to the command:

sudo tailscale up --advertise-tags=tag:server --force-reauth

You can then log in again as the appropriate user.

Applying a tag to a device using the API

You can apply a tag to a device using the API.

To do so, send a POST request for a device, with the body specifying the desired tags. For example:

curl https://api.tailscale.com/api/v2/device/11055/tags \
-u "tskey-<key>" \
-H "Content-Type: application/json" \
--data-binary '{"tags": ["tag:foo", "tag:bar"]}'

Using an ACL tag with an auth key

When connecting a new device to a tailnet using an auth key, you can specify an ACL tag as well, so that a device is automatically tagged when it is authenticated.

To do this, you must:

  1. Generate an auth key with the desired ACL tags.
  2. Then, specify that auth key when authenticating a device. The tag is automatically applied.

Generate an auth key with an ACL tag

When you generate a new auth key, you can specify the tags to be applied when the auth key is used. A user can only add tags for which they are a tag owner, unless they are an Owner, Admin, or IT admin. You can generate an auth key with an ACL tag both using the admin console and using the API.

In the admin console:

  1. Open the Keys page in the admin console.
  2. Click Generate auth key.
  3. Enable adding tags to the auth key.
  4. Click Add tags to add tags to the auth key.
  5. Click Generate to generate the auth key.
The Pre-approved option will only display in the dialog if device approval is enabled in your Tailscale network.

In the API:

  1. Send a POST request to the /api/v2/tailnet/:tailnet/keys endpoint, specifying desired tags as part of the request:
    {
        "capabilities": {
            "devices": {
                "create": {
                    "tags": [
                        "tag:montreal-webserver",
                        "tag:api-server"
                    ]
                }
            }
        },
        ...
    }
    
  2. The server responds with a JSON message with the generated key in the key member. For example:
    {
      "id": "k123456CNTRL",
      "key": "tskey-k123456CNTRL-abcdefghijklmnopqrstu",
      "created": "2021-12-09T09:20:52Z",
      "expires": "2022-03-09T09:20:52Z",
      "capabilities": {
        "devices": {
          "create": {
            "reusable": false,
            "ephemeral": false,
            "tags": ["tag:montreal-webserver", "tag:api-server"]
          }
        }
      }
    }
    

Then, to use the auth key:

sudo tailscale up --authkey=KEY

Authenticate the device with the auth key

If you have an auth key with ACL tags, you do not need to specify the tags when authenticating. They will automatically be applied:

sudo tailscale up --authkey=KEY

All tags in the auth key are applied.

To re-tag the device to add or remove tags, either:

  • Generate a new auth key with the desired set of tags, or
  • Modify tagOwners to make the current tags owners of the desired tags, and then apply the new tags. See below.
Apply a tag from another tag

When authenticating, if you wish to apply different tags from those in the auth key, you can re-tag the device. This replaces any tags already applied to the device. When re-tagging a device, the tags in the auth key must be owners of any tags you wish to apply.

This is useful for larger infrastructure deployments, where many servers need to be tagged, typically using a deployment tool. For example, you could have your deployment system tagged with tag:deployment-1, which owns both tag:prod-2 and tag:test-2:

  "TagOwners": {
    "tag:deployment-1": ["alice@tailscale.com"],
    "tag:prod-2": ["tag:deployment-1"],
    "tag:test-2": ["tag:deployment-1"],
  },

You could generate an auth key KEY-1 with the ACL tag tag:deployment-1, and make it available to the deployment tool. Then, depending on what workload you deploy, the system will authenticate the device and apply the correct infrastructure tag, which enforces the correct access controls. When spinning up a new production server, the deployment tool could tag the device as tag:prod-2:

sudo tailscale up --authkey=KEY-1 --advertise-tags=tag:prod-2

Using tags in ACLs for access control

Once you’ve tagged some devices, you can write access control rules that grant permissions based on tags. You can consult the ACL reference manual for a full list of possibilities, but here are a few simple examples of access rules we’ve found useful.

This rule grants SSH access to all devices tagged as servers, for members of the SRE group:

{
  "acls": [
    {
      "action": "accept",
      "src": ["group:sre"],
      "dst": ["tag:server:22"]
    }

    // Other access rules here...
  ]

  // Other policy configuration here...
}

This single rule will automatically adjust the entire network’s access filters as new devices are tagged with tag:server, or as members are added or removed from group:sre.

This rule allows devices tagged with tag:testbed to communicate freely with each other:

{
  "acls": [
    {
      "action": "accept",
      "src": ["tag:testbed"],
      "dst": ["tag:testbed:*"]
    }

    // Other access rules here...
  ]

  // Other policy configuration here...
}

This kind of rule is very useful to create lower-security “sandbox” environments within your network, in which communication is not restricted, but with a strict perimeter that prevents testbed devices from communicating with more important systems.

Of course, you can mix up source and destination tags. For example, this rule grants web frontends and SREs access to database servers:

{
  "acls": [
    {
      "action": "accept",
      "src": ["tag:webserver", "group:sre"],
      "dst": ["tag:database:*"]
    }

    // Other access rules here...
  ]

  // Other policy configuration here...
}

Using tags in ACL tests

To ensure that the ACLs for your tagged devices are working as expected, you can use ACL tests to verify your tailnet policy file prior to saving and applying it.

For example, to verify that your tailnet policy file allows users in the group:sre to access devices tagged tag:prod, you might write an ACL test:

"tests": [
  {
    "src": "group:sre",
    "accept": ["tag:prod:1234"],
  },
],

Last updated