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. Use tags when adding servers to your Tailscale network so that their access is based on their purpose, not on which operations team member enrolled them.

Tags are intended for non-human machines. Users can only access and use Tailscale through their designated user accounts.
ACL tags are available for all plans.

What are tags?

Some services have a “role account” or “service account” based on a service’s role rather than a human identity.

ACL tags are similar to service accounts but more flexible: you can assign many tags to a device, whereas only a single user can sign in on a device.

When should you use ACL tags?

Tags are Tailscale’s answer to service accounts. They’re a way to manage devices on a tailnet without associating them with a user. In fact, a device cannot simultaneously have tags and a user account.

Use tags to:

  • Manage devices you don’t have tied to a specific user (such as a server hosting a web application).
  • Manage devices you want to allow multiple users to manage.

Tags are ideal for managing devices you don’t want to be tied to a specific user (such as a server hosting a web application) because removing a user also removes all their devices. If you link a service-providing device to a user, you lose that device if you remove the user. Removing a user won’t affect the device if you use tags to manage the device instead.

Tags provide a way to allow multiple users to manage a device. When you manage devices with users, you must link each device to a single user, which isn’t ideal for devices that host shared resources. However, when you manage devices with tags, you can assign one or more users as tag owners with tags. These users can manage all the devices with the tags they own.

Do not use tags to:

  • Annotate user devices.
  • Link a user device with a user.

Using tags to annotate user devices is poor practice because a device cannot simultaneously have a user and a tag. Adding a tag to a device removes the associated user. Devices can have tags or a user account, not both.

Do not use tags to associate a user device with a user account. Tags are not designed to tie individual users to a device. They’re intended to manage devices with service account roles. Using tags as a substitute for users poses a security risk because the user’s devices will remain on your network even if you remove the user.

Authentication and authorization

Tags are authenticated as a user but authorized as a tag. Unlike service accounts, they aren’t a new identity for authentication but rely on existing user identities from your identity provider. Adding an ACL tag to a device replaces the prior user authentication on that device.

After you tag a device, it loses the access permissions of the human user who tagged it and acquires any access permissions granted to its tags. If you log into a device as dave@tailscale.com and tag it with tag:server, the device loses all the network permissions granted to dave@tailscale.com and gains all the access rules for tag:server. Deleting the user who added the device doesn’t remove the device.

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

You might need to re-authenticate if you update the tags for a device. This includes adding, changing, or removing tags.

If your device is not signed into a Tailscale account, Tailscale will ask you to authenticate as part of the normal 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 can assign both tags to the device to manage permissions for these tags separately.

You can use tags as part of access control lists (ACLs) 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 specifying each device individually.

Here’s an example tailnet policy file for letting all devices tagged tag:prod communicate with each other:

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

Key expiry for tagged devices

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 before March 10, 2022, its expiry will also be disabled by default.

If you change the tags on the device from the admin console, Tailscale CLI, or the Tailscale API, the device’s key expiry will not change unless you re-authenticate. After you re-authenticate, the device’s key expiry will be disabled.

You can enable or disable key expiry on a device from the Machines page of the admin console or by using the Tailscale 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"],
  }
}

Tailscale parses all ACL tags in the tailnet policy file as lowercase. 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 tagOwners section of 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, which is equivalent to having the owner set to autogroup:admins. This still allows you to apply the tag in the admin console and as part of an auth key. The following example shows tag:infrastructure with empty owners:

{
  // (other tailnet policy file entries here)

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

Applying a tag to a device

You can tag devices using the admin console, the CLI, or the API.

When you re-authenticate and tag a device, it 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 to tag a device from the admin console. This does not require re-authentication because the current 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. 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 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

You can only use the CLI to tag devices running Linux, macOS, or Windows. To tag other devices, use the admin console.

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

sudo tailscale up

… then you could 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 Update device tags method that is available in the Tailscale 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

You can specify an ACL tag when connecting a new device to a tailnet using an auth key. Doing so makes it so that a device is automatically tagged when it authenticates.

To do this, you must:

  1. Generate an auth key with the desired ACL tags.
  2. 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 using the admin console or 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, you can do one of the following:

  • Generate a new auth key with the desired set of tags
  • Modify tagOwners to make the current tags owners of the desired tags, 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 you might need to tag many servers, 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

After you’ve tagged some devices, you can write access control rules that grant permissions based on tags. You can consult the Network access controls topic for a complete 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 with tag:server for members of the Site Reliability Engineers (SRE) group:

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

    // Other access rules here...
  ]

  // Other policy configuration here...
}

This single rule automatically adjusts the entire network’s access filters when you:

  • Tag new devices with tag:server
  • Add members to group:sre
  • Remove members 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 type of rule is 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 critical systems.

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"],
  },
],

Common patterns for tag names

ACL tags allow you to reflect access patterns and network segments based on your organization’s requirements. These access patterns and network segments usually fall into a few common categories. Use consistent patterns for tag names based on these categories to make your ACLs easier to understand and maintain over time. Some common categories of access to consider in your ACL tag names are:

  • Server role: for example, application server, database, or queue
  • Application name: for example, support console, finance reporting, or operations dashboard
  • Environment: for example, production, staging, or development
  • Location: for example, americas, emea, or asia-south1

While a device can have many tags assigned to it, tags are not “joined” for the purpose of access rules. For example, you cannot define a rule that allows access to devices with both tag:prod and tag:database. Instead, you can use a composite tag such as tag:prod-database to represent this type of segmented access pattern. Below are some examples of composite tags.

Tag Access control
tag:prod-app To production application servers
tag:nonprod-db To non-production database servers
tag:prod-app-finance-reporting To the production finance reporting application
tag:prod-emea-app-support-console To the production support console application in EMEA
tag:prod-asiasouth1-ingest-logging To the production logging ingest endpoint in asia-south1