Limiting Camunda Authorisations with LDAP plugin

Hello everyone, I’m using Camunda 7.21 with the LDAP plugin. However, I have externalized the task list to my custom frontend, so only a small number of admin users are actually involved with Cockpit.

I have noticed that in the authorization tables in the database, a record is created for every single task assigned to a user, granting the user permissions to: READ and TASK_WORK on the task resource with the given ID. Since I have a large number of users and user tasks, when my external task worker invokes fetch and lock, a join is performed on the authorization table, which takes quite a bit of time (the sample below takes about 10 seconds).

Is there a way to avoid, limit, or exclude the creation of permissions on the ACT_RU_AUTHORISATION table for user tasks since I don’t need it?

SELECT SUB.* FROM (     select                               RES.*     , row_number() over (ORDER BY RES.PRIORITY_ desc) rnk FROM ( select distinct RES.*      from (     select RES.*, PI.BUSINESS_KEY_, PD.VERSION_TAG_     from ACT_RU_EXT_TASK RES      left join ACT_RU_EXECUTION PI on RES.PROC_INST_ID_ = PI.ID_     inner join ACT_RE_PROCDEF PD on RES.PROC_DEF_ID_ = PD.ID_                                                   left join      (     SELECT A.*     FROM ACT_RU_AUTHORIZATION A     WHERE A.TYPE_ < 2          AND ( A.USER_ID_ in ( @P0, '*')                        OR A.GROUP_ID_ IN  (  @P1 , @P2 )            )             )                AUTH ON (        (AUTH.RESOURCE_TYPE_ = 8          AND (AUTH.RESOURCE_ID_ IN ( RES.PROC_INST_ID_ , '*' ))            AND AUTH.PERMS_ &2 = 2)       OR        (AUTH.RESOURCE_TYPE_ = 6          AND (AUTH.RESOURCE_ID_ IN ( RES.PROC_DEF_KEY_ , '*' ))          AND AUTH.PERMS_ &512 = 512)        )                                            left join      (     SELECT A.*     FROM ACT_RU_AUTHORIZATION A     WHERE A.TYPE_ < 2          AND ( A.USER_ID_ in ( @P3, '*')                        OR A.GROUP_ID_ IN  (  @P4 , @P5 )            )             )               AUTH1 ON (          (AUTH1.RESOURCE_TYPE_ = 8            AND (AUTH1.RESOURCE_ID_ IN ( RES.PROC_INST_ID_ , '*' ))           AND AUTH1.PERMS_ &4 = 4)                OR          (AUTH1.RESOURCE_TYPE_ = 6            AND (AUTH1.RESOURCE_ID_ IN ( RES.PROC_DEF_KEY_ , '*' ))            AND AUTH1.PERMS_ &1024 = 1024)       )                WHERE (RES.LOCK_EXP_TIME_ is null or RES.LOCK_EXP_TIME_ <= @P6)       and (RES.SUSPENSION_STATE_ is null or RES.SUSPENSION_STATE_ = 1)       and (RES.RETRIES_ is null or RES.RETRIES_ > 0)                and         (           RES.TOPIC_NAME_ = @P7                                                                                                                                                                                                              )                            AND                                 AUTH.RESOURCE_ID_ IS NOT NULL                               AND                                                                                        AUTH1.RESOURCE_ID_ IS NOT NULL                                                                                                                         ) RES           )RES ) SUB WHERE SUB.rnk >= @P8 AND SUB.rnk < @P9 ORDER BY SUB.rnk

Is the join still performed if you access the engine without an authenticated user?

yes, the authentication is done outside of the application via ambassador, yet still the join is executed

That’s interesting. How can an authorization check be performed if the REST call (I assume you use the REST API) does not contain a user info?

I think I still have not understood your setup.

in my setup, the ambassador Is responsible for all the authorisation stuff, based on the headers, it authenticates user (in my case it is the technical user for worker) and attaches jwt token, which is then decoded with the group info of the user and put into the context. in this setup the request to fetch and lock is authenticated same way as a normal user request to rest api, and I do not have a problem with that. The problem is that for every user task, somehow the engine is creating authentication for to the resource, for example:
user A is assigned to task X, so in the ACT_RU_AUTHORIZATION a new record is created that authorises user A to READ and TASK_WORK on task X, now imagine I have 500 tasks per user and around 5000 users. This makes joins on this tables very costly and this affects mostly the executions of fetch and locks of external tasks which also acts as a user, therefore I want to limit the amount of records in the table.

I have already tried to organise all users into a group and gave permission to the group to all resources of type: task, but this still did not prevent the engine to create a separate permission per task per user.

The description is still a bit vage (e.g. what is “ambassador” and “context”), but I can imagine what you are talking about.

as a normal user request to rest api

IMO there is no such thing. REST API is usually called by a machine. What happens if you don’t provide any authentication info along with the REST call? Will the engine still perform DB joins?

As to why an auth entry is made for every assigned task – I’ve never worked with explicitly assigned tasks and can’t tell anything about it. In general, such auths appear sensible: the cockpit will be able to show to a user only the tasks he’s assigned to. If you don’t want them – could you leave tasks unassigned and fetch them based on some other criteria?

Hi @JohnArray

In case you do not require authorizations , make sure that authorization checks are disabled, since they do have a performance impact. You might not need authorizations if you build your own custom web application handling authentication and authorization itself that just uses Camunda in the background, for example.

2 Likes

Hi @hassang,
setting the property described in this doc to false indeed resolved my issue, thank you!

1 Like