---
id: roles-and-permissions
title: 'Roles and Permissions'
description: 'The thirteen roles Agility supports, how Rights differ from Privileges, and what actually separates one role from another — written for integrators provisioning Members.'
sidebar_label: 'Roles and Permissions'
sidebar_position: 7
tags: ['reference', 'roles', 'permissions', 'rights', 'privileges', 'members']
---

If you are provisioning Members through the API, the role you assign is the single most
consequential field on the request — and until now it has not been documented anywhere public.
This page covers the roles Agility supports and what genuinely separates them.

## Rights and Privileges Are Not the Same Thing

Agility has two distinct permission mechanisms, and the distinction is the thing most worth
understanding before assigning anything.

| | **Rights** | **Privileges** |
| --- | --- | --- |
| Apply | Within a Scope | Across **all** Scopes |
| Depend on | The Scope of the asset being acted on, where that asset has a SecurityScope | Nothing — they are global |
| Typical use | Viewing and editing work: stories, tasks, tests, defects, actuals | Administration: managing members, roles, metadata, teams, tags |

**Rights are scoped.** Whether a member may edit a Story depends on which project that Story is
in. The same member can hold different rights in different projects.

**Privileges are global.** A member who can manage metadata can manage it everywhere; there is
no per-project version of that permission.

:::warning Three names appear in both, meaning different things

`ManageSecurity`, `ManageConfig` and `ManageSchedules` exist as **both** a Right and a
Privilege. They are not the same permission — the Right is scoped to a project, the Privilege
is instance-wide.

If you are reading a permission name out of context, establish which of the two it is before
concluding what a member can do. A member holding the `ManageConfig` *Right* on one project is
not the same as a member holding the `ManageConfig` *Privilege*.

:::

## `DefaultRole` Is the Global One

On a Member, **`DefaultRole` is what the UI presents as Admin Privileges**. It does two things:

1. Determines the member's **global privileges**.
2. Determines the role they will act as **by default when granted access to a new Scope**.

A member's role *on a particular project* is separate and can differ. Reading
[`api/ProjectRoles`](/apis/project-roles) returns both, precisely because they answer different
questions.

When provisioning, set `DefaultRole` deliberately — it is not merely a default, it is the
carrier of global privileges.

## The Thirteen Roles

### Administrative

All three have full editing capability within projects. They differ in what they may administer
across the instance.

| Role | Distinguishing capability |
| --- | --- |
| **System Admin** | Everything. The only role that can administer **metadata, roles, lists and OKRs**, and the only one that can override base privileges. |
| **Member Admin** | Everything System Admin can do within projects, plus **member administration** and member labels. Cannot administer metadata, roles or lists. |
| **Project Admin** | Full project capability plus **project-level configuration**, tags, project labels and test integration. **Cannot administer members** — the main line between it and Member Admin. |

### Project Delivery

| Role | Can edit | Cannot |
| --- | --- | --- |
| **Project Lead** | Everything within the project, including project settings, budgets, roadmap, rooms, teams and schedules | Manage security |
| **Team Lead** | All work items — themes, stories, tasks, tests, defects, issues, actuals, retrospectives, capacities, milestones | Edit the project itself, manage security, schedules, rooms or teams |
| **Developer** | Tasks, actuals, defects, issues, capacities, milestones | **Stories, tests and themes** |
| **Tester** | Tests, regression tests, actuals, defects, issues, capacities, milestones | **Stories and tasks** |
| **Customer** | Themes, stories, tests, goals, strategic themes, roadmap, defects, issues | **Tasks and actuals** — the execution side |

The three specialist roles are the ones integrators most often get wrong. **Developer and Tester
are near-mirrors**: Developer edits tasks but not tests, Tester edits tests but not tasks, and
neither can edit stories. **Customer is the requirements role** — it can shape what gets built
but not record how the work is executed.

### Read and Submit

| Role | What it can see |
| --- | --- |
| **Requestor** | Everything Observer sees, **plus the ability to submit** — it holds general write but cannot edit work items |
| **Observer** | Full read across work items. No write of any kind |
| **Visitor** | Limited read: scope, themes, stories, defects, goals and roadmap |
| **Inheritor** | Minimal read: scope, themes, goals and roadmap. Used where access is inherited from a parent project |
| **No Access** | Nothing |

**Requestor and Observer see exactly the same things.** The only difference is that Requestor can
submit. If you are provisioning someone who needs to raise requests but not edit work, that is
Requestor; if they need to look and nothing more, that is Observer.

## Match on Role ID, Never on the Name

**Role IDs are fixed.** The OID token identifying a role is stable, so it is the safe thing for
an integration to match on.

**Role names are not.** Agility almost never displays a role's `Name` directly — it runs it
through the localizer first. Three consequences follow, and each one breaks integrations that
match on strings.

### The Displayed Name Can Differ from the Stored Name

A role's stored `Name` is a localization tag of the form `Role.Name'<label>`, and the UI shows
the tag's translation. Most roles display as the label inside their tag. One does not:

| Stored `Name` | Displayed as (default English) |
| --- | --- |
| `Role.Name'Team Lead` | **`Team Member`** |
| `Role.Name'Project Admin` | `{Scope} Admin` — "Project Admin" by default |
| `Role.Name'Project Lead` | `{Scope} Lead` — "Project Lead" by default |
| All others | The label inside the tag — `Role.Name'System Admin` displays as `System Admin`, and likewise `Developer`, `Tester`, `Customer`, `Requestor`, `Observer`, `Visitor`, `Inheritor`, `No Access` |

**`Team Lead` and `Team Member` are the same role.** Someone reading "Team Member" in the UI and
searching the API for a role of that name will find nothing, because the asset's `Name` is
`Role.Name'Team Lead`. Searching for `Team Lead` finds nothing either: a lookup by name has to use
the whole tag. This is the single most likely place to lose time when provisioning.

### Two Role Names Embed the Term for Scope

`Project Admin` and `Project Lead` display as `{Scope} Admin` and `{Scope} Lead`, where `{Scope}`
is itself a localized term. An instance that has re-termed "Project" as "Workstream" shows those
roles as **Workstream Admin** and **Workstream Lead** — with no change to the underlying role.

### Customers Can Rename Any Role

Because a role's stored `Name` is an ordinary localizer tag, its translation can be overridden
per instance through
[terminology overrides](/apis/loc-2-v1/overrides). Any role can be called anything on any
instance.

:::danger Do not match roles by name

Between the `Team Lead` / `Team Member` mismatch, the two `{Scope}`-derived names, and
per-instance terminology overrides, a role's displayed name is not a reliable identifier. Match
on the **Role OID**.

Read the OIDs from the instance once — for example via a [`meta.v1`](/apis/meta-v1)-informed
query for `Role` assets — and hold them as configuration. They are fixed, so this is a one-time
lookup rather than something to resolve on every call.

The same reasoning applies to asset type and attribute names, which are also localized. See
[Terminology](/apis/conventions/terminology).

:::

## Assigning Roles

Role assignment is a **write**, and the [Bulk API](/apis/asset-bulk) is the only API endpoint
designed for it. [`api/ProjectRoles`](/apis/project-roles) reads role assignments and cannot
change them.

## Where These Permissions Show up in This Documentation

Several endpoints name a specific Right or Privilege as their requirement:

- [Room panels](/apis/rooms/panels) require the **`EditRoom` Right** — held by System Admin,
  Member Admin, Project Admin and Project Lead. Note this applies even to the read routes.
- [Terminology overrides](/apis/loc-2-v1/overrides) via `api/localizations` require the
  **`ManageConfig` Privilege** — the global one, not the project-scoped Right of the same name,
  which is why it is effectively System Admin only.
- [Creating a webhook subscription](/apis/webhooks/create) requires the **`ManageConfig`
  Privilege**.


## Related

- [Project Roles API](/apis/project-roles) — read who holds which role where
- [Bulk API](/apis/asset-bulk) — assign roles
- [Meta API](/apis/meta-v1) — `Member`, `Role` and `Scope` schema
