Skip to main content

Authorization

This document describes the authorization model used in Camunda's Orchestration Cluster. It covers the core concepts, data structures, and how they relate to each other.

Overview

Authorization in Camunda controls who can perform what action on which resource. The model is built around three core concepts:

  1. Resource Types -- the kind of entity being protected (e.g. a process definition, a user task, a tenant)
  2. Permission Types -- the action being performed (e.g. read, create, update, delete)
  3. Resource Scoping -- which specific resources the permission applies to (by ID, by property, or wildcard)

These are combined into an Authorization record that represents a single access rule: "this permission type is granted on this resource type for these specific resources."

Core Data Structures

Authorization Record

Location: security/security-core/.../security/auth/Authorization.java

The Authorization<T> record is the central type. It binds together:

FieldTypeDescriptionExample
resourceTypeAuthorizationResourceTypeThe kind of resource being protectedPROCESS_DEFINITION, USER_TASK, TENANT
permissionTypePermissionTypeThe action being authorizedREAD_PROCESS_INSTANCE, CLAIM_USER_TASK, CREATE
resourceIdsList<String>Specific resource IDs access is granted to["my-process-id"] for one process, ["*"] for all
resourceIdSupplierFunction<T, String>Extracts a resource ID from a domain object at runtimeProcessInstanceRecord::getBpmnProcessId
resourcePropertyNamesSet<String>Property-based authorization (e.g. task assignee){"assignee"}, {"candidateUsers", "candidateGroups"}
conditionPredicate<T>Optional predicate that must hold for the authorization to applywithCondition(al -> al.processDefinitionId() != null)
transitivebooleanWhether this authorization is inherited transitivelytrue for process-definition permissions that apply to child process instances

An authorization can grant access in two ways:

  • By resource ID -- the user has access to specific resource instances (identified by ID), or to all instances via the wildcard *.
  • By resource property -- the user has access because a property of the resource matches them (e.g. they are the assignee of a user task).

Authorization Context Keys

Location: zeebe/auth/.../zeebe/auth/Authorization.java

A simpler class that defines constant keys used to propagate authentication context through the system:

ConstantPurpose
AUTHORIZED_ANONYMOUS_USERMarks the request as coming from an anonymous user
AUTHORIZED_TENANTSThe tenants the authenticated user is authorized for
AUTHORIZED_USERNAMEThe authenticated user's username
AUTHORIZED_CLIENT_IDThe authenticated client's ID
USER_TOKEN_CLAIMSClaims extracted from the user's token
USER_GROUPS_CLAIMSGroup claims extracted from the user's token
IS_CAMUNDA_USERS_ENABLEDWhether Camunda-managed users are enabled
IS_CAMUNDA_GROUPS_ENABLEDWhether Camunda-managed groups are enabled

These keys are used to attach identity information to requests so that downstream authorization checks can evaluate permissions.

Resource Types

Location: security/security-protocol/.../AuthorizationResourceType.java

Each resource type declares the set of permission types it supports. The full list:

Resource TypeSupported Permissions
AUDIT_LOGREAD
AUTHORIZATIONCREATE, READ, UPDATE, DELETE
BATCHCREATE, CREATE_BATCH_OPERATION_* (various), READ, UPDATE
CLUSTER_VARIABLECREATE, DELETE, UPDATE, READ
COMPONENTACCESS
DECISION_DEFINITIONCREATE_DECISION_INSTANCE, READ_DECISION_DEFINITION, READ_DECISION_INSTANCE, DELETE_DECISION_INSTANCE
DECISION_REQUIREMENTS_DEFINITIONREAD
DOCUMENTCREATE, READ, DELETE
EXPRESSIONEVALUATE
GLOBAL_LISTENERCREATE_TASK_LISTENER, READ_TASK_LISTENER, UPDATE_TASK_LISTENER, DELETE_TASK_LISTENER
GROUPCREATE, READ, UPDATE, DELETE
MAPPING_RULECREATE, READ, UPDATE, DELETE
MESSAGECREATE, READ
PROCESS_DEFINITIONCREATE_PROCESS_INSTANCE, CLAIM_USER_TASK, READ_PROCESS_DEFINITION, READ_PROCESS_INSTANCE, READ_USER_TASK, UPDATE_PROCESS_INSTANCE, UPDATE_USER_TASK, MODIFY_PROCESS_INSTANCE, COMPLETE_USER_TASK, CANCEL_PROCESS_INSTANCE, DELETE_PROCESS_INSTANCE
RESOURCECREATE, READ, DELETE_DRD, DELETE_FORM, DELETE_PROCESS, DELETE_RESOURCE
ROLECREATE, READ, UPDATE, DELETE
SYSTEMREAD, READ_USAGE_METRIC, READ_JOB_METRIC, UPDATE
TENANTCREATE, READ, UPDATE, DELETE
USERCREATE, READ, UPDATE, DELETE
USER_TASKREAD, UPDATE, CLAIM, COMPLETE

The special value UNSPECIFIED exists as an internal default to catch cases where a resource type was not set.

Authorization Scope

Location: security/security-protocol/.../AuthorizationScope.java

AuthorizationScope defines how a permission is scoped to specific resources:

  • Wildcard (*) -- access to all resources of that type. Uses AuthorizationResourceMatcher.ANY.
  • By ID -- access to a specific resource instance, identified by its ID. Uses AuthorizationResourceMatcher.ID.
  • By Property -- access based on a resource property name (e.g. assignee, candidateUsers, candidateGroups for user tasks). Uses AuthorizationResourceMatcher.PROPERTY.

Property-Based Authorization

For user tasks, authorization can be granted based on the relationship between the authenticated user and the task:

PropertyConstantMeaning
AssigneePROP_ASSIGNEEThe user is assigned to this task
Candidate UsersPROP_CANDIDATE_USERSThe user is a candidate for this task
Candidate GroupsPROP_CANDIDATE_GROUPSThe user belongs to a candidate group for this task

This allows fine-grained access control where users can only see and act on tasks they are directly involved with, without needing explicit per-task authorization rules.

How Authorizations Are Built

The Authorization record provides a fluent builder API. A typical authorization is constructed like:

Authorization.of(b -> b
.processDefinition() // resource type
.readProcessInstance() // permission type
.resourceId("my-process-id") // scoped to a specific resource
);

Or for property-based user task authorization:

Authorization.of(b -> b
.userTask()
.readUserTask()
.authorizedByAssignee()
.or()
.authorizedByCandidateUsers()
.or()
.authorizedByCandidateGroups()
);

Where Authorization Checks Are Applied

Authorization checks happen in two places in the codebase, corresponding to the two storage layers:

  1. Engine Authorization -- checks performed in the Zeebe stream processor before commands are written to RocksDB (primary storage). This is the pre-execution gate that prevents unauthorized state mutations.

  2. REST Layer Authorization -- checks performed in the REST API layer against Elasticsearch/OpenSearch (secondary storage). This handles search result filtering, pre-validation of actions before forwarding to the engine, and permission collection for UI feature toggling.

Both layers use the same underlying authorization model described on this page, but they differ in how they operate:

AspectEngine (AuthorizationCheckBehavior)REST (AuthorizationChecker)
WhenBefore command processingAt query time / before forwarding to engine
Data sourceRocksDB (primary, strongly consistent)Elasticsearch/OpenSearch (secondary, eventually consistent)
Identity resolutionExtracts from command claims, resolves groups/roles/mapping rules from engine stateReceives pre-resolved CamundaAuthentication
Tenant checksBuilt-in multi-tenancy supportHandled separately (not in this class)
CachingGuava LoadingCache with configurable TTLNo caching (relies on search index performance)
Property-based authThree-step cascade with property evaluatorsReturns property scopes for upstream filtering
Internal commandsCan bypass checks for engine-internal commandsNot applicable
Primary useGate state mutationsFilter search results and pre-validate actions

See the individual pages for details.

Relationship to Identity Model

Authorizations are granted to identity entities (users, roles, groups, mapping rules, clients). See Identity documentation for the full data model. The key relationships are:

  • A User, Role, Group, Mapping Rule, or Client can be granted one or more Authorization records.
  • Each Authorization contains one or more Permission entries scoped to specific resources.
  • Roles and groups provide indirect authorization -- a user inherits permissions from their assigned roles and group memberships.