You can synchronize your users and groups via the Microsoft Graph API. To enable the sync, you need to complete the steps in both Microsoft Entra ID and Haiilo's Administration. You can view a video of the setup below.
When syncing a user directory, users and groups are considered separately in the sync. Groups are synced first, followed by users. Users can only be added to groups synced in the first step. However, all users matching the user filters are synced, regardless of whether they belong to the groups synced in the group sync.
Please complete the app registration in Microsoft Entra ID as detailed in the Setting up OpenID authentication on Microsoft Entra ID article before proceeding with this tutorial.
Add API permissions in Microsoft
You need admin rights in your Microsoft Entra ID account to complete the configuration.
- Log in to the Microsoft Azure Platform.
- Go to Microsoft Entra ID > App registrations > select the app that you created when setting up Microsoft authentication for Haiilo
- Go to API permissions
- Select Add permissions > Microsoft Graph > Application permissions
- Add the following API permissions:
Group.Read.AllUser.Read.All
- Select Grant admin consent for app_name for the added permissions and ensure the status for all permissions is marked Granted for your_tenant.
Set up a new user directory in Haiilo
You need "Manage user directories" permission to set up a Microsoft Graph user directory in Haiilo.
- In Haiilo, go to Administration > User directories
- Select Create user directory
- Enter a name
- Choose the type: Microsoft Graph
- Toggle Activate directory, if this new user directory should be activated directly
- Check Deny form login for this user directory to prevent users synced from this directory from logging in through the local login form (email + password). If a user previously used local login and later was connected to the directory, they can still log in with local login unless this option is enabled.
Fill out the fields on each tab as detailed below.
Connection
- Input the Application (client) ID that you copied from Microsoft Entra ID into the Client ID field
- Input the Client Secret Value that you copied from Microsoft Entra ID into the Client Secret field
- Input the Directory (tenant) ID that you copied from Microsoft Entra ID into the Tenant ID field
- Select Test connection to verify the connection is established
User
-
User filter: Define filters to synchronize only certain users. You can use the standard Microsoft Graph filters, e.g.,
startsWith(displayName,'Jane'). -
Local user filter: The local user filter acts just like the normal user filter, but isn't part of the query to the MS Graph API, but will be executed on the Haiilo backend on the received response. This allows for filtering by the 'user filter' in the 1st stage and then filtering further by the 'local user filter' using expressions that MS Graph doesn't support.
- Learn more before using the Local user filter in Local user filter for a Microsoft Graph user directory
- Remove local groups: Toggle if you want to remove the synced users from any local groups they've been manually added to.
- Remove other directory groups: Toggle if you want to remove the synced users from any other user directory groups they've been manually added to.
- Sync managers: Toggle if you want users' managers and teams to be visible on their profiles.
- Sync display names: Toggle if you want users' DisplayName from your directory to be synchronized with the DisplayName field on Haiilo. This display name will be used as the user's name instead of their first and last name.
-
Username: Enter the attribute for username. We recommend using
mailoruserPrincipalName. - You can also synchronize additional profile fields. Profile field mapping can be complex for the MS Graph API because the API responds with JSON objects that can contain nested data.
- Learn more before configuring mapping: Additional information on mapping profile fields
Groups
- To synchronize groups from Microsoft Graph, toggle Synchronize groups.
-
Group filter: Define filters to synchronize only certain groups. You can use the standard Microsoft Graph filters, e.g.,
startsWith(displayName, 'Haiilo') - Users from groups only: Check if you want to sync only users who are part of a synchronized group. Enabling this means that only the users matching the User filter who also belong to a group synced in the group sync will be synced.
- Preserve groups: If Synchronize groups is disabled, you can toggle this field to preserve any previously synced groups for this specific user directory. This way, you can freeze the previously synced groups. If left unchecked, any previously synced groups and their memberships will be removed in the next sync.
Synchronization
- Page size: Defines how many items are synchronized per query. We recommend not setting the page size to a value higher than 120, as Microsoft states this is the limit in their documentation. However, they also say that the value could be even lower depending on the query.
- Activation: If checked, new and restored users are activated during synchronization. Otherwise, you have to manually set the users' status to Active in the user management.
- Orphaned users: Choose what happens to users that currently exist as active users on Haiilo, but no longer exist in the user directory. If you choose Ignore, they will remain unchanged.
- Restore users: If toggled, a user who has been deactivated or deleted from Haiilo but is present again in the user directory during the sync will be reactivated. It's not possible to restore anonymized users. A previously anonymized user can only be created as a new user.
Scheduling
- Choose the synchronization frequency. If you choose Disabled, you run the sync manually.
Setup Video
Check out the setup video for an example setup! For a deeper dive into user directories, take our course "Setting Up Authentication & Provisioning" on the Haiilo Academy. It's a great way to learn more and get the most out of your setup!
Additional information on mapping profile fields
A user's profile field mapping can be somewhat complex because the MS Graph API responds with JSON objects that can contain nested data. This requires the use of a more complex field address syntax. We chose JSONPath, which allows access to nested or indexed properties and predicates, which are useful for extension selection.
MS Graph also requires that you specify in the query which properties the call should return. This is done by passing a list of fields in the $select or $expand parameters. A simple field name is automatically inserted verbatim into the $select clause of the MS Graph API query. The new syntax accepts the select/expand clause as an optional second part of the expression. The previous simple field syntax is still valid and can also be used.
For the additional field mapping, the syntax is as follows:
<jsonpath>[:select/expand- clause]Please pay attention to the following syntax:
- The JSONPath must start with
$.to be recognized as new JSONPath syntax - If the JSONPath contains a colon, the colon must be masked with a backslash
- If the JSONPath selects more than one entry, only the first one is returned
- The selected value is converted to a string
- A missing value leads to an empty profile field
The path may optionally be followed by a colon (the colon must not be masked with a backslash here) and the select/expand clause corresponding to an entry of the $select or $expand parameter above. Only if the value is extensions, the query parameter $expand=extensions is added. Any other value is interpreted as an entry for the $select field list. It is recommended to configure the select/expand clause to ensure that the API response contains the required field.
Examples of syntax for profile fields assignment
-
$.aboutMe:aboutMe- This expression adds the
$select=aboutMeparameter to the query. The JSONPath part will select theaboutMeproperty from the query result. This expression is equivalent to theaboutMesimple field expression.
- This expression adds the
-
$.employeeOrgData.division:employeeOrgData- This expression adds the
$select=employeeOrgDataparameter to the query. The JSONPath part selects the nested propertydivisionof the rootemployeeOrgDataproperty. This expression has no equivalent in a simple field expression because it is not possible to select nested properties in this way.
- This expression adds the
-
$.extensions[?(@.id=='com.haiilo')].nested.prop1:extensions- This expression adds the
$expand=extensionsparameter to the query. The JSONPath part selects the firstextensioninside the root object, which has a property id with valuecom.haiilo. From this extension, the nested propertynested.prop1is selected.
- This expression adds the
The API response is not known until the synchronization job is executed, so it is not known what a valid JSONPath expression actually selects. We currently recommend administrators to query the Microsoft Graph API manually with a tool like Postman, then copy the JSON response into a JSONPath evaluation tool and find out what the expression returns.