Task authorization
This page explains which user tasks a person may see and act on. The rules are the same in Embedded, Bundled and Cluster mode, because all three use the same code.
A task’s own fields decide who may see it: its assignee, its candidate users and its candidate groups. This is called user-task property authorization, and it is part of the permission model.
- The permissions
task:adminandtask:assigncan come from a role, a static credential or a grant (onUSER_TASK *or on a process definition). - Group memberships stored in the engine count as candidate groups.
- A grant of a task permission on one process limits that permission to the tasks of that process.
Two checks, in order
Section titled “Two checks, in order”- The route check. The caller (by token, single sign-on or session)
needs the route’s permission:
task:readto list or read,task:claimto claim, andtask:unclaim,task:updateortask:completefor those actions. On/v1,/assignmentneedstask:assign. On/v2,POST /v2/user-tasks/{key}/assignmentneedstask:claim, because assigning a task to yourself is a claim; assigning it to anybody else also needstask:assign(see below). A missing permission is403before anything is read. - The task check. It runs on the task itself, before the request body is validated and before anything is written.
Which tasks a human principal sees
Section titled “Which tasks a human principal sees”A principal is whoever makes the request: a person or a client. A task is visible and actionable when the principal belongs to the task’s tenant and any of these holds:
| Rule | Example |
|---|---|
The principal holds task:admin or * | a team lead with task:admin sees every task of the tenant |
| The task’s assignee names the principal | alice sees tasks assigned to alice |
One of the task’s candidateUsers names the principal | candidateUsers="alice, bob" |
One of the principal’s groups is one of the task’s candidateGroups | the principal’s groups claim contains shipping, the task has candidateGroups="shipping" |
| The task has no assignee and no candidates at all | an unrestricted task is open to everyone in the tenant who may read tasks |
A stored grant of task:read or task:admin names the task (USER_TASK with the task key) | a grant of task:read on USER_TASK 2251799813685290 shows that one task |
A stored grant of task:read or task:admin names the task’s process (PROCESS_DEFINITION with the BPMN process id) | a grant of task:admin on PROCESS_DEFINITION invoice shows every task of invoice |
The last two rules widen visibility only through grants that name a task
or a process. A task:read held on every resource (from a role such as
task-worker, a static credential, or a USER_TASK * grant) is what every
task worker has, so it widens nothing; a task:admin held on every resource
is the first rule and shows the whole tenant.
A name names a person of the identity provider it says: alice and
alice@local are alice of the default provider (local here), alice@corp
is alice of the provider corp, who is someone else and sees none of the
first alice’s tasks (see
Who a person is). A person keeps
the tasks named by a username their provider has since changed.
Groups are read from the principal’s groups claim. OIDC mapping rules put
them there (see Identity and access).
A static credential (CONDUCTOR_AUTH_CREDENTIALS_JSON) carries no claims. So a
static user credential sees only tasks assigned to it, tasks that name it
as a candidate user, and unrestricted tasks, unless it has task:admin.
Once a task is assigned to someone else, it stays visible only to candidates
and administrators. A task assigned to bob with no candidates disappears
from alice’s list.
Claiming for someone else
Section titled “Claiming for someone else”Claiming or assigning a task to anyone other than oneself also needs
task:assign. alice may claim a visible task for alice (or alice@local,
the same person). Claiming it for bob, or for alice@corp, is 403
unless alice holds task:assign. Taking over a task that
is assigned to somebody else (an assignment that replaces the current
assignee) needs task:assign too, even when alice assigns it to herself.
task:admin makes every task visible but does not grant task:assign.
Completing a task that is assigned to somebody else, or returning it to the
pool, is acting on their work: it needs task:assign too. A candidate who
sees a task bob has claimed can read it, but only bob (or someone with
task:assign) can complete or unclaim it. An unassigned task is completed
by anyone who can see it and holds task:complete. Update needs only the
route permission and a visible task.
403 or 404
Section titled “403 or 404”| Situation | Answer |
|---|---|
| Missing route permission | 403 urn:bpm:error:forbidden |
| Task invisible to the principal (other people’s task, other tenant) | 404 urn:bpm:error:not-found, byte-identical to a task that does not exist |
Task visible, but claiming or assigning to someone else without task:assign | 403 with detail claiming or assigning a task to another subject requires task:assign |
Task visible, but taking over somebody else’s assignment without task:assign | 403 with detail taking over a task assigned to someone else requires task:assign |
Task visible, but completing somebody else’s task without task:assign | 403 with detail completing a task assigned to someone else requires task:assign |
Task visible, but unclaiming somebody else’s task without task:assign | 403 with detail returning a task assigned to someone else to the pool requires task:assign |
A claim (allowOverride: false on /v2) of a task that is already assigned | 409 urn:bpm:error:invalid-state |
The 404 is deliberate: a principal can’t learn that somebody else’s task exists.
Lists are filtered on the server
Section titled “Lists are filtered on the server”POST /v2/user-tasks/search, POST /v1/user-tasks/search (and
/api/v1/user-tasks/search) only ever return visible tasks. Cluster mode adds
the visibility rule to its database query, so page sizes, cursors and
totalItems count visible rows only. Embedded and Bundled mode apply the
same rule before paging. A filter can’t widen visibility: bob searching for
candidateGroup=shipping gets an empty page.
Every other /v2/user-tasks/{key} operation (read, form, variables, effective
variables, audit log, and the commands) answers an invisible task with the
same 404 as a missing one. See
Building an external task list for the whole API.
Service principals and anonymous engines
Section titled “Service principals and anonymous engines”- Service principals (
kind: service, for machines) get only the route check. They see every task of their tenant and may claim for anyone the route allows. Job workers and integrations are not affected by task-level rules. - An engine without authentication (
CONDUCTOR_ALLOW_ANONYMOUS=1, loopback only) has no principal to decide for. It applies no task-level rule. - Bundled’s generated first-boot token is the
operatoruser with*, so it sees and acts on every task.
Who did it
Section titled “Who did it”Every user-task command records who did it: who claimed, who assigned on
whose behalf, who completed. Every mode stores this with the command, and
Bundled mode keeps it across restarts. Read it back with
GET /v1/audit-log (see Audit log API).
What these rules do not cover
Section titled “What these rules do not cover”- The console’s operations history read (
/api/v1/history/user-tasks/search) is an operator view gated byhistory:read. The task-level rules do not filter it. - Which processes a principal may work on at all: that is decided by grants
on
PROCESS_DEFINITIONorUSER_TASKresources, managed in the console’s Access area (see Permissions). The task rules above then decide per task. - Tenants: a principal that may act in several tenants sees the tasks of the
tenant it selects with
X-Tenant-Id, one tenant per request.