Securing Camunda

Disallow unauthorized access by securing the Camunda Platform before going live with your process applications. Understand Camunda user management essentials, enforce authorization for the REST API, define access rights for Camunda specific resources such as process definitions and consider to integrate with your Single-Sign-On (SSO).
Securing Camunda is also related to
  • Security
  • SSO
  • Authentication
  • Authorization
Securing Camunda

Understanding User Management Essentials

Please also have a look into the security section of the documentation.

Understanding Users, Groups and Tenants

A user refers to a human individual and a group is any custom defined "bundle" of users sharing some usage relevant attributes (like e.g. working on specific business functions). Setup groups corresponding to your workflow roles or create new logical roles for that purpose. Both groups and users can be added to one or more tenants in order to ensure a certain degree data isolation between different logical entities (for more information, see multi-tenancy).

The core of the Camunda engine treats users, groups and tenants as simple text strings. Therefore you can e.g. do things like assigning a user task to a group of people by directly referencing the group in your BPMN file …​

<bpmn:userTask id="Invoice customer" camunda:candidateGroups="finance"/>

…​ or claim that user task for a specific user via the Java API by simply referencing the user with a text string based user id:

taskService.claim(taskId, "fozzie");

No further concepts exist like logical workflow roles or special mappings.

Camunda ships with an IdentityService which allows to either manage real users and groups directly within the Camunda database or access the users and group information managed in a directory service database which supports LDAP ("Lightweight Directory Access Protocol"), like e.g. Microsoft’s "Active Directory" and many others. One can also provide a custom IdentityService implementation to satisfy each and every requirement apart from the default identity service options shipped with Camunda. This is particularly helpful if you plan to integrate with a third party identity management system. Using the IdentityService is not mandatory - it is possible to reference users and groups within Camunda that are not known by the engine’s IdentityService at all. This could be useful for testing purposes or when integrating with third party identity management solutions.

As of Camunda 7.12 the LDAP Identity Service doesn’t support tenants. That means tenant related access restrictions do not work by default when using the LDAP plugin.

Just to illustrate, Camunda needs e.g. access to (text string based) users and groups in order to

  • allow logging into the web applications shipping with it (Camunda Tasklist, Cockpit, …​)

  • allow Tasklist to e.g. present open tasks available for the groups of the logged in user

  • allow Cockpit to e.g. present just the process definitions related to the tenant(s) the logged in user is associated with.

Keep in mind that your custom directory service is decoupled from Camunda. While it is possible to delete users and groups or change memberships in your directory service without harming Camunda’s runtime, the text strings already known to Camunda won’t change without manual intervention.

Understanding Memberships

Camunda’s IdentityService allows to add users to groups - we call this a group membership. Accordingly, adding a user or group to a tenant creates a tenant membership.

Understanding Authentication

The procedure of authentication makes sure that the user is known to the Camunda engine. When directly using Camunda’s Java API, this must be done for each thread by issueing e.g.

identityService.setAuthenticatedUserId("fozzie");
If you use the Java API and do not set the authenticated user, Camunda will not check any authorizations. This is because the engine simply does not know who is logged in. When using the REST API, whether an authentication is set or not depends on the configuration as described below.

Understanding Authorizations

Permissions and restrictions for specific users or groups to access resources within Camunda (such as e.g. process definitions, tenants, process instances) are called authorizations. Because they relate users and groups to Camunda specific resources, they must of course always be managed in a Camunda specific way and be contained in the Camunda database.

Camunda comes with an AuthorizationService API (Java or REST), allowing to manage such Authorizations and also ships with a dedicated Admin application to manage them through a web interface. For example, you might want to give the group "accounting" all rights to access a specific process definition called "invoice":

process definition authorization
While some permissions are requirement specific and should be created during deployment, others are created automatically (e.g. for assigned tasks).

Securing Camunda with Authentication and Authorizations

In order to better understand the consequences and needs when being faced with the task to secure a Camunda installation, it is good to understand the big picture.

security architecture
1 A request is either asking for a REST API enpoint or one of the web applications functionalities.
2 The ProcessEngineAuthenticationFilter (for REST) or the AuthenticationFilter (for the web applications) check the user’s authentication credentials via the IdentityService. The filters retrieve groups and tenant memberships and set the authenticated user for the current thread in the engine.
3 The request is allowed.
4 The request might of course also be denied, in case the authentication fails (e.g. because the username is unknown or the password does not match). For the web applications, a denied request is redirected to the login page.
5 All applications use Camunda’s Java API internally.
6 Under the hood, the engine enforces authorizations by instrumenting SQL querys. That means you can never get any data from a query the current user is not authorized for.
7 As a consequnce, only allowed and accessible data will be presented to the user.

Securing the Camunda Core Engine

You can enable or disable authorization checks for the engine itself. Authorizations will only be checked if you enable authorization checks and tell the engine who is logged in with the current thread:

identityService.setAuthenticatedUserId("fozzie");
If you directly use the API and do not tell the process engine who is logged in with the current thread, it will provide full access to all data!

Authorization is enabled per default in the Camunda distributions, but if you configure and run your own engine (e.g. via Spring), it is disabled by default.

For the authorization checks (to access specific resources), the engine does not question whether the authenticated user is known to the used IdentityService. As mentioned above, the engine treats users, groups and tenants as strings and grants access if those strings match with the defined authorization rules.

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

If you have authorization checks enabled, you might or might not want to perform these checks when you execute Java code as part of your workflow. One example could be loading the number of running process instances to be used for some decision. For this reason, you can enable or disable authorization checks for custom user code seperately.

Securing Camunda’s REST API

Internally, the REST API is just another client for the Java API which needs to inform the engine about the authenticated user. This only works if you turn on authentication for the REST API - otherwise no user is logged in and you have unrestricted access.

Authentication and hence authorization checks are by default disabled for the REST API to allow for a quick getting started experience.

For real life usage, enable at least Basic Authentication for the REST API by adjusting the web.xml as described in the User Guide. The REST API’s default ProcessEngineAuthenticationFilter authenticates the user with HTTP Basic Auth. It makes use of the IdentityService to check the user’s password and to load group and tenant memberships for that user. If that was sucessful, it sets the user as authenticated for the current thread via the Java API.

If you require an authentication mechanism other than HTTP Basic Auth, you need to implement your own AuthenticationFilter. For more details, see the SSO section below.

If you do not need the REST API in production, consider undeploying the REST API web application.

Securing Camunda’s Web Apps

The Camunda web applications (Tasklist, Cockpit, Admin) have by default a form based authentication turned on. There is no further need for changing any configuration when going into production, apart from the more general consideration to enable a custom identity service provider (see below). However, please make sure that you do not deploy artifacts like the h2 console and the example applications in your production environments. They are solely shipped for development purposes and a smooth experience when getting started with Camunda.

Internally, Camunda Web Apps use an AuthenticationFilter very similar to the REST API`s ProcessEngineAuthenticationFilter described above, it just redirects an unknown user to the login page.

Configuring the Identity Service

By default, Camunda will manage users and groups directly within the Camunda database. As an alternative to that, you can also enable read-only access to an LDAP-based user/group repository. The LDAP identity service is implemented as a Process Engine Plugin and can be added to the process engine configuration in order to replace the default database identity service.

As an alternative to those two possibilities, implement a custom IdentityProvider to satisfy each and every other requirement. You can provide read-only or even writable access to your user repository. Note that as of Camunda 7.12 the LDAP Identity Service doesn’t support tenants (multi-tenancy). For multi-tenancy configured via LDAP, you would therefore need a custom identity service allowing you to retrieve tenant IDs from your LDAP.

The identity service ships with a security feature that throttles login attempts. That means that a user will not be able to log in for a specific amount of time after an unsuccessful login attempt. Carefully review the default values for this feature’s configuration and change them to your requirements if needed.

Securing Custom Code

The process engine offers numerous extension points for customization of process behavior by using Java code, expression language, scripts and templates. While these extension points allow for great flexibility in process implementation, they open up the possibility to perform malicious actions when in the wrong hands. It is therefore advisable to restrict access to APIs that allows custom code submission to trusted parties only. Find more information on that topic in the User Guide.

Securing your Web Application Container

Make sure to secure your web application container (e.g. Wildfly or Tomcat) by checking and securing default settings, e.g. by removing any default predefined users allowed to access your container’s administration console.

Bonus  Supporting Single Sign-on (SSO)

The difficulty with Single Sign-on (SSO) is that it always works a bit differently depending on your exact environment and SSO framework used.

Therefore, Camunda only provides the hooks for plugging in the exact mechanism that fits your needs. The key part that you need to touch concerns the authentication filters of Camunda’s web applications and the REST API (see illustration above). The idea is to exchange or modify the AuthenticationFilter defined inside the WEB-INF/web.xml file of Camunda’s web applications (or the REST API) and hook in your custom SSO provider. That means that your filter implementation circumvents the redirect to Camunda’s login page by telling Camunda directly who is currently logged in.

From Camunda 7.9 on, it is much easier to implement SSO by making use of the ContainerBasedAuthenticationFilter. This means that you do not need to replace the existing AuthenticationFilter by a custom one anymore, but you only need to add the ContainerBasedAuthenticationFilter that ships with the product and implement a custom AuthenticationProvider if required.

You can get started by looking at some examples showing how this can be achieved for different authentication frameworks:

No guarantee - The statements made in this publication are recommendations based on the practical experience of the authors. They are not part of Camunda’s official product documentation. Camunda cannot accept any responsibility for the accuracy or timeliness of the statements made. If examples of source code are shown, a total absence of errors in the provided source code cannot be guaranteed. Liability for any damage resulting from the application of the recommendations presented here, is excluded.

Copyright © Camunda Services GmbH - All rights reserved. The disclosure of the information presented here is only permitted with written consent of Camunda Services GmbH.