Connector guides
Microsoft Entra ID Governance
Connect Warde to Microsoft Entra ID through Microsoft Graph, choose how much it may change, and see what it reads and writes.
With an Entra engine, Warde reads your tenant's groups, application roles, licences, access packages and directory roles through Microsoft Graph, matches each user to a ServiceNow user, and makes the changes your consented permissions allow. What it cannot change goes to a person as a ServiceNow task.
Before you start
You need:
- a Microsoft Entra tenant, and the right to register an application and grant admin consent;
- the tenant ID, as a GUID or a domain name such as
example.onmicrosoft.com; - the Entra attribute that identifies a person in both Entra and ServiceNow, such as
employeeIdoruserPrincipalName.
1. Choose a permission level
Warde works at one of four levels. Each includes the ones above it. Choose the highest level you will consent to in full.
| Level | Warde can | Microsoft Graph application permissions |
|---|---|---|
read_only | Read everything. Every change goes to a person. | User.Read.All, Group.Read.All, GroupMember.Read.All, Directory.Read.All, Application.Read.All, LicenseAssignment.Read.All, EntitlementManagement.Read.All, RoleManagement.Read.Directory, PrivilegedAssignmentSchedule.Read.AzureADGroup, PrivilegedEligibilitySchedule.Read.AzureADGroup, RoleEligibilitySchedule.Read.Directory |
membership | Add and remove group members, assign licences, enable and disable users | The above, plus GroupMember.ReadWrite.All, LicenseAssignment.ReadWrite.All, User.EnableDisableAccount.All, User.ReadUpdate.All, PrivilegedAssignmentSchedule.ReadWrite.AzureADGroup |
entitlement_management | Assign and remove access packages | The above, plus EntitlementManagement.ReadWrite.All |
privileged | Assign and remove application roles and directory roles | The above, plus AppRoleAssignment.ReadWrite.All, RoleManagement.ReadWrite.Directory |
With Microsoft Entra ID P2, also grant RoleAssignmentSchedule.Read.Directory, so access reviews can tell a PIM role activation from a standing role.
Under-claiming the level sends changes to a person that Warde could have made. Over-claiming sends changes that Graph will refuse.
2. Register the application in Entra
- In the Microsoft Entra admin center, open App registrations and select New registration. Name it, for example
Warde, and leave the redirect URI empty. - Note the Application (client) ID and the Directory (tenant) ID.
- Under Certificates & secrets, create a client secret and copy its value. Note when it expires.
- Under API permissions, add the Microsoft Graph application permissions for your level, then select Grant admin consent.
Warde signs in with the client credentials flow and the https://graph.microsoft.com/.default scope. Certificate sign-in is not available yet.
3. Set the endpoint in ServiceNow
- Open Connections & Credentials > Connections & Credential Aliases and open Microsoft Entra ID.
- Open its HTTP connection, Microsoft Entra ID - connection.
- Set Connection URL to
https://graph.microsoft.com, with no version on the end. - Save.
4. Add the engine
In Guided Setup step 2, select Add an engine:
| Field | Value |
|---|---|
| Engine name | Such as Entra ID (production) |
| Connector | Microsoft Entra ID |
| Connection alias | Microsoft Entra ID |
| Application (client) ID | From the app registration |
| Client secret | The secret's value |
Select Create engine.
Set the tenant and level
Guided Setup does not ask for the tenant. Open the engine in the Admin Workspace and set Connector configuration:
{ "tenant_id": "00000000-0000-0000-0000-000000000000", "permission_tier": "membership" }
| Key | Default | What it does |
|---|---|---|
tenant_id | none | Required. Your tenant ID, as a GUID or a domain. common, organizations and consumers are refused. |
permission_tier | read_only | The level you consented to |
graph_version | v1.0 | The Graph version |
login_base | Microsoft's global sign-in endpoint | For a national cloud, its sign-in endpoint |
Then select Test connection in Guided Setup, or Run health check on the engine. A pass reads "Connected to Entra tenant" with the tenant and the permission level.
5. Bind accounts to users
In Guided Setup step 3, set the engine's pair. The Entra attributes Warde can match on are userPrincipalName, mail, employeeId, onPremisesSamAccountName, onPremisesImmutableId and id. If you choose employeeNumber, Warde reads employeeId. An attribute Graph does not have falls back to userPrincipalName against the user's user_name.
6. Run the first sync
In Guided Setup step 4, select Sync now, then Refresh until the counts settle.
What Warde reads
| Entra | Becomes in Warde |
|---|---|
| Groups | Entitlements in a collection named <engine name>: Groups |
| Licences | Entitlements in <engine name>: Licences |
| Directory roles | Entitlements in <engine name>: Directory roles |
| Each application with app roles users can be given | A collection, with its app roles as entitlements |
| Each access package catalog | A collection, with its access packages as entitlements |
| What an access package or group gives | Links, so a review shows the package or group rather than its parts |
| Each user | An account. Guests are imported as orphans. Service principals are left out. |
| Memberships and assignments | Holdings |
Some entitlements are imported but cannot be requested or changed by Warde, because nobody can assign them directly: dynamic groups, groups synced from on-premises Active Directory, mail-enabled groups, and disabled or application-only app roles. Anything your permission level cannot write is imported as not fulfillable, so a request for it goes to a person. PIM-managed groups are marked as such and cannot go in an access bundle.
Delta reads. Group membership is read as a Graph delta, so most runs read only what changed. App roles, licences, access packages and directory roles are read in full at the full-sweep interval.
Access through a group. A person who holds access because they are in a group is shown holding it, but it cannot be removed on its own: remove them from the group instead. Eligible PIM directory roles are shown and cannot be removed on request.
End dates. Entra keeps access package end dates. Warde keeps every other end date and removes the access when it passes.
What Warde writes
| Change | Graph call | Level needed |
|---|---|---|
| Add or remove a group member | POST or DELETE /groups/{id}/members/$ref | membership |
| Assign or remove a licence | POST /users/{id}/assignLicense | membership |
| Assign or remove an application role | POST or DELETE /users/{id}/appRoleAssignments | privileged |
| Assign or remove a directory role | POST or DELETE /roleManagement/directory/roleAssignments | privileged |
| Assign or remove an access package | POST /identityGovernance/entitlementManagement/assignmentRequests | entitlement_management |
| Enable or disable a user | PATCH /users/{id} | membership |
Graph has no request reference, so before every change Warde reads the target to see whether the change is already made. Sending a change twice is therefore safe. Group, licence, app role and directory role changes complete on Graph's answer. Access package requests are polled until Entra delivers them; if one is held up by an open request for more than 24 hours, it goes to a person.
These go to a person instead:
- a change your permission level does not allow;
- a PIM-managed group;
- a dynamic, mail-enabled or on-premises synced group;
- a licence when the user has no usage location, the licence has none left, or it is inherited from a group;
- an access package with no policy that fits the person;
- enabling or disabling a user who is synced from on-premises or holds an administrator role.
Warde does not create Entra users.
Health and troubleshooting
The health check reads the tenant ID, signs in, and reads one user.
| Message | What to do |
|---|---|
| Has no Entra tenant ID | Add tenant_id to the engine's connector configuration |
| Refused the credentials | Check the client ID, the client secret and the tenant ID. The secret may have expired. |
| Accepted the credentials but refused to read users | Grant User.Read.All and admin consent |
| Something other than Entra answered | The connection URL is wrong, or a proxy answered. Set it to https://graph.microsoft.com. |
| The permission level does not allow changes to this | Raise permission_tier once the permissions are consented, or leave the change to a person |
Graph's request id is written to the log with each failed call, for Microsoft support. Log lines start [Warde sync] and [Warde dispatch].