# Roles & permissions

The five Comvi roles, the organization and project permission matrices, project-level overrides, language restrictions and ownership rules.

Canonical: https://comvi.io/docs/platform/roles-permissions

Roles are assigned at the organization level and can be narrowed per project. Humans act
through their member role over a session; an API key carries its own scopes, intersected on
every request with the permissions of the person who created it.

<Mermaid
code={`flowchart LR
    User["Human user"]
    Dashboard["Dashboard / browser"]
    Session["Session<br/>(cookie, Redis store)"]

    Machine["CLI / CI / automation"]
    Header["Authorization: Bearer header"]
    Key["API key record<br/>(project-scoped permission list)"]

    API["Comvi API"]
    PermCheck{"Permission check"}

    User --> Dashboard --> Session --> API
    Machine --> Header --> Key --> API
    API --> PermCheck
    PermCheck -- resolves against --> Roles["Role → permissions"]
    PermCheck -- or --> KeyPerms["API key ∩ creator's current permissions"]
`}
caption="Sessions resolve to the member's role. API keys resolve to their scopes intersected with the creator's current permissions, so demoting the creator narrows the key."
/>

## Roles

| Role | Level | Summary |
|---|---|---|
| **Owner** | 5 | Full control over the organization, billing and all projects |
| **Manager** | 4 | All project permissions plus organization settings, member management and project creation |
| **Editor** | 3 | Create and edit keys and namespaces, import and export, review translations. No members or billing |
| **Translator** | 2 | Create and edit translation values, use machine translation, comment. No keys or project structure |
| **Viewer** | 1 | Read-only access to projects, translations, glossaries and history |

Roles mostly expand access up the hierarchy, but a few permissions differ per role. The
matrices are the source of truth.

## Organization permissions

| Action | Owner | Manager | Editor | Translator | Viewer |
|---|:---:|:---:|:---:|:---:|:---:|
| View organization | ✓ | ✓ | ✓ | ✓ | ✓ |
| Edit organization settings | ✓ | ✓ | | | |
| Delete organization | ✓ | | | | |
| Manage members and invitations | ✓ | ✓ | | | |
| Manage billing | ✓ | | | | |
| Create projects | ✓ | ✓ | | | |
| Manage glossaries | ✓ | ✓ | | | |
| Edit glossary entries | ✓ | ✓ | ✓ | | |
| View glossaries | ✓ | ✓ | ✓ | ✓ | ✓ |
| Manage translation memory | ✓ | ✓ | | | |
| View translation memory | ✓ | ✓ | ✓ | ✓ | ✓ |

## Project permissions

| Action | Owner | Manager | Editor | Translator | Viewer |
|---|:---:|:---:|:---:|:---:|:---:|
| View project and translations | ✓ | ✓ | ✓ | ✓ | ✓ |
| Edit project name, description, AI context | ✓ | ✓ | ✓ | | |
| Delete project | ✓ | ✓ | | | |
| Import translations | ✓ | ✓ | ✓ | | |
| Export translations | ✓ | ✓ | ✓ | | |
| Create and edit translation keys | ✓ | ✓ | ✓ | | |
| Delete translation keys | ✓ | ✓ | ✓ | | |
| Create and edit translation values | ✓ | ✓ | ✓ | ✓ | |
| Review / approve translations | ✓ | ✓ | ✓ | | |
| Create and edit namespaces | ✓ | ✓ | ✓ | | |
| Delete namespaces | ✓ | ✓ | ✓ | | |
| Use machine translation | ✓ | ✓ | ✓ | ✓ | |
| Manage MT settings | ✓ | ✓ | | | |
| Create comments | ✓ | ✓ | ✓ | ✓ | |
| Edit anyone's comment | ✓ | ✓ | ✓ | | |
| Delete comments | ✓ | ✓ | | | |
| View translation history | ✓ | ✓ | ✓ | ✓ | ✓ |
| Create API keys | ✓ | ✓ | ✓ | | |
| Edit and delete API keys | ✓ | ✓ | | | |
| View API keys | ✓ | ✓ | ✓ | ✓ | ✓ |
| Manage webhooks | ✓ | ✓ | ✓ | | |
| View webhooks | ✓ | ✓ | ✓ | | ✓ |
| Manage project members | ✓ | ✓ | | | |
| Configure and run a CDN deploy | ✓ | ✓ | | | |

"Review / approve translations" is what moves a value to **Translated**. Without it a member
can still save values, and every save lands in Needs Review. Everyone who can comment can
edit and delete their own comments; "Edit anyone's comment" reaches someone else's. Editors
hold "Edit project name, description, AI context" over the REST API, but the dashboard's
**Settings → General** page is reserved for Owners and Managers.

## Project-level overrides

1. Open the project and go to **Settings → Project Access**.

2. Find the member, or use **Add member** if they are not listed.

3. Choose **Change role & languages** in the row menu and set the project role.

The override applies to this project only. A project role cannot exceed the organization
role; the API rejects the attempt with "Project role (x) cannot exceed organization role
(y)". Nobody can grant a role above their own or change their own role. To raise someone's
access, change their organization role first.

The effective role is the first that applies: the project assignment (the lower of it and
the organization role), then the organization role for organization-wide members, then no
access. **Preview impact** in the role dialogs lists the effective permissions before
anything is saved, and the **Audit Log** card on **Organization → Members** records role
changes, invitations and removals.

## Language restrictions

Translators, Editors and Viewers can be restricted to specific languages within a project.
Set them under **Settings → Project Access** with **Change role & languages**; an empty
selection means all languages.

> **Owners and Managers see every language**
>
> Any restriction stored against them is ignored on every permission check, so promoting
> someone to Manager gives them every language.

## Ownership

An organization always keeps at least one Owner. The API refuses to remove or demote the
last one, and refuses to remove an Owner while a paid subscription is linked to the
organization. **Transfer Ownership** on **Organization → Members** hands the role to another
organization-wide member, and the previous Owner becomes a Manager.

## Next steps

- [Translation lifecycle](/docs/platform/translation-lifecycle): which transitions each role can trigger.
- [Team management](/docs/platform/team-management): inviting members and assigning roles.
- [API keys](/docs/platform/api-keys): scopes and the creator intersection.
- [API authentication](/docs/api/authentication): permission scopes per REST endpoint.
