LDAP sync tools
DEPRECATED
The LDAP Sync tool can be used but it is not maintained and we don't offer support. It has been deprecated in favor of Just-In-Time Provisioning via SAML
LDAP (Lightweight Directory Access Protocol) is an application protocol for querying and modifying items in directory service providers like Active Directory (AD), which supports a form of LDAP.
Active Directory is a directory services database, and LDAP is one of the protocols you can use to talk to it.
In LDAP, directory entries are arranged in a hierarchical tree-like structure.

For a comprehensive overview, refer to the Wikipedia articles about LDAP and Active Directory.
Synchronizing Active Directory members with your team in Celonis Execution Management System
Synchronization of AD with the Celonis EMS creates accounts in the EMS team and allows people to log in via SSO, or can facilitate provisioning accounts for a large number of users. Without an account on the team, a user will not be able to use SSO.
The tool with which to accomplish this is documented here. A regular sync (e.g. via cron job installed on the customer side) will automatically sync new users that correspond to the LDAP search filter to the Celonis EMS user database and add them to the team. Users who are not part of the sync anymore (e.g. because they left the company or changed departments) will automatically be removed from the team. If an LDAP sync is set up after team members have already been invited to the team, the Celonis EMS will check if the email addresses of the newly synced users are already part of the team. If that is the case, the status of this user will change from “manually managed” to “managed by LDAP sync”.
Permission Handling
The best way to assign permissions is to assign the permissions not to individual team members directly but to the groups they belong to. This way, a new-joiner on the customer side who is synced via LDAP for the first time to Celonis EMS will automatically inherit the right permission profile from the LDAP group into which he or she was synced.
Manually managed users and groups vs. LDAP managed users and groups
Users & groups who were synced via LDAP are also managed by the LDAP sync. The reason for this is that any manual changes performed by the Team Admin would be undone with the next LDAP sync: e.g. the team admin manually removes a member from a specific group in the team and the next LDAP sync would add this user to the same group again.
A team admin will still be able to manually invite team members (whose email addresses are currently not included in the LDAP sync load) and create groups. The manually created team members & groups can then be fully managed by the team admin

How does Single Sign-On work in combination with LDAP?
In order to easily administrate users, groups and permissions, it is highly recommended to set up an LDAP sync in combination with a SSO configuration.
This is an overview of the complete setup of SSO (SAML) and LDAP for a given Team:

Step | Description |
---|---|
Users and groups are synchronized to Celonis EMS user database via LDAP sync | |
1 | LDAP-client.jar pulls from active directory users and groups that fit the search criteria defined in the yml file |
2 | LDAP-client.jar pushes these users & groups to Celonis EMS |
User log in via SAML (SSO) | |
3 | The user tries to log in to the Customers Celonis EMS Team; if SAML has been configured for the team: |
4 | Celonis EMS responds by generating a SAML request and redirect request to IdP |
5 | The browser redirects the user to an SSO URL with Identity Provider (IdP); IdP parses the SAML request |
6 | IdP authenticates the user (this could be via username and password or even a two-factor authentication; if the user is already authenticated with IdP and has an active IdP session, login with IdP will be skipped) and generates a SAML response. |
7 | IdP returns the SAML response to the browser. IdP triggers redirect to callback URL of Celonis EMS Service provider and sends SAML response for verification. |
8 | Browser executes the redirect that has been initiated and passes SAML response to Celonis EMS |
9 | Service Provider verifies on user database that user is part of the team (based on email address) |
10 | Service Provider verifies on user database that user is part of the team (based on email address) |
Tool setup and documentation
Please try SAML JIT in conjunction with the Member Locking policy first. The download has been removed.
If you find that it does not work for you, please ask servicedesk@celonis.com for the LDAP sync file.
Warning
Dreprecated: The LDAP Sync tool can be used but it is not maintained and we don't offer support. It has been deprecated in favor of Just-In-Time Provisioning via SAML
Download the jar file and the YML file used for the LDAP connection.s
Open the directory containing the LDAP client package in a terminal.
Add the configuration described below into a file
application.yml
and save it next to the LDAP client package.Test your configuration by running:
java -jar ibc-ldap-sync-<VERSION>.jar
This will tell you which users are picked up and which changes would be made to the team in the following step.
Please replace <Version> with the version number of your LDAP Client package. This will fetch and print the data from the LDAP server, without pushing it to the Celonis EMS.
Once you have verified your configuration is correct, run the following to execute the full user and group synchronization:
java -jar ibc-ldap-sync-<VERSION>.jar --live-action
Warning
All newly synced users must confirm their e-mail address, i.e. they will receive an e-mail.
You can configure the two ways for this to happen:
All users receive an email when they are synchronized - resulting in a large one-time wave
Users confirm their email on their first login - spreading out the e-mail volume over time
Data processing flow
The client queries the Active Directory via two LDAP queries. Each query delivers a set of users, and the intersection of both sets is synchronized to the team. This section briefly describes the technical reasoning behind this approach, as LDAP is an old protocol in technology terms.
For each run of the ldap-client sync, two queries are run.
The user query acquires all users matching the query in the configuration
The returned user object gets mapped with the appropriate attributes according to the mapping section of the configuration, e.g.: the user_id in the directory server is to be mapped to the user dn
The same flow happens for the groups' queries.
The flow would diverge when include-nested-membership config option is toggled, as this will make sure that any group queried will have all its children included for linking with the memberships of the users returned in the user query.
Any additional groups added by the previous step are removed from the final groups' results.
Key takeaway
In short, the intersection of the user memberships & group sets returned by the user and group queries is synced. A user membership not contained in both sets will not be synced.
Limitations
Our LDAP client queries on-site Active Directories (ADs). These ADs can be from numerous vendors, and thus implement different features of the extensive range of LDAP commands.
We try to make our client as universally applicable as possible. However, in the interest of query performance, the client has the following behavioral characteristics:
The client assumes that the server supports the
member-of
attribute and has it enabled.Note
Any data inserted before enabling the member-of on directory-server won't contain the member-of attribute.
Queries expecting nesting in the results are supported only server-side by the CHAIN support control with OID:
1.2.840.113556.1.4.1941
Note
If the server doesn't respond with that OID included in the list of supported controls, it's assumed that the server doesn't support the support control. If that is a wrong assumption, then it should be added to the query supplied in the config YML file.
A sanity check on the queries result is done, to make sure that the memberships array of each user contains valid group ids, otherwise, the membership is discarded.
Usage of option include-nested-memberships can only result in expected behavior if the following is supported:
Group nesting is supported (ie. groups can be members of other groups).
Recursive
memberof
querying is supported by the serverExample: Using
memberof:
1.2.840.113556.1.4.1941:=DN
to query all children groups of a groupThis limitation is imposed to avoid congesting the directory server with recursive calls to get all groups that are indirect members of the root group
If the recursive querying isn't supported, a workaround can be used to achieve the same results. This can be achieved by making sure that all groups returned by the group's query form a subtree. In other words, the groups returned should contain a subset of the groups that are direct parents of the queried users. This will end-up mapping the root_group along with other children groups and managing the users can be either done on the root_group level or on the children level.
Supported Active Directories
We support the following list of Active Directory servers. Supported means that we actively test the tool during development against these systems.
Windows Server 2016 Datacenter
Ping Directory 8.0
What to do if your setup is not reflected in this list? It does not mean that the tool will not work with your setup. Please try it - and if you find it not working then file a feature request with our ServiceDesk.
Version Logging
Upon successful execution, the tool sends to us the following information:
Tool version, such as
1.26
Active Directory Vendor, such as
Windows Server 2016 Datacenter
We use this information for expanding our range of supported directories and may reach out to you if we find out that the vendor is unknown.
Proxies
Using the application with your system proxy is possible by setting the environment variable https_proxy
and passing the following parameter:
-Djava.net.useSystemProxies=true
Example use cases
Example 1
Goal: Map a group called my_group with all the direct user members to a Celonis group within a team.
How:
Ldap group query is to return my_group only, you can test that by running the same query directly against the server.
Ldap user query is to return all direct members of my_group.
Configuration example 1
search-options: accept-partial-results: true users-filters: search-base: DC=domain,dc=test search-scope: SUBTREE query: (memberof=cn=my_group,ou=groups,dc=domain,dc=test) groups-filters: search-base: DC=domain,dc=test search-scope: SUBTREE query: (cn=my_group)
Example 2
Goal: Map the group my_group to a Celonis group along with a subset of the direct user members of that group. The users of interest have thecn attribute suffixed by the string:manager.
How:
Ldap group query is to return one my_group only.
Ldap user query is to return all direct members of my_group filtered by their cn.
Configuration example 2
search-options: accept-partial-results: true users-filters: search-base: DC=domain,dc=test search-scope: SUBTREE query: (&(memberof=cn=my_group,ou=groups,dc=domain,dc=test) (cn=*manager) ) groups-filters: search-base: DC=domain,dc=test search-scope: SUBTREE query: (cn=my_group)
Example 3
Goal: Map all management groups nested under group root_management_group in a directory server to one group in a Celonis team along with direct and indirect members.
root_management_group contains multiple groups as members and so on till a leaf group
Please note: This configuration uses the include-nested-memberships option, this option is subject to the limitations.
Configuration example 3
search-options: accept-partial-results: true include-nested-memberships: true users-filters: search-base: DC=domain,dc=test search-scope: SUBTREE query: (&(memberof:1.2.840.113556.1.4.1941:=cn=all_management_group,ou=groups,dc=domain,dc=test) (cn=*manager) ) groups-filters: search-base: DC=domain,dc=test search-scope: SUBTREE query: (cn=all_management_group)
Configuration
The application is configured with a file called application.yml
. It is divided into five blocks of top-level configuration options, which are documented subsequently below.
General configuration
The general
block allows for configuring a general option for identifying the directory server.
Attribute | Required | Available Options | Explanation |
---|---|---|---|
general.provider-id | TRUE | An identifier for your directory server, for example: | |
general.send-invitation-emails | [TRUE, FALSE ] | This flag controls whether invited users receive an email when they are synchronized. If set to false, there will not be a potentially large amount of emails, but each user will have to confirm their e-mail during their first sign-in. |
General Default Values
general: provider-id: LDAP_TEST_ID send-invitation-emails: TRUE
Connection configuration
The connection block exists for configuring the credentials for accessing the LDAP server and the EMS.
Attribute | Required | Available Options | Explanation |
---|---|---|---|
connection.cloud.url | TRUE | Link to your celonis team domain | |
connection.cloud.api-key | TRUE Either |
Obtain this key by visiting your celonis account page, clicking on the Create Api Key button to generate a new API key. | |
connection.cloud.application-key | TRUE Either | From LDAP client release 2.5 onwards, we encourage the use of application keys, as they are more secure than API keys. The team admin needs to create an application in the team settings and grant it the IMPORT MEMBERS permission under Permissions > Team Permissions. Then the key has to be provided via the configuration field application-key (instead of api-key) in the configuration | |
connection.ldap.url | TRUE | directory server url Note: use ldaps://IP:PORT to enable connection over TLS or simply use ldap://IP:PORT to use non-encrypted connection. on client side make sure that you have trusted the certificate authority that issued the certificate the ldap-server is using. | |
connection.ldap.user-dn | TRUE | LDAP user-dn | |
connection.ldap.password | TRUE | LDAP user-dn password | |
connection.ldap.referral | TRUE | [ ignore, follow ] | https://docs.oracle.com/javase/jndi/tutorial/ldap/referral/overview.html |
Connection Default Values
connection: cloud: url: https://myteam.celonis.cloud api-key: API_KEY application-key: APPLICATION_KEY ldap: url: ldaps://LDAP_IP:LDAP_PORT user-dn: cn=Example,ou=Example Accounts,ou=Example Accounts,dc=example,dc=com password: MyPassword referral: ignore
Search options configuration
The search-options
block exists for configuring the user- and group-filter queries.
Attribute | Required | Available Options | Explanation |
---|---|---|---|
search-options.accept-partial-results | TRUE | [ true, false ] | When this is set to false, any received result containing referral that is ignored or invalid throws an exception (a referral is invalid when the referral is set to ignore, a referral is empty or referral points to a nonexisting or unreachable server) |
search-options.include-nested-memberships | FALSE | [ true, false ] | Allows mapping groups with indirect user memberships. See Examples and Limitations. |
search-options.users-filters.search-base | TRUE | [ ignore, follow ] | Base node from which to start the search |
search-options.users-filters.search-scope | FALSE | [ OBJECT, ONELEVEL, SUBTREE ] Default: SUBTREE | SUBTREE: search in the whole subtree whose root is the search base. OBJECT: return only one object. ONELEVEL: search one level below the root. |
search-options.users-filters.query | FALSE | LDAP query for search refinement, Examples: | |
search-options.groups-filters.search-base | TRUE | [ ignore, follow ] | Base node from which to start the search |
search-options.groups-filters.search-scope | FALSE | [ OBJECT, ONELEVEL, SUBTREE ] Default: SUBTREE | SUBTREE: search in the whole subtree whose root is the search base. OBJECT: return only one object. ONELEVEL: search one level below the root. |
search-options.groups-filters.query | FALSE | LDAP query for search refinement, Examples: |
Search Options Example
search-options: accept-partial-results: true users-filters: search-base: DC=test,dc=com search-scope: SUBTREE query: (sn=W*) # ex: all users with surnames that starts with W groups-filters: search-base: DC=test,dc=com search-scope: SUBTREE query: (name=A*) # all groups with names starting with A
Attribute Mapping
The objects
block exists for mapping attributes to Celonis EMS attributes. The two sub-blocks user-attributes
and group-attributes
exist for the mappings for user and groups respectively.
Attribute | Required | Explanation |
---|---|---|
objects.user-attributes.id | TRUE | id parameter inside the directory server. for example objectGUID |
objects.user-attributes.first-name | TRUE | first name parameter inside the directory server. for example: givenName |
objects.user-attributes.last-name | TRUE | last name parameter inside the directory server. for example sn |
objects.user-attributes.user-name | TRUE | user name parameter inside the directory server. for example: sAMAccountName |
objects.user-attributes.email | TRUE | email parameter inside the directory server. for example mail → This parameter is used for sign-up |
objects.user-attributes.language | TRUE | language parameter inside the directory server. for example language |
objects.user-attributes.currency | TRUE | currency parameter inside the directory server. for example currency |
objects.user-attributes.group-ids | TRUE | The list of groups a user is directly a member of. for example memberof |
objects.user-attributes.object-class | FALSE | Defines the objectClass for the user on the directory server. Default value: person Default values work for most directory servers and rarely needs to be adjusted. |
objects.group-attributes.id | TRUE | id parameter inside the directory server. for example objectGUID |
objects.group-attributes.name | TRUE | name parameter inside the directory server. for example: sAMAccountName |
objects.group-attributes.object-class | FALSE | Defines the objectClass for the group on the directory server. Default value: group Default values work for most directory servers and rarely need to be adjusted. |
Attribute Mapping Example
objects: user-attributes: id: objectGUID first-name: givenName last-name: sn user-name: sAMAccountName email: mail language: language currency: currency group-ids: memberof # all the groups a user is part of group-attributes: id: objectGUID name: sAMAccountName object-class: group
Object Extraction Patterns
The objects-extraction-patterns
block is for manipulation of the results returned by the directory server. This can be used to use only parts of a mapped attribute. For example, if the directory server returns a user-id that is mapped to a DN, if the server appends the used internal id of the retrieved object, and the interest lies only in the value of that internal id and not the rest of the retrieved string. The same applies for the other *-id/s attributes.
Attribute | Required | Explanation |
---|---|---|
objects-extraction-patterns.user-attributes.group-ids | FALSE | Defines a regex to extract the group ids a user belongs to/member of, from the server response. If left empty the default value <GUID=(.+?)> is applied. |
objects-extraction-patterns.user-attributes.id | FALSE | Defines a regex to extract the user id from the server response. If left empty, the whole user id is processed. |
objects-extraction-patterns.group-attributes.id | FALSE | Defines a regex to extract the group id from the server response |
Note
The result of the user's query, for each user, contains a membership set. This set is matched against the set of ids of groups returned by the group's query and should be a subset of that.
By default, the optional parameters work with the active directory and are set to the following:
objects-extraction-patterns: user-attributes: group-ids: <GUID=(.+?)>
Object Extractions Patterns Example
objects-extraction-patterns: user-attributes: id: (?:CN|cn)=(.+?)(?=,) group-ids: (?:CN|cn)=(.+?)(?=,) group-attributes: id: (?:CN|cn)=(.+?)