IAM: system roles

This guide explains how to use IAM system roles to configure user rights in CVAT.

System roles

Open Policy Agent

CVAT system roles are based on the Open Policy Agent(OPA) microservice having REST API. Thus, CVAT sends HTTP requests (Query) to OPA that replies with “allow” or “deny” in the simplest case (Decision). OPA is the Policy Decision Point (PDP), and it makes decisions, and CVAT is the Policy Enforcement Point (PEP), and enforces these decisions by providing information about requested resources or responding with an error.

OPA provides a high-level declarative language that lets specify the policy as code and simple APIs to offload policy decision-making from software. CVAT controls what queries look like and implements policies to handle them. After a query is processed by OPA in accordance with implemented policies, OPA replies CVAT with its decision.

Rules

In the CVAT repository for each resource there is a CSV file which describes all permissions in a simple and readable form. For example, the users.csv file describes permissions for working with information about users. Every line in the file is a primitive rule which tells us who has rights to perform a specific action.

users.csv

Scope Resource Context Ownership Limit Method URL Privilege Membership
list User N/A N/A GET /users None N/A
view User Sandbox None GET /users/{id} Admin N/A
view User N/A Self GET /users/{id} None N/A
view User Organization None resource["membership"]["role"] != None GET /users/{id} None Worker
update User N/A None PATCH /users/{id} Admin N/A
update User N/A Self PATCH /users/{id} None N/A
delete User N/A None DELETE /users/{id} Admin N/A
delete User N/A Self DELETE /users/{id} None N/A

All CSV files which describe permissions have the same set of columns:

  • Scope is the action which is performed on the resource. For example, list - get the list of users, update - change information about a user, view - get information about a user and so on.

  • Resource describes the object on which the action is performed.

  • Context can take one of two values: sandbox or organization. An object is in the sandbox if it is created outside of any organization. In theory it is possible to make an object in the sandbox visible for other users but let’s skip these details. An organization can have users with different roles and resources. Resources are shared between members of the organization, but each member has permissions in accordance with their role and ownership. If a user creates an object inside an organization, he/she delegates some rights for the object to members with maintainer and owner roles in the organization.

  • Ownership describes how the user and the specific resource are connected together. For example, N/A value means that the property isn’t applicable for the query. Some possible values can be self, owner, assignee, etc. None value means that the user who is making the query doesn’t have any relationships with the resource.

  • Limit covers constraints for the query. They can look not user-friendly in the table above to make it easy for the code generation. This will probably be solved in future releases. Typical constrains are the number of tasks and projects which a regular user can create.

  • Method and URL contain data for information purposes only and are not used. They help to connect rules with the REST API. If a user makes a GET /api/users/1 call, it is easy to locate corresponding permissions in the table. Thus, the scope is view, the resource is user, and the context is sandbox.

  • Privilege corresponds to the group for the current user with the maximum level of permissions. It can be empty if the user doesn’t belong to any groups or equal to worker, user, business, or admin. The primary idea is to delimit the fundamental rights of the user on the platform. For example, users with the privilege less than or equal to worker cannot create tasks and projects. At the same time a user with the maximum privilege admin doesn’t have any restrictions.

  • Membership is the user’s role inside the organization like worker, supervisor, maintainer, or owner. The column makes sense only if a request is made in the context of an organization and allows to delimit access to resources of the organization. For example, if a user has the maintainer role in an organization, but the privilege is worker, he/she will be able to see all resources in the organization but not be able to create tasks and projects in the organization.

If somebody needs to change the default behavior, it is possible to modify the policies defined in .rego files and restart the OPA microservice.

Example of changing rules

By default, CVAT has a system of rules described in the organisation section. But you can change them by editing the csv files in the cvat repository.

Example 1

For example, if you want users with the supervisor role to be able to update in organizations cloud storage edit cloudstorages.csv

cloudstorages.csv

Scope Resource Context Ownership Limit Method URL Privilege Membership
create Storage Sandbox N/A POST /cloudstorages User N/A
create Storage Organization N/A POST /cloudstorages User Maintainer
list Storage Sandbox N/A GET /cloudstorages None N/A
list Storage Organization N/A GET /cloudstorages None Worker
view Storage Sandbox None GET /cloudstorages/{id}, /cloudstorages/{id}/preview, /cloudstorages/{id}/status Admin N/A
view Storage Sandbox Owner GET /cloudstorages/{id}, /cloudstorages/{id}/preview, /cloudstorages/{id}/status None N/A
view Storage Organization Owner GET /cloudstorages/{id}, /cloudstorages/{id}/preview, /cloudstorages/{id}/status None Worker
view Storage Organization None GET /cloudstorages/{id} User Supervisor
update Storage Sandbox None PATCH /cloudstorages/{id} Admin N/A
update Storage Sandbox Owner PATCH /cloudstorages/{id} Worker N/A
update Storage Organization Owner PATCH /cloudstorages/{id} Worker Worker
update Storage Organization None PATCH /cloudstorages/{id} User Maintainer
delete Storage Sandbox None DELETE /cloudstorages/{id} Admin N/A
delete Storage Sandbox Owner DELETE /cloudstorages/{id} Worker N/A
delete Storage Organization Owner DELETE /cloudstorages/{id} Worker Worker
delete Storage Organization None DELETE /cloudstorages/{id} User Maintainer
list:content Storage Sandbox None GET /cloudstorages/{id}/content Admin N/A
list:content Storage Sandbox Owner GET /cloudstorages/{id}/content None N/A
list:content Storage Organization Owner GET /cloudstorages/{id}/content None Worker
list:content Storage Organization None GET /cloudstorages/{id}/content User Supervisor

Example 2

If you want to disable the ability to register new users on your server, edit auth.csv

auth.csv

Scope Resource Context Ownership Limit Method URL Privilege Membership
login N/A N/A N/A POST /auth/login N/A N/A
logout N/A N/A N/A GET, POST /auth/logout N/A N/A
change:password N/A N/A N/A POST, OPTIONS /auth/password/change N/A N/A
reset:password N/A N/A N/A POST, OPTIONS /auth/password/reset, /auth/password/reset/confirm N/A N/A
register N/A N/A N/A POST /auth/register N/A N/A
sign:url N/A N/A N/A POST /auth/signing N/A N/A
confirm:email N/A N/A N/A GET /account-confirm-email/<key> N/A N/A
confirm:email N/A N/A N/A GET, POST register/account-email-verification-sent N/A N/A

Example 3

Prohibit invitations to the organization for everyone except the creator of the organization edit Invitations

invitations.csv

Scope Resource Context Ownership Limit Method URL Privilege Membership
list Invitation Sandbox N/A GET /invitations None N/A
list Invitation Organization N/A GET /invitations None Worker
create Invitation Organization N/A resource["role"] not in ["maintainer", "owner"] POST /invitations User Maintainer
create Invitation Organization N/A resource["role"] != "owner" POST /invitations User Owner
view Invitation Sandbox None GET /invitations/{id} Admin N/A
view Invitation N/A Owner, Invitee GET /invitations/{id} None N/A
view Invitation Organization None GET /invitations/{id} User Maintainer
resend Invitation Sandbox None, Invitee PATCH /invitations/{id} Admin N/A
resend Invitation N/A Owner PATCH /invitations/{id} Worker N/A
resend Invitation Organization None, Invitee PATCH /invitations/{id} User Maintainer
delete Invitation Sandbox None, Invitee DELETE /invitations/{id} Admin N/A
delete Invitation N/A Owner DELETE /invitations/{id} Worker N/A
delete Invitation Organization None, Invitee DELETE /invitations/{id} User Maintainer
accept Invitation N/A None PATCH /invitations/{id} Admin N/A
accept Invitation N/A Invitee PATCH /invitations/{id} None N/A

Rules for other resources

analytics.csv

Scope Resource Context Ownership Limit Method URL Privilege Membership
view Analytics N/A N/A resource['visibility']=='public' GET /analytics business N/A
view Analytics N/A N/A GET /analytics admin N/A

comments.csv

Scope Resource Context Ownership Limit Method URL Privilege Membership
list Comment Sandbox N/A GET /issues/{id}/comments, /comments None N/A
list Comment Organization N/A GET /issues/{id}/comments, /comments None Worker
create@issue Comment, Issue Sandbox N/A POST /comments Admin N/A
create@issue Comment, Issue Sandbox Project:owner, Project:assignee, Task:owner, Task:assignee, Job:assignee, Issue:owner, Issue:assignee POST /comments Worker N/A
create@issue Comment, Issue Organization N/A POST /comments User Maintainer
create@issue Comment, Issue Organization Project:owner, Project:assignee, Task:owner, Task:assignee, Job:assignee, Issue:owner, Issue:assignee POST /comments Worker Worker
view Comment Sandbox N/A GET /comments/{id} Admin N/A
view Comment Sandbox Project:owner, Project:assignee, Task:owner, Task:assignee, Job:assignee, Issue:owner, Issue:assignee, Owner GET /comments/{id} None N/A
view Comment Organization None GET /comments/{id} User Maintainer
view Comment Organization Project:owner, Project:assignee, Task:owner, Task:assignee, Job:assignee, Issue:owner, Issue:assignee, Owner GET /comments/{id} None Worker
update Comment Sandbox N/A PATCH /comments/{id} Admin N/A
update Comment Sandbox Project:owner, Project:assignee, Task:owner, Task:assignee, Job:assignee, Issue:owner, Issue:assignee, Owner PATCH /comments/{id} Worker N/A
update Comment Organization N/A PATCH /comments/{id} User Maintainer
update Comment Organization Project:owner, Project:assignee, Task:owner, Task:assignee, Job:assignee, Issue:owner, Issue:assignee, Owner PATCH /comments/{id} Worker Worker
delete Comment Sandbox None DELETE /comments/{id} Admin N/A
delete Comment Sandbox Project:owner, Project:assignee, Task:owner, Task:assignee, Job:assignee, Issue:owner, Issue:assignee, Owner DELETE /comments/{id} Worker N/A
delete Comment Organization None DELETE /comments/{id} User Maintainer
delete Comment Organization Project:owner, Project:assignee, Task:owner, Task:assignee, Job:assignee, Issue:owner, Issue:assignee, Owner DELETE /comments/{id} Worker Worker

issues.csv

Scope Resource Context Ownership Limit Method URL Privilege Membership
list Issue Sandbox N/A GET /jobs/{id}/issues, /issues None N/A
list Issue Organization N/A GET /jobs/{id}/issues, /issues None Worker
create@job Issue, Job Sandbox N/A POST /issues Admin N/A
create@job Issue, Job Sandbox Project:owner, Project:assignee, Task:owner, Task:assignee, Job:assignee POST /issues Worker N/A
create@job Issue, Job Organization N/A POST /issues User Maintainer
create@job Issue, Job Organization Project:owner, Project:assignee, Task:owner, Task:assignee, Job:assignee POST /issues Worker Worker
view Issue Sandbox N/A GET /issues/{id} Admin N/A
view Issue Sandbox Project:owner, Project:assignee, Task:owner, Task:assignee, Job:assignee, Owner, Assignee GET /issues/{id} None N/A
view Issue Organization N/A GET /issues/{id} User Maintainer
view Issue Organization Project:owner, Project:assignee, Task:owner, Task:assignee, Job:assignee, Owner, Assignee GET /issues/{id} None Worker
update Issue Sandbox N/A PATCH /issues/{id} Admin N/A
update Issue Sandbox Project:owner, Project:assignee, Task:owner, Task:assignee, Owner PATCH /issues/{id} Worker N/A
update Issue Organization N/A PATCH /issues/{id} User Maintainer
update Issue Organization Project:owner, Project:assignee, Task:owner, Task:assignee, Owner PATCH /issues/{id} Worker Worker
delete Issue Sandbox N/A DELETE /issues/{id} Admin N/A
delete Issue Sandbox Project:owner, Project:assignee, Task:owner, Task:assignee, Owner DELETE /issues/{id} Worker N/A
delete Issue Organization N/A DELETE /issues/{id} User Maintainer
delete Issue Organization Project:owner, Project:assignee, Task:owner, Task:assignee, Owner DELETE /issues/{id} Worker Worker

jobs.csv

Scope Resource Context Ownership Limit Method URL Privilege Membership
list N/A Sandbox N/A GET /tasks/{id}/jobs None N/A
list N/A Organization N/A GET /tasks/{id}/jobs None Worker
view Job Sandbox None GET /jobs/{id} Admin N/A
view Job Sandbox Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee GET /jobs/{id} None N/A
view Job Organization None GET /jobs/{id} User Maintainer
view Job Organization Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee GET /jobs/{id} None Worker
update:stage Job Sandbox None, Assignee PATCH /jobs/{id} Admin N/A
update:stage Job Sandbox Project:owner, Project:assignee, Task:owner, Task:assignee PATCH /jobs/{id} Worker N/A
update:stage Job Organization None, Assignee PATCH /jobs/{id} User Maintainer
update:stage Job Organization Project:owner, Project:assignee, Task:owner, Task:assignee PATCH /jobs/{id} Worker Worker
update:state Job Sandbox None PATCH /jobs/{id} Admin N/A
update:state Job Sandbox Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee PATCH /jobs/{id} Worker N/A
update:state Job Organization None PATCH /jobs/{id} User Maintainer
update:state Job Organization Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee PATCH /jobs/{id} Worker Worker
update:assignee Job Sandbox None, Assignee PATCH /jobs/{id} Admin N/A
update:assignee Job Sandbox Project:owner, Project:assignee, Task:owner, Task:assignee PATCH /jobs/{id} Worker N/A
update:assignee Job Organization None, Assignee PATCH /jobs/{id} User Maintainer
update:assignee Job Organization Project:owner, Project:assignee, Task:owner, Task:assignee PATCH /jobs/{id} Worker Worker
view:annotations Job Sandbox None GET /jobs/{id}/annotations Admin N/A
view:annotations Job Sandbox Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee GET /jobs/{id}/annotations None N/A
view:annotations Job Organization None GET /jobs/{id}/annotations User Maintainer
view:annotations Job Organization Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee GET /jobs/{id}/annotations None Worker
update:annotations Job Sandbox None PATCH /jobs/{id}/annotations Admin N/A
update:annotations Job Sandbox Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee PATCH /jobs/{id}/annotations Worker N/A
update:annotations Job Organization None PATCH /jobs/{id}/annotations User Maintainer
update:annotations Job Organization Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee PATCH /jobs/{id}/annotations Worker Worker
delete:annotations Job Sandbox None DELETE /jobs/{id}/annotations Admin N/A
delete:annotations Job Sandbox Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee DELETE /jobs/{id}/annotations Worker N/A
delete:annotations Job Organization None DELETE /jobs/{id}/annotations User Maintainer
delete:annotations Job Organization Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee DELETE /jobs/{id}/annotations Worker Worker
view:data Job Sandbox None GET /jobs/{id}/data Admin N/A
view:data Job Sandbox Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee GET /jobs/{id}/data None N/A
view:data Job Organization None GET /jobs/{id}/data User Maintainer
view:data Job Organization Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee GET /jobs/{id}/data None Worker
view:commits Job Sandbox None GET /jobs/{id}/commits Admin N/A
view:commits Job Sandbox Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee GET /jobs/{id}/commits None N/A
view:commits Job Organization None GET /jobs/{id}/commits User Maintainer
view:commits Job Organization Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee GET /jobs/{id}/commits None Worker
import:annotations Job Sandbox None PUT /jobs/{id}/annotations?format= Admin N/A
import:annotations Job Sandbox Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee PUT /jobs/{id}/annotations?format= Worker N/A
import:annotations Job Organization None PUT /jobs/{id}/annotations?format= User Maintainer
import:annotations Job Organization Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee PUT /jobs/{id}/annotations?format= Worker Worker

lambda.csv

Scope Resource Context Ownership Limit Method URL Privilege Membership
list N/A N/A N/A GET /lambda/functions None N/A
view LambdaFunction N/A N/A GET /lambda/functions/{func_id} None N/A
call:online LambdaFunction, Job N/A N/A POST /lambda/functions/{func_id} Worker N/A
call:offline LambdaFunction, Task N/A N/A POST /lambda/requests Business N/A
call:offline LambdaFunction, Task N/A N/A GET /lambda/requests/{id}, /lambda/requests Business N/A

memberships.csv

Scope Resource Context Ownership Limit Method URL Privilege Membership
list Membership Sandbox N/A GET /memberships None N/A
list Membership Organization N/A GET /memberships None Worker
view Membership Sandbox None GET /membership/{id} Admin N/A
view Membership Sandbox Self GET /membership/{id} None N/A
view Membership Organization None, Self GET /membership/{id} None Worker
change:role Membership Organization None, Self resource["role"] not in ["maintainer", "owner"] PATCH /membership/{id} User Maintainer
change:role Membership Organization None, Self resource["role"] != "owner" PATCH /membership/{id} User Owner
delete Membership Organization None, Self resource["role"] not in ["maintainer", "owner"] DELETE /membership/{id} User Maintainer
delete Membership Organization None, Self resource["role"] != "owner" DELETE /membership/{id} User Owner
delete Membership Sandbox Self resource["role"] != "owner" DELETE /membership/{id} Worker N/A

organizations.csv

Scope Resource Context Ownership Limit Method URL Privilege Membership
create Organization N/A N/A resource["user"]["num_resources"] < 1 POST /organizations User N/A
create Organization N/A N/A POST /organizations Business N/A
list N/A N/A N/A GET /organizations None N/A
view Organization N/A Worker, Supervisor, Maintainer, Owner GET /organizations/{id} None N/A
view Organization N/A None GET /organizations/{id} Admin N/A
update Organization N/A Owner, Maintainer PATCH /organizations/{id} Worker N/A
update Organization N/A None, Worker, Supervisor PATCH /organizations/{id} Admin N/A
delete Organization N/A Owner DELETE /organizations/{id} Worker N/A
delete Organization N/A None, Worker, Supervisor, Maintainer DELETE /organizations/{id} Admin N/A

projects.csv

Scope Resource Context Ownership Limit Method URL Privilege Membership
create Project Sandbox N/A resource['user']['num_resources'] < 3 POST /projects User N/A
create Project Organization N/A resource['user']['num_resources'] < 3 POST /projects User Supervisor
create Project Sandbox N/A POST /projects Business N/A
create Project Organization N/A POST /projects Business Supervisor
import:backup Project Sandbox N/A resource['user']['num_resources'] < 3 POST /projects/backup User N/A
import:backup Project Organization N/A resource['user']['num_resources'] < 3 POST /projects/backup User Supervisor
import:backup Project Sandbox N/A POST /projects/backup Business N/A
import:backup Project Organization N/A POST /projects/backup Business Supervisor
list N/A Sandbox N/A GET /projects None N/A
list N/A Organization N/A GET /projects None Worker
view Project Sandbox None GET /projects/{id}, /projects/{id}/tasks Admin N/A
view Project Sandbox Owner, Assignee GET /projects/{id}, /projects/{id}/tasks None N/A
view Project Organization None GET /projects/{id}, /projects/{id}/tasks User Maintainer
view Project Organization Owner, Assignee GET /projects/{id}, /projects/{id}/tasks None Worker
delete Project Sandbox None, Assignee DELETE /projects/{id} Admin N/A
delete Project Sandbox Owner DELETE /projects/{id} Worker N/A
delete Project Organization Owner DELETE /projects/{id} Worker Worker
delete Project Organization None, Assignee DELETE /projects/{id} User Maintainer
update:desc Project Sandbox None PATCH /projects/{id} Admin N/A
update:desc Project Sandbox Owner, Assignee PATCH /projects/{id} Worker N/A
update:desc Project Organization Owner, Assignee PATCH /projects/{id} Worker Worker
update:desc Project Organization None PATCH /projects/{id} User Maintainer
update:assignee Project, User Sandbox None, Assignee PATCH /projects/{id} Admin N/A
update:assignee Project, User Sandbox Owner PATCH /projects/{id} Worker N/A
update:assignee Project, User Organization Owner PATCH /projects/{id} Worker Worker
update:assignee Project, User Organization None, Assignee PATCH /projects/{id} User Maintainer
update:owner Project, User Sandbox None, Assignee, Owner PATCH /projects/{id} Admin N/A
update:owner Project, User Organization None, Assignee PATCH /projects/{id} User Maintainer
update:owner Project, User Organization Owner PATCH /projects/{id} Worker Maintainer
export:annotations Project Sandbox None GET /projects/{id}/annotations Admin N/A
export:annotations Project Sandbox Owner, Assignee GET /projects/{id}/annotations None N/A
export:annotations Project Organization Owner, Assignee GET /projects/{id}/annotations None Worker
export:annotations Project Organization None GET /projects/{id}/annotations User Maintainer
export:dataset Project Sandbox None GET /projects/{id}/dataset Admin N/A
export:dataset Project Sandbox Owner, Assignee GET /projects/{id}/dataset None N/A
export:dataset Project Organization Owner, Assignee GET /projects/{id}/dataset None Worker
export:dataset Project Organization None GET /projects/{id}/dataset User Maintainer
import:dataset Project Sandbox None POST /projects/{id}/dataset Admin N/A
import:dataset Project Sandbox Owner, Assignee POST /projects/{id}/dataset Worker N/A
import:dataset Project Organization Owner, Assignee POST /projects/{id}/dataset Worker Worker
import:dataset Project Organization None POST /projects/{id}/dataset User Maintainer
export:backup Project Sandbox None GET /projects/{id}/backup Admin N/A
export:backup Project Sandbox Owner, Assignee GET /projects/{id}/backup None N/A
export:backup Project Organization Owner, Assignee GET /projects/{id}/backup None Worker
export:backup Project Organization None GET /projects/{id}/backup User Maintainer
update:organization Project, Organization Sandbox None, Assignee PATCH /projects/{id} Admin N/A
update:organization Project, Organization Sandbox Owner PATCH /projects/{id} Worker N/A
update:organization Project, Organization Organization None, Assignee PATCH /projects/{id} User Maintainer
update:organization Project, Organization Organization Owner PATCH /projects/{id} Worker Worker

restrictions.csv

Scope Resource Context Ownership Limit Method URL Privilege Membership
view:user-agreements N/A N/A N/A POST /restrictions/user-agreements N/A N/A
view:terms-of-use N/A N/A N/A GET /restrictions/terms-of-use N/A N/A

server.csv

Scope Resource Context Ownership Limit Method URL Privilege Membership
view N/A N/A N/A GET /server/about, /server/annotation/formats, /server/plugins None N/A
send:exception N/A N/A N/A POST /server/exception None N/A
send:logs N/A N/A N/A POST /server/logs None N/A
list:content N/A N/A N/A GET /server/share Worker N/A

tasks.csv

Scope Resource Context Ownership Limit Method URL Privilege Membership
create Task Sandbox None resource['user']['num_resources'] < 10 POST /tasks User N/A
create Task Organization None resource['user']['num_resources'] < 10 POST /tasks User Supervisor
create Task Sandbox None POST /tasks Business N/A
create Task Organization None POST /tasks Business Supervisor
import:backup Task Sandbox None resource['user']['num_resources'] < 10 POST /tasks/backup User N/A
import:backup Task Organization None resource['user']['num_resources'] < 10 POST /tasks/backup User Supervisor
import:backup Task Sandbox None POST /tasks/backup Business N/A
import:backup Task Organization None POST /tasks/backup Business Supervisor
create@project Task, Project Sandbox None POST /tasks Admin N/A
create@project Task, Project Sandbox Project:owner, Project:assignee resource['user']['num_resources'] < 10 POST /tasks User N/A
create@project Task, Project Organization None resource['user']['num_resources'] < 10 POST /tasks User Supervisor
create@project Task, Project Organization Project:owner, Project:assignee resource['user']['num_resources'] < 10 POST /tasks User Worker
create@project Task, Project Sandbox Project:owner, Project:assignee POST /tasks Business N/A
create@project Task, Project Organization None POST /tasks Business Supervisor
create@project Task, Project Organization Project:owner, Project:assignee POST /tasks Business Worker
view Task Sandbox None GET /tasks/{id}, /tasks/{id}/status Admin N/A
view Task Sandbox Owner, Project:owner, Assignee, Project:assignee GET /tasks/{id}, /tasks/{id}/status None N/A
view Task Organization None GET /tasks/{id}, /tasks/{id}/status User Maintainer
view Task Organization Owner, Project:owner, Assignee, Project:assignee GET /tasks/{id}, /tasks/{id}/status None Worker
list N/A Sandbox N/A GET /tasks None N/A
list N/A Organization N/A GET /tasks None Worker
update:desc Task Sandbox None PATCH /tasks/{id} Admin N/A
update:desc Task Sandbox Owner, Project:owner, Assignee, Project:assignee PATCH /tasks/{id} Worker N/A
update:desc Task Organization None PATCH /tasks/{id} User Maintainer
update:desc Task Organization Owner, Project:owner, Assignee, Project:assignee PATCH /tasks/{id} Worker Worker
update:owner Task, User Sandbox None, Assignee PATCH /tasks/{id} Admin N/A
update:owner Task, User Sandbox Owner, Project:owner, Project:assignee PATCH /tasks/{id} Worker N/A
update:owner Task, User Organization None, Assignee PATCH /tasks/{id} User Maintainer
update:owner Task, User Organization Owner, Project:owner, Project:assignee PATCH /tasks/{id} Worker Worker
update:assignee Task, User Sandbox None, Assignee PATCH /tasks/{id} Admin N/A
update:assignee Task, User Sandbox Owner, Project:owner, Project:assignee PATCH /tasks/{id} Worker N/A
update:assignee Task, User Organization None, Assignee PATCH /tasks/{id} User Maintainer
update:assignee Task, User Organization Owner, Project:owner, Project:assignee PATCH /tasks/{id} Worker Worker
update:project Task, Project Sandbox None, Assignee PATCH /tasks/{id} Admin N/A
update:project Task, Project Sandbox Owner, Project:owner, Project:assignee PATCH /tasks/{id} Worker N/A
update:project Task, Project Organization None, Assignee PATCH /tasks/{id} User Maintainer
update:project Task, Project Organization Owner, Project:owner, Project:assignee PATCH /tasks/{id} Worker Worker
delete Task Sandbox None, Assignee DELETE /tasks/{id} Admin N/A
delete Task Sandbox Owner, Project:owner, Project:assignee DELETE /tasks/{id} Worker N/A
delete Task Organization None, Assignee DELETE /tasks/{id} User Maintainer
delete Task Organization Owner, Project:owner, Project:assignee DELETE /tasks/{id} Worker Worker
view:annotations Task Sandbox None GET /tasks/{id}/annotations Admin N/A
view:annotations Task Sandbox Owner, Project:owner, Assignee, Project:assignee GET /tasks/{id}/annotations None N/A
view:annotations Task Organization None GET /tasks/{id}/annotations User Maintainer
view:annotations Task Organization Owner, Project:owner, Assignee, Project:assignee GET /tasks/{id}/annotations None Worker
update:annotations Task Sandbox None PATCH, PUT /tasks/{id}/annotations Admin N/A
update:annotations Task Sandbox Owner, Project:owner, Assignee, Project:assignee PATCH, PUT /tasks/{id}/annotations Worker N/A
update:annotations Task Organization None PATCH, PUT /tasks/{id}/annotations User Maintainer
update:annotations Task Organization Owner, Project:owner, Assignee, Project:assignee PATCH, PUT /tasks/{id}/annotations Worker Worker
delete:annotations Task Sandbox None DELETE /tasks/{id}/annotations Admin N/A
delete:annotations Task Sandbox Owner, Project:owner, Assignee, Project:assignee DELETE /tasks/{id}/annotations Worker N/A
delete:annotations Task Organization None DELETE /tasks/{id}/annotations User Maintainer
delete:annotations Task Organization Owner, Project:owner, Assignee, Project:assignee DELETE /tasks/{id}/annotations Worker Worker
export:dataset Task Sandbox None GET /tasks/{id}/dataset?format= Admin N/A
export:dataset Task Sandbox Owner, Project:owner, Assignee, Project:assignee GET /tasks/{id}/dataset?format= None N/A
export:dataset Task Organization None GET /tasks/{id}/dataset?format= User Maintainer
export:dataset Task Organization Owner, Project:owner, Assignee, Project:assignee GET /tasks/{id}/dataset?format= None Worker
view:data Task Sandbox None GET /tasks/{id}/data, /tasks/{id}/data/meta Admin N/A
view:data Task Sandbox Owner, Project:owner, Assignee, Project:assignee GET /tasks/{id}/data, /tasks/{id}/data/meta None N/A
view:data Task Organization None GET /tasks/{id}/data, /tasks/{id}/data/meta User Maintainer
view:data Task Organization Owner, Project:owner, Assignee, Project:assignee GET /tasks/{id}/data, /tasks/{id}/data/meta None Worker
upload:data Task Sandbox None POST /tasks/{id}/data Admin N/A
upload:data Task Sandbox Owner, Project:owner, Assignee, Project:assignee POST /tasks/{id}/data Worker N/A
upload:data Task Organization None POST /tasks/{id}/data User Maintainer
upload:data Task Organization Owner, Project:owner, Assignee, Project:assignee POST /tasks/{id}/data Worker Worker
import:annotations Task Sandbox None PUT /tasks/{id}/annotations?format= Admin N/A
import:annotations Task Sandbox Owner, Project:owner, Assignee, Project:assignee PUT /tasks/{id}/annotations?format= Worker N/A
import:annotations Task Organization None PUT /tasks/{id}/annotations?format= User Maintainer
import:annotations Task Organization Owner, Project:owner, Assignee, Project:assignee PUT /tasks/{id}/annotations?format= Worker Worker
export:annotations Task Sandbox None GET /tasks/{id}/annotations?format= Admin N/A
export:annotations Task Sandbox Owner, Project:owner, Assignee, Project:assignee GET /tasks/{id}/annotations?format= None N/A
export:annotations Task Organization None GET /tasks/{id}/annotations?format= User Maintainer
export:annotations Task Organization Owner, Project:owner, Assignee, Project:assignee GET /tasks/{id}/annotations?format= None Worker
export:backup Task Sandbox None GET /tasks/{id}/backup Admin N/A
export:backup Task Sandbox Owner, Project:owner, Assignee, Project:assignee GET /tasks/{id}/backup None N/A
export:backup Task Organization None GET /tasks/{id}/backup User Maintainer
export:backup Task Organization Owner, Project:owner, Assignee, Project:assignee GET /tasks/{id}/backup None Worker
update:organization Task, Organization Sandbox None, Assignee PATCH /tasks/{id} Admin N/A
update:organization Task, Organization Sandbox Owner, Project:owner, Project:assignee PATCH /tasks/{id} Worker N/A
update:organization Task, Organization Organization None, Assignee PATCH /tasks/{id} User Maintainer
update:organization Task, Organization Organization Owner, Project:owner, Project:assignee PATCH /tasks/{id} Worker Worker