Entra ID Permission Visibility Expansion
Surfaces cloud-native attack paths in your Entra ID tenant: abusable application permissions, OAuth2 delegated grants, Conditional Access coverage, PIM eligible roles, and guest user identification.
Requires role: Operator (graph exploration and analysis); Admin (trigger syncs) Related: Entra ID Setup | Over-Permission Analytics | Identity Graph & Simulation | Risk Posture Dashboard
Overview
By default, GraphnAI collects group memberships, role assignments, ownership, and application role assignments from Entra ID. This expansion adds four new categories of visibility that are critical for detecting cloud privilege escalation paths:
Abusable MS Graph application permissions — Service principals that hold dangerous Microsoft Graph API permissions (such as
Application.ReadWrite.All) can escalate to Global Administrator with no additional steps. These are detected automatically during Entra sync and surfaced as permission edges in the graph.OAuth2 delegated permission grants — When users or administrators consent to applications accessing Microsoft APIs on their behalf, those grants are stored as delegated permissions. Broadly-scoped grants (such as
Mail.ReadWriteorDirectory.ReadWrite.All) represent significant risk if the application is compromised.Conditional Access policy coverage (requires
Policy.Read.All) — Identifies which users and groups are explicitly targeted by your Conditional Access policies, making authentication policy gaps visible in the graph.PIM eligible role assignments (requires
RoleEligibilitySchedule.Read.Directoryand Entra P2) — Users eligible for privileged roles via Privileged Identity Management can activate those roles on demand. These latent privileges are represented as a distinct edge type so they appear in attack path analysis.
Additionally, guest user accounts are flagged with a property that makes them identifiable in graph searches and filters.
No changes to the graph's data structure are required to use features 1 and 2. Features 3 and 4 require additional Microsoft Graph API permissions granted to the GraphnAI app registration.
Prerequisites
- An Entra ID bridge must be configured and at least one sync must have completed. See Entra ID Setup.
- Operator or Admin role in GraphnAI.
- For Conditional Access policy visibility (P1): the
Policy.Read.Allapplication permission must be granted to the GraphnAI app registration in Entra. - For PIM eligible role visibility (P1): the
RoleEligibilitySchedule.Read.Directoryapplication permission must be granted, and the tenant must have an Entra ID P2 license.
What Gets Detected
Abusable MS Graph Application Permissions
When a service principal is granted an application permission on the Microsoft Graph API that can be used to escalate privilege, GraphnAI creates a HasPermission edge from that service principal to the Microsoft Graph service principal. The edge carries the permission name(s) and a severity classification.
The following permissions are detected:
| Permission | Severity | Why It Matters |
|---|---|---|
Application.ReadWrite.All | Critical | Can modify any application in the tenant, enabling persistent backdoor creation |
Directory.ReadWrite.All | Critical | Full directory write access — path to Global Admin |
RoleManagement.ReadWrite.Directory | Critical | Can assign any directory role, including Global Admin |
AppRoleAssignment.ReadWrite.All | High | Can grant any application permission to any principal |
GroupMember.ReadWrite.All | High | Can add members to any group, including privileged groups |
ServicePrincipalEndpoint.ReadWrite.All | High | Can modify service principal configurations |
Group.ReadWrite.All | Medium | Broad group management capability |
Multiple abusable permissions held by the same service principal are consolidated into a single HasPermission edge. The edge's severity reflects the highest-severity permission in the set.
NOTE
This detection runs against data already collected during the existing Entra sync — no additional API calls or permissions are required beyond the baseline setup.
OAuth2 Delegated Permission Grants
When a user or administrator consents to an application accessing a Microsoft API on their behalf, the resulting OAuth2 permission grant is collected and represented as a HasPermission edge in the graph.
Edge direction depends on how the consent was granted:
- Admin-consented grants (
AllPrincipals): edge from the client service principal to the resource service principal. The application can exercise these permissions for any user. - User-consented grants: edge from the consenting user to the resource service principal. The application acts on behalf of that specific user.
Severity classification of delegated scopes:
| Severity | Example Scopes |
|---|---|
| Critical | Directory.ReadWrite.All, RoleManagement.ReadWrite.Directory, Application.ReadWrite.All |
| High | Mail.ReadWrite, Files.ReadWrite.All, Group.ReadWrite.All, User.ReadWrite.All |
| Medium | Mail.Send, Calendars.ReadWrite, Contacts.ReadWrite |
| Low | User.Read, openid, profile, email |
Scopes not listed above default to Medium — unrecognized scopes are treated conservatively to avoid missed findings.
All scopes within a single grant appear in the edge's permissions list. Multiple grants from the same source to the same resource service principal are merged into a single edge.
Conditional Access Policy Coverage (P1)
When the Policy.Read.All permission is granted, Entra sync fetches all Conditional Access policies and creates AppliedPolicy edges from users and groups to the policies that explicitly include them.
This lets you answer questions like:
- Which users have no Conditional Access policy applied?
- Are privileged users covered by MFA-required policies?
- Which groups are excluded from specific policies?
When a policy targets All Users, no individual edges are created (which would create an enormous number of edges). Instead, the policy node receives an appliesToAll property. Analytics can use this flag to identify users who are covered by a catch-all policy but excluded by a more specific one.
AppliedPolicy edges are structural — they are not counted as permissions in over-permission analytics and are not traversed in attack path analysis.
PIM Eligible Role Assignments (P1)
When RoleEligibilitySchedule.Read.Directory is granted and the tenant has an Entra P2 license, Entra sync fetches PIM eligible role assignments. These are roles that a user is configured to activate on demand — they are not currently active but represent latent privilege.
A EligibleForRole edge is created from the principal to the role definition. This edge appears in the graph and is included in Critical Junction analysis (an attacker who compromises an account eligible for Global Admin can activate the role).
Unlike HasRole (which represents an active role assignment), EligibleForRole is displayed separately so you can distinguish between what a principal currently holds versus what they can activate.
If the PIM endpoint returns a 403 (the tenant does not have Entra P2, or the permission is missing), the sync continues normally and logs a warning. PIM data is never required for the sync to succeed.
Guest User Flagging
User accounts where userType is "Guest" in Entra ID are tagged with isGuest: true on the node. This property is visible in the node properties panel in the graph view and can be used to filter search results.
No additional API permissions are needed for guest flagging.
Setting Up P1 Features
P1 features (Conditional Access policy coverage and PIM eligible roles) require additional Microsoft Graph application permissions to be granted to the GraphnAI app registration.
Step 1: Add the Required Permissions
- Navigate to the Entra admin center and open App registrations.
- Select the GraphnAI app registration (named
GraphnAI Platformor the name you chose during setup). - Go to API permissions > Add a permission > Microsoft Graph > Application permissions.
- Add the following permissions:
| Permission | Feature Enabled |
|---|---|
Policy.Read.All | Conditional Access policy edges |
RoleEligibilitySchedule.Read.Directory | PIM eligible role edges |
- Click Grant admin consent for [your tenant] to apply the permissions.
IMPORTANT
Admin consent must be granted by a Global Administrator or Privileged Role Administrator. The permissions will not take effect until consent is granted.
Step 2: Trigger a Sync
After granting the permissions, trigger a new Entra ID sync:
- Log in as an Admin in GraphnAI.
- Navigate to Bridges and select your Entra ID bridge.
- Click Sync Now.
The sync will automatically detect the new permissions and collect Conditional Access and PIM data during the next run. Check the sync log for messages confirming the new data types were collected.
Viewing This Data in the Graph
HasPermission Edges (Abusable App Roles and Delegated Grants)
After sync, open the Graph Explorer and search for a service principal that you know holds sensitive Graph API permissions. The graph will show a HasPermission edge from that service principal toward the Microsoft Graph service principal node. The edge label shows the most severe permission name followed by a count if multiple permissions are consolidated (for example: Application.ReadWrite.All +1).
The edge color reflects severity: red for Critical, orange for High, yellow for Medium.
To find all service principals with abusable Graph permissions:
- Open Graph Explorer or Search.
- Search for
type:ServicePrincipaland filter on the graph to show outgoingHasPermissionedges. - Edges leading to the Microsoft Graph service principal with Critical or High severity indicate abusable app role holders.
EligibleForRole Edges (PIM)
In the graph, EligibleForRole edges appear as dashed lines (distinguishing them from solid HasRole edges for active assignments). Hover over an edge to see the role name and the start/end dates of the eligibility window.
To show or hide these edges, use the View menu in the top navigation bar and toggle the EligibleForRole filter.
AppliedPolicy Edges (Conditional Access)
AppliedPolicy edges connect user and group nodes to Conditional Access policy nodes. These edges use a distinct style in the graph to indicate they are structural (not attack paths).
To see which users are covered by a specific policy:
- Search for the policy by name.
- Focus on the policy node in the graph.
- The incoming edges show all users and groups explicitly included by that policy.
To find users with no Conditional Access coverage, use the Over-Permission Analytics or a search query filtered to identities without any outgoing AppliedPolicy edges and where no covering group exists.
Guest User Nodes
Guest accounts display a "Guest" indicator in the node properties tooltip. To find all guests in your tenant:
- Open Search.
- Filter by
type:Userand look for nodes whereisGuestistruein the properties panel.
How These Edges Affect Analysis
Over-Permission Analytics
HasPermission edges from abusable app roles and OAuth2 delegated grants are counted toward the effective permission total for service principals and users. A service principal holding Application.ReadWrite.All will appear as a significant outlier in its peer group.
AppliedPolicy and EligibleForRole edges are excluded from permission counting — they represent structural relationships, not actionable permissions.
Critical Junction Analysis
The junction engine traverses HasPermission and EligibleForRole edges when computing attack paths to critical assets. A service principal with RoleManagement.ReadWrite.Directory can escalate to Global Admin and will contribute to the junction score of any node on the path to that service principal.
AppliedPolicy edges are not traversed in junction analysis.
Risk Posture Dashboard
HasPermission edges from Entra sources contribute to the over-permission finding counts on the Risk Posture Dashboard. Tenants with many over-consented applications will see more findings in over-permission analytics.
Troubleshooting
No abusable app role edges appear after sync
Cause: The Microsoft Graph service principal may not have been detected in the tenant, or no service principals hold abusable permissions.
Steps:
- Check the sync log for the message
Found MS Graph service principal. If this message is absent, GraphnAI could not locate the Microsoft Graph SP in your tenant (extremely rare). - Verify the service principals in your tenant have not been excluded from sync via attribute filters.
- Confirm the tenant has at least one application with Graph API permissions assigned via app role assignment — not just delegated permissions.
OAuth2 grant edges are not appearing
Cause: The sync may have encountered an error fetching grants, or no grants exist in the tenant.
Steps:
- Review sync logs for
ListOAuth2PermissionGrantserrors. - Confirm the GraphnAI app registration has
Directory.Read.All— this permission covers the OAuth2 grants endpoint and is part of the baseline setup. - If grants exist in the tenant but no edges appear, check that the consenting user or service principal was included in the sync (not filtered out).
Conditional Access edges are missing after adding Policy.Read.All
Cause: Admin consent was not granted, or the sync has not yet run since the permission was added.
Steps:
- In the Entra admin center, verify
Policy.Read.Allappears in the app's API permissions with a green checkmark and shows Granted for [tenant]. - Trigger a new sync from the Bridges page.
- Check sync logs for
Syncing Conditional Access Policies...— if this line is absent, the permission was not detected.
PIM edges are missing
Cause: The tenant does not have an Entra ID P2 license, or RoleEligibilitySchedule.Read.Directory was not granted.
Steps:
- Check the sync log for a warning containing
PIM eligible assignments unavailable. This is expected and normal for tenants without Entra P2 — the sync still completes successfully. - Confirm the tenant license tier in the Entra admin center under Identity > Overview > License features.
- If the tenant has P2, verify
RoleEligibilitySchedule.Read.Directoryhas been granted with admin consent.
Guest users are not showing the isGuest property
Cause: The guest user accounts may not have been included in the most recent sync.
Steps:
- Trigger a full sync from the Bridges page.
- After the sync completes, search for the guest user and check the properties panel —
isGuest: trueshould appear.
Seeing a large number of permission findings
Cause: Over-consented applications and broadly-scoped delegated grants are counted as permission edges. Tenants with many admin-consented applications or broad delegated grants will see more findings in over-permission analytics.
Steps:
- Filter the Over-Permission Analytics view to
ServicePrincipaltype to review app-related findings first. - For each high-severity finding, open the graph view to inspect the specific permissions involved.
- Work with application owners to narrow the scopes of over-consented applications.