Links
External system
Demo
- Movie: Grouper provisioning framework Azure demo (v2.6.15): https://youtu.be/abTkJVBMr1M
Config (grouper-loader.properties from version 2.6.15). Note, you should configure this in the provisioning configuration wizard.
- Another config with extension attributes
Provisioning groups
API documentation
Grouper name | Type | Required? | Azure/Entra API | Description |
|---|---|---|---|---|
| allowOnlyMembersToPost | Boolean | No | resourceBehaviorOptions: ["AllowOnlyMembersToPost"] | When the attribute allowOnlyMembersToPost is true, it would add "AllowOnlyMembersToPost" to the resourceBehaviorOptions array in the API call |
| description | String | No | description | This is the group description on the Azure side |
| displayName | String | Required | displayName | This is the group display name on the Azure side |
| groupOwners | String array | No | owners@odata.bind | This is list of owners. It's sent to Azure only when groupOwnersManage is set to true |
| groupOwnersManage | Boolean | No | N/A | If the value of this attribute is true, then Grouper sends owners@odata.bind property to Azure |
| groupType (Not being used) | String | No | N/A | N/A |
| groupTypeUnified | Boolean | No | If the value of this attribute is true, then Grouper add "Unified" to the groupTypes array in the API call | |
| hideGroupInOutlook | Boolean | No? | resourceBehaviorOptions: ["HideGroupInOutlook"] | When the attribute hideGroupInOutlook is true, it would add "HideGroupInOutlook" to the resourceBehaviorOptions array in the API call |
| id | String | required | id | This is the id read from Azure. Select only. This should not be translated from Grouper, and the target attribute should be cached. |
| isAssignableToRole | Boolean | No | isAssignableToRole | A group with isAssignableToRole property set to true cannot be of dynamic membership type, its securityEnabled must be set to true, and visibility can only be Private. |
| mailEnabled | Boolean | No | mailEnabled | Set to |
| mailNickname | String | Required | mailNickname | Sets the value of mailNickname on the Azure side |
| resourceProvisioningOptionsTeam | Boolean | No | resourceBehaviorOptions: ["Team"] | When the attribute resourceProvisioningOptionsTeam is true, it would add "Team" to the resourceProvisioningOptions array in the API call |
| securityEnabled | Boolean | Yes | securityEnabled | Set to |
| subscribeMembersToCalendarEventsDisabled | Boolean | No | resourceBehaviorOptions: ["SubscribeMembersToCalendarEventsDisabled"] | When the attribute subscribeMembersToCalendarEventsDisabled is true, it would add "SubscribeMembersToCalendarEventsDisabled" to the resourceBehaviorOptions array in the API call |
| subscribeNewGroupMembers | Boolean | No | resourceBehaviorOptions: ["SubscribeNewGroupMembers"] | When the attribute subscribeNewGroupMembers is true, it would add "SubscribeNewGroupMembers" to the resourceBehaviorOptions array in the API call |
| visibility | String | No | visibility | Can be Public | Private | HiddenMembership If you make a metadata for visibility, select show on groups |
| welcomeEmailDisabled | Boolean | No | resourceBehaviorOptions: ["WelcomeEmailDisabled"] | When the attribute welcomeEmailDisabled is true, it would add "WelcomeEmailDisabled" to the resourceBehaviorOptions array in the API call |
Provisioning users
You can search by email only. You should cache the email and id.
API documentation
Grouper name | Type | Required? | Azure/Entra API | Description |
|---|---|---|---|---|
| accountEnabled | Boolean | Required | accountEnabled | true if the account is enabled; otherwise, false. |
| displayName | String | Required | displayName | The name to display in the address book for the user. |
| id | String | Required | userId | This is the id read from Azure. Select only. This should not be translated from Grouper, and the target attribute should be cached. |
| mailNickname | String | Required | mailNickname | The mail alias for the user. |
| onPremisesImmutableId | String | See description | onPremisesImmutableId | Required only when creating a new user account if you are using a federated domain for the user's userPrincipalName (UPN) property. |
| userPrincipalName | String | Required | userPrincipalName | The user principal name (someuser@contoso.com). It's an Internet-style login name for the user based on the Internet standard RFC 822. By convention, this should map to the user's email name. The general format is alias@domain, where domain must be present in the tenant's collection of verified domains. The verified domains for the tenant can be accessed from the verifiedDomains property of organization. NOTE: This property cannot contain accent characters. Only the following characters are allowed A - Z, a - z, 0 - 9, ' . - _ ! # ^ ~. |
Entra Id provisioner configuration
| Name | Config suffix | Value | Description |
|---|---|---|---|
| assignableToRole | true|false | When marking a group as provisionable, allow users to choose if the group is assignable to role. Default value is 'false'. | |
| azureGroupType | true|false | When marking a group as provisionable, allow users to choose azure group type. The possible values are: 'security', 'unified', 'unifiedSecurityEnabled'. Default value is 'false'. | |
| groupOwners | true|false | When marking a group as provisionable, allow users to choose azure group owners. Default value is 'false'. | |
| groupOwnersManage | true|false | When marking a group as provisionable, allow users to decide if they want to manage group owners. Default value is 'false'. | |
| allowOnlyMembersToPost | true|false | When marking a group as provisionable, allow users to choose if only members can post. Default value is 'false'. | |
| hideGroupInOutlook | true|false | When marking a group as provisionable, allow users to choose if group can be hidden in outlook. Default value is 'false'. | |
| subscribeNewGroupMembers | true|false | When marking a group as provisionable, allow users to choose if new group members can subscribe. Default value is 'false'. | |
| welcomeEmailDisabled | true|false | When marking a group as provisionable, allow users to choose if welcome email can be disabled. Default value is 'false'. | |
| subscribeMembersToCalendarEventsDisabled | true|false | When marking a group as provisionable, allow users to choose if subscribe members to calendar events can be disabled. Default value is 'false'. | |
| resourceProvisioningOptionsTeam | true|false | When marking a group as provisionable, allow users to choose if resource provisioning options can be set as Team. Default value is 'false'. | |
| visibilityMetadata | true|false | When marking a group as provisionable, allow users to choose two metadata: 1. visibility public/private 2. hidden membership. Default value is 'false'. |
Configure group owners in Azure
Note: groupOwners is a multivalued attribute. You must set "multi-value attribute" to True. To display the "multi-valued attribute" setting in the UI, first set "advanced options" to True, then set "show value settings" to True.
provisioner.myAzureProvisioner.groupOwnersManage = true
provisioner.myAzureProvisioner.targetGroupAttribute.5.multiValued = true
provisioner.myAzureProvisioner.targetGroupAttribute.5.name = groupOwners
provisioner.myAzureProvisioner.targetGroupAttribute.5.showAdvancedAttribute = true
provisioner.myAzureProvisioner.targetGroupAttribute.5.showAttributeValueSettings = true
provisioner.myAzureProvisioner.targetGroupAttribute.5.translateExpression = ${provisioningGroupWrapper.thisGroupPrivilegeHolders('admins', 'entityAttributeValueCache2')}
provisioner.myAzureProvisioner.targetGroupAttribute.5.translateExpressionType = translationScript
provisioner.myAzureProvisioner.entityAttributeValueCache2entityAttribute = id
provisioner.myAzureProvisioner.entityAttributeValueCache2has = true
provisioner.myAzureProvisioner.entityAttributeValueCache2source = target
provisioner.myAzureProvisioner.entityAttributeValueCache2type = entityAttribute
provisioner.myAzureProvisioner.entityAttributeValueCacheHas = true
Setting the Grouper service account as the owner of new groups (to reduce Azure privileges) v4.2.0+
If the service account Grouper uses for Graph API calls can be set as the owner of a managed group, the Azure application no longer needs the privileges to update all groups and memberships. It only needs the Group.Create privilege to create a new group, Group.Read.All to find groups to match with Grouper, and User.Read.All to resolve target entities. While there is an option in the Azure provisioner to set the groupOwner attribute with one or more entities, the ability to add non-users (i.e. service accounts) is only available v4.2.0.
The "groupOwners" attribute is normally expected to be a Grouper subject ID or identifier used for search/match to resolve to an Azure object URL. But this lookup always uses the /users api endpoint, which means the service account can't be added this way. Since v4.2.0, an already-resolved URL can be entered in this field, and this URL can be either for a user or a service account. There are two ways to specify the account.
1) https://graph.microsoft.com/v1.0/servicePrincipals/{id}
2) https://graph.microsoft.com/v1.0/servicePrincipals(appId='{appId}')
where {id} is the "Object ID" for the object in the Enterprise Applications page (it's not the App registrations page, but you can get to it from there by clicking "Managed application in local directory"). The {appId} is the application ID, also called the client ID, and is easier to find, being on the Enterprise applications page, the App registrations page, and various other pages when you look at the service account details. The appId is also the "Client ID" value in the external system configuration for Azure.
Note: As of August 2025, the MS Graph API call to select the Entra goup's owners will not list service principals in the response. By default, Grouper will try to re-add the service principal as a group owner every time it updates the Entra group. The audit log for the Entra group will show a failure to "Add owner to group" with a reason "Microsoft.Online.DirectoryServices.DirectoryValueExistsException", although Grouper does not report any error in its logs. To stop Grouper from attempting to update the Entra group owner, disable the Update operation for the "groupOwners" attribute:
provisioner.myAzureProvisioner.targetGroupAttribute.4.name = groupOwners provisioner.myAzureProvisioner.targetGroupAttribute.4.showAdvancedAttribute = true provisioner.myAzureProvisioner.targetGroupAttribute.4.showAttributeCrud = true provisioner.myAzureProvisioner.targetGroupAttribute.4.showAttributeValueSettings = true provisioner.myAzureProvisioner.targetGroupAttribute.4.translateExpressionType = staticValues provisioner.myAzureProvisioner.targetGroupAttribute.4.translateFromStaticValues = https\u003A//graph.microsoft.com/v1.0/servicePrincipals/<redacted> provisioner.myAzureProvisioner.targetGroupAttribute.4.update = false
Group extension attributes
Grouper can manage custom extensions on groups. The attributes must be pre-configured in Entra ID before using them, Grouper only manages existing extension attributes. This is NOT for mail enabled groups or any group if you have one of these attributes configured: welcomeEmailDisabled , resourceProvisioningOptionsTeam.
- https://learn.microsoft.com/en-us/graph/extensibility-overview?tabs=http
To set up directory extensions in Azure/Entra, follow the steps below:
- Call POST endpoint like https://graph.microsoft.com/v1.0/applications/2083897a-1149-43e1-aad5-2bd9be5b97c2/extensionProperties
- The ID after the /
applicationsis the Object ID. You can retrieve it from the Azure portal in the application tab. Sample Payload for the POST call
{ "name": "jobGroup", "dataType": "String", "isMultiValued": true, "targetObjects": [ "User", "Group" ] }Response should look like
{ "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#applications('2083897a-1149-43e1-aad5-2bd9be5b97c2')/extensionProperties/$entity", "id": "e0918040-c1ac-4724-929e-6c104eb1cbaa", "deletedDateTime": null, "appDisplayName": "vivek-chris-test-july-2022", "dataType": "String", "isMultiValued": true, "isSyncedFromOnPremises": false, "name": "extension_1ed9f56e96ef441dbf1a8391747e8c7f_jobGroup", "targetObjects": [ "User", "Group" ] }- In Azure portal, give Application.ReadWrite.all permissions to the application
To create extension attributes on the Grouper side, follow the steps below:
- Create an extension attribute in the provisioner config. It must start with "extension_<applicationId>_<extensionProperty>". It's exactly the same name you see in the response body of the POST call https://graph.microsoft.com/v1.0/applications/2083897a-1149-43e1-aad5-2bd9be5b97c2/extensionProperties
- If the extension property is single valued and of type string on the Azure side, then the above settings will work.
- In case, the extension property is multi-valued, then on the Grouper side, set "
- The extension attribute value type on the Azure side must match with the value type on the Grouper side.







