---
title: "User roles"
description: "What the owner, admin, network admin, IT admin, auditor and member roles may do in the API and console, how ownership moves, and roles in the policy."
---

Every user has a role that bounds what the user may do through the admin API
and the management console. The vocabulary follows
[Tailscale's user roles](https://tailscale.com/docs/features/user-roles) minus
billing admin, which has no meaning on a self-hosted server, so the
Tailscale-compatible v2 API reports the same values the Tailscale ecosystem
expects.

A role never decides what a user's devices can reach. That remains the job of
the [policy](/slopscale/ref/policy), which may address roles through
`autogroup:owner`, `autogroup:admin`, `autogroup:network-admin`,
`autogroup:it-admin` and `autogroup:auditor`.

## The roles

| Role            | Users, devices, keys, settings | Policy and routes | Webhooks, posture | Reads everything | Assigns roles |
| --------------- | ------------------------------ | ----------------- | ----------------- | ---------------- | ------------- |
| `owner`         | write                          | write             | write             | yes              | yes           |
| `admin`         | write                          | write             | write             | yes              | yes           |
| `network-admin` | read                           | write             | write             | yes              | no            |
| `it-admin`      | write                          | read              | write             | yes              | no            |
| `auditor`       | read                           | read              | read              | yes              | no            |
| `member`        | none                           | none              | none              | no               | no            |

"Users, devices, keys, settings" are the `users`, `devices:core`, `auth_keys`,
`oauth_keys` and `feature_settings` scopes of the v2 API; "policy and routes"
are `policy_file`, `devices:routes`, `dns` and `services`; webhooks and posture are
`webhooks` and `devices:posture_attributes`. The audit log and log streaming are
`logs:configuration`, which every admin role holds. The
[traffic monitor](/slopscale/ref/traffic) is `logs:network`: the network admin runs it,
and the IT admin reads it with `logs:network:read`. The v1 API declares the same scopes on
its operations, so a credential means the same thing on both APIs. Run
`GET /api/v1/whoami` to see the role and permissions a credential carries.

## What a member gets

A member holds no scope, but every user looks after their own things, so
the [console](/slopscale/ref/console) and the v1 API give a signed-in user a
self-service view whatever their role:

- **Their own machines**, and the machines other users [share](/slopscale/ref/sharing)
  with them. `GET /api/v1/node` lists them and `GET /api/v1/node/{id}`
  reads one, with the live reads a machine's page makes (client health,
  certificate, preferences). Any other machine, tagged ones included, is
  not found, so a member cannot enumerate the tailnet.
- On a machine they own: rename it, expire its key or turn key expiry off,
  remove it, share it and take a share back. A machine shared with them is
  theirs to see, not to change. Tags, routes, approval, suspension and the
  machine's preferences stay with the roles that hold the scopes.
- **The user directory**: `GET /api/v1/user` answers with every approved
  user's id, name, display name and picture, and nothing else (no email,
  provider or role), so a member can share a machine with a colleague by
  name. The list takes no filter for such a caller.
- Their own API keys, [access requests](/slopscale/ref/temporary-access) and console
  sessions, and a browser SSH session to a machine of theirs.

This is what the signed-in user may do for themselves, so it goes with the
credentials that stand for the user: a console session, or an API key
minted without scopes. A key minted with a scope list, or an OAuth token,
is bounded by exactly that list and gets none of it; `whoami` reports such
a credential as `scoped`.

## The owner

The tailnet has exactly one owner.

- The first user created on a fresh server becomes the owner, whether it is
  created with `slopscale users create` or by the first OpenID Connect login.
- The owner's role changes only by transferring ownership: assigning `owner`
  to another user makes that user the owner and turns the previous owner into
  an admin.
- Only the owner can transfer ownership. Nobody can demote or delete the
  owner.

Servers upgraded from a version without roles have no owner: every existing
user is a `member`. Pick one with the CLI, which is bound only by the rules
above:

```console
slopscale users set-role --name alice --role owner
```

## Assigning roles

Only the owner or an admin may assign roles, and nobody may change their own.

```console
slopscale users set-role --name bob --role network-admin
slopscale users list
```

Through the API, `POST /api/v1/user/{id}/role` with `{"role": "auditor"}`.
Roles show in `slopscale users list`, in the v1 user object and in the v2
user object's `role` field, which `GET /api/v2/tailnet/-/users?role=admin`
filters on.

## API keys and roles

An API key may belong to a user, in which case the key is bounded by that
user's current role: demoting the user demotes every key the user holds.

```console
slopscale apikeys create --user 3
```

- Any authenticated caller may mint a key for itself.
- Only the owner, an admin or the CLI over the socket may mint keys for
  other users or keys without a user.
- A key without a user is the historical all-access admin key. Keys created
  before roles existed keep working unchanged.
- A role-bounded caller lists, expires and deletes only its own keys.

OAuth clients created through the v2 API are narrowed the same way: a client
may not be granted a scope its creator lacks.

## Roles in the policy

The role autogroups select the personal (untagged) devices of every user
holding the role, and behave like `autogroup:member` wherever the policy
reasons about users. They work as sources, destinations, SSH sources and
destinations, and `nodeAttrs` targets.

```json title="policy.json"
{
  "grants": [
    {
      "src": ["autogroup:admin"],
      "dst": ["tag:prod-app-servers"],
      "ip": ["22"]
    }
  ],
  "ssh": [
    {
      "action": "accept",
      "src": ["autogroup:owner", "autogroup:network-admin"],
      "dst": ["autogroup:tagged"],
      "users": ["root"]
    }
  ]
}
```

Devices of the owner and admins additionally receive Tailscale's `is-admin`
capability, and the owner's devices `is-owner`, which clients use for the
admin affordances in their UI. Tagged devices carry neither.
