๐ Microsoft Entra ID
Microsoft Entra ID (Azure AD) โ directory + provisioning via Microsoft Graph.
Identification
- vendor key:
entra - engine:
entra - default role:
target - type: Out-of-the-box vendor
- default authoritative for:
entra_object_id,user_principal_name - vendor docs: https://learn.microsoft.com/graph/overview
Supported auth methods
oauth2_client_credentials
Importable objects (6)
Object types the wizard offers to import out of the box.
Users
- name:
users - iga_target:
identity - path:
/users?$expand=manager($select=id,userPrincipalName,mail)&$select=id,userPrincipalName,displayName,givenName,surname,mail,mobilePhone,department,jobTitle,companyName,officeLocation,accountEnabled,employeeId,employeeHireDate,employeeLeaveDateTime,employeeOrgData
All users in the tenant. For reuse: filter via $filter=accountEnabled eq true
Default field mappings:
| IGA field | Expression | Required |
|---|---|---|
business_id |
{{ id }} |
โ |
display_name |
{{ displayName }} |
โ |
native_account_name |
{{ userPrincipalName }} |
โ |
identity_business_id |
{{ mail|if_null(userPrincipalName)|lower }} |
|
status |
{{ 'active' if accountEnabled else 'terminated' }} |
|
is_privileged |
{{ false }} |
|
identity_id |
{{ userPrincipalName }} |
|
email |
{{ mail|if_null(userPrincipalName) }} |
|
first_name |
{{ givenName }} |
|
last_name |
{{ surname }} |
|
department |
{{ department }} |
|
function |
{{ jobTitle }} |
|
manager_id |
{{ manager.userPrincipalName|if_null(manager.mail) }} |
|
hire_date |
{{ employeeHireDate }} |
|
end_date |
{{ employeeLeaveDateTime }} |
|
location |
{{ officeLocation }} |
|
company |
{{ companyName }} |
|
cost_center |
{{ employeeOrgData.costCenter }} |
|
employee_id |
{{ employeeId }} |
|
entra_object_id |
{{ id }} |
Security & M365 groups
- name:
groups - iga_target:
entitlement - iga_subtype:
security_group - path:
/groups?$select=id,displayName,description,securityEnabled,mailEnabled,groupTypes,membershipRule
All groups โ use for membership provisioning.
Default field mappings:
| IGA field | Expression | Required |
|---|---|---|
business_id |
{{ id }} |
โ |
name |
{{ displayName }} |
โ |
description |
{{ description }} |
|
native_identifier |
{{ id }} |
|
risk_level |
{{ 'high' if (('Privileged' in (displayName or '')) or ('Admin' in (displayName or ''))) else 'low' }} |
|
privileged |
{{ ('Privileged' in (displayName or '')) or ('Admin' in (displayName or ''))|to_bool }} |
Directory Roles (privileged)
- name:
directory_roles - iga_target:
entitlement - iga_subtype:
directory_role - path:
/directoryRoles
Built-in Entra roles (Global Admin, User Admin, etc.).
Default field mappings:
| IGA field | Expression | Required |
|---|---|---|
business_id |
{{ id }} |
โ |
name |
{{ displayName }} |
โ |
description |
{{ description }} |
|
native_identifier |
{{ id }} |
|
risk_level |
'critical' |
|
privileged |
true |
Service Principals / Enterprise apps
- name:
service_principals - iga_target:
account - path:
/servicePrincipals?$select=id,displayName,appId,servicePrincipalType,accountEnabled
Apps + service identities โ often NHIs
Default field mappings:
| IGA field | Expression | Required |
|---|---|---|
business_id |
{{ id }} |
โ |
native_account_name |
{{ appId }} |
โ |
display_name |
{{ displayName }} |
|
status |
{{ 'active' if accountEnabled else 'terminated' }} |
|
is_privileged |
{{ false }} |
|
identity_type |
'service_account' |
License SKUs
- name:
subscribed_skus - iga_target:
entitlement - iga_subtype:
license - path:
/subscribedSkus
Available licenses (M365 E5, etc.) and consumption
Default field mappings:
| IGA field | Expression | Required |
|---|---|---|
business_id |
{{ skuId }} |
โ |
name |
{{ skuPartNumber }} |
โ |
native_identifier |
{{ skuId }} |
|
description |
{{ skuPartNumber }} ({{ consumedUnits }}/{{ prepaidUnits.enabled }} consumed) |
|
risk_level |
'medium' |
|
total |
{{ prepaidUnits.enabled }} |
|
consumed |
{{ consumedUnits }} |
App roles (per Enterprise app)
- name:
app_role_assignments - iga_target:
entitlement - iga_subtype:
app_role - path:
/servicePrincipals?$select=id,displayName,appRoles
Which app roles does each Enterprise app offer? These are the role definitions (e.g. Salesforce.Admin / Tableau.Viewer) โ the actual assignments to users are retrieved at runtime via /servicePrincipals/{id}/appRoleAssignedTo.
Default field mappings:
| IGA field | Expression | Required |
|---|---|---|
business_id |
{{ id }} |
โ |
name |
{{ displayName }} |
โ |
native_identifier |
{{ id }} |
|
description |
Discovered app-role definitions for {{ displayName }} |
|
risk_level |
'medium' |
|
source_app |
{{ displayName }} |
|
role_list |
{{ appRoles }} |
Account type templates (6)
Pre-filled account types the wizard's ACCOUNT_TYPES_REVIEW step shows.
๐ค Personal accounts โ ๐ข governance
- business_id_suffix:
personal - purpose_class:
personal - default_identity_type:
employee - native_filter:
userType eq 'Member' and accountEnabled eq true
Regular employee accounts โ fall into JML, certifications and access requests. If your tenant has separate admin or service-account naming conventions, enable the Privileged admin or Service accounts types below for stricter governance per subtype. Otherwise admin/service accounts fall into this catch-all type and you can split them out post-onboarding via Account Rules.
๐ค B2B Guest accounts โ ๐ก visibility-only
- business_id_suffix:
guest - purpose_class:
guest - default_identity_type:
external - native_filter:
userType eq 'Guest'
External collaboration via Entra business-to-business (B2B). Visible in IGA for audit + reporting, but NOT in joiner / mover / leaver (JML) or access-review workflows (no employer relationship).
๐ Disabled / dormant accounts โ ๐ก visibility-only
- business_id_suffix:
disabled - purpose_class:
personal - native_filter:
accountEnabled eq false
Accounts that are disabled in Entra (offboarded employees, obsolete service accounts). Visibility-only for cleanup audits and access-review sweeps that identify what can be removed.
๐ก Privileged admin accounts (personal) โ ๐ข governance (opt-in)
- business_id_suffix:
admin-personal - purpose_class:
administrative - default_identity_type:
employee - native_filter:
userType eq 'Member' and accountEnabled eq true and (startswith(userPrincipalName, 'a-') or startswith(userPrincipalName, 'adm-') or startswith(userPrincipalName, 'admin-'))
Secondary personal accounts for elevated/admin work. Stricter governance (shorter cert cycle, MFA required, JIT recommended). Identification via UPN naming convention (a-/adm-/admin- prefix); ownership via employeeId โ the admin account is linked to its human owner by writing the identity's employee_id to the account's employeeId Graph attribute. This requires the provisioning mapping below to be active. If your tenant uses a different correlation field, uncheck the ownership rule and refine via Systems โ Account Types โ Rules post-onboarding.
โ๏ธ Service accounts (NHI) โ ๐ข governance (opt-in)
- business_id_suffix:
service - purpose_class:
service - default_identity_type:
service_account - native_filter:
userType eq 'Member' and accountEnabled eq true and (startswith(userPrincipalName, 'svc-') or startswith(userPrincipalName, 'svc_') or endswith(userPrincipalName, '.svc'))
Non-human identities: integration users, scheduled jobs, system accounts. Different lifecycle than human accounts โ longer dormant threshold, NHI ownership review. Heuristic via UPN naming convention; refine the rule if your tenant uses different prefixes.
โ Microsoft-managed system accounts โ โซ excluded (opt-in)
- business_id_suffix:
excluded-system - purpose_class:
service - native_filter:
startswith(userPrincipalName, 'Sync_') or startswith(userPrincipalName, 'ADToAADSyncServiceAccount')
Built-in tenant-system accounts (Directory Sync, On-Premises Directory Synchronization Service, etc.). Managed by Microsoft โ IGA should NEVER include them in workflows.
Default write-mappings (13)
Surfaced in the wizard PROVISIONING_CONFIG_REVIEW step for activation. sync_mode and per-type scoping are tunable per mapping.
| target_field | operator | source / expression | sync_mode | job_type | applies_to |
|---|---|---|---|---|---|
displayName |
passthrough |
identity.display_name |
enforce |
* |
all types |
givenName |
passthrough |
identity.first_name |
enforce |
* |
all types |
surname |
passthrough |
identity.last_name |
enforce |
* |
all types |
mail |
passthrough |
identity.email |
enforce |
* |
all types |
jobTitle |
passthrough |
identity.function |
enforce |
* |
all types |
department |
passthrough |
identity.department |
enforce |
* |
all types |
usageLocation |
passthrough |
identity.location |
enforce |
* |
all types |
employeeId |
passthrough |
identity.employee_id |
set_once |
* |
all types |
manager |
lookup |
find_user_by_upn |
enforce |
* |
all types |
accountEnabled |
expression |
{identity.status|lower} |
enforce |
* |
all types |
userPrincipalName |
passthrough |
identity.email |
set_once |
* |
all types |
userPrincipalName |
expression |
admin.{identity.email|lower} |
set_once |
* |
all types |
extensionAttribute1 |
constant |
admin |
set_once |
* |
all types |
Default lookups (3)
Helper lookups used by the write-mappings above (e.g. manager-FK resolution).
- ๐ find_user_by_upn โ looks up
usersviauserPrincipalName eq '{{ value }}'returningid(cache:per_job)
Find a user by user principal name (UPN) โ for manager_id, owner refs, and cross-system identity correlation.
- ๐ find_group_by_name โ looks up
groupsviadisplayName eq '{{ value }}'returningid(cache:per_job)
Find a group by displayName โ for group-membership writes where the admin only knows the name.
- ๐ find_directoryrole_by_name โ looks up
directoryRolesviadisplayName eq '{{ value }}'returningid(cache:per_job)
Find a directory role by displayName (Global Administrator, Privileged Role Administrator, โฆ).
Onboarding setup checklist
Create an Entra app registration with Microsoft Graph permissions, collect tenant_id + client_id + secret, and paste them below. Takes ~5 minutes in a clean tenant.
Estimated time: ~5 min. The wizard exposes this checklist as a drawer (๐ button) during onboarding. See the Onboarding wizard walkthrough for context.