Docs menu

Entra ID Permission Visibility: Graph API Permissions, OAuth Grants, Conditional Access and PIM

See the cloud attack paths in your Entra ID tenant: abusable Microsoft Graph API permissions, OAuth 2.0 delegated grants, Conditional Access coverage, Privileged Identity Management (PIM) eligible roles, and guest users.

Roles
Viewer to explore these edges in the graph. Operator for the analysis views. Admin to sync a tenant or change its permissions.
Applies to
Entra ID
Updated
On this page

Overview

GraphnAI collects group memberships, role assignments, ownership and app role assignments from Entra ID. It also collects four data sets that expose cloud privilege escalation paths:

  1. Abusable Microsoft Graph API application permissions. A service principal that holds a permission such as Application.ReadWrite.All can make itself a Global Administrator. Every sync finds these and records them as HasPermission edges.
  2. OAuth 2.0 delegated permission grants. When a user or an administrator consents to an app acting on their behalf, Entra ID stores a delegated grant. A broad grant, such as Mail.ReadWrite or Directory.ReadWrite.All, is a serious risk if the app is compromised. Attackers also abuse them in illicit consent grant attacks.
  3. Conditional Access policy coverage. Shows which users and groups your Conditional Access policies name, so gaps in sign-in policy show up in the graph.
  4. PIM eligible role assignments. A user eligible for a privileged role can activate it on demand. GraphnAI records that latent privilege as its own edge type, EligibleForRole, so attack path analysis includes it.

GraphnAI also flags guest users, and links each app registration to the service principal it runs as. See Entra ID Directory Accuracy.

The first data set needs no extra setup. The other three need an optional Microsoft Graph permission or an Entra ID license. The Data collected from this tenant card on Admin > Identity Providers shows which of them your tenant collects. It also says what each one needs and how to fix a gap. See Entra ID Directory Accuracy.


Prerequisites

  • An Entra ID tenant added on Admin > Identity Providers, with at least one finished sync. See Entra ID Setup.
  • For delegated permission grants: Directory.Read.All, approved for the GraphnAI app registration.
  • For Conditional Access coverage: Policy.Read.All, approved for the GraphnAI app registration.
  • For PIM eligible roles: a tenant with Microsoft Entra ID P2 or Microsoft Entra ID Governance. The permission it uses, RoleManagement.Read.Directory, is one GraphnAI already requires.

What Gets Detected

Abusable Microsoft Graph Application Permissions

A service principal can hold a Microsoft Graph application permission that escalates privilege. GraphnAI then adds a HasPermission edge from it to the Microsoft Graph service principal. The edge lists the permissions and carries a severity.

GraphnAI looks for these permissions:

Permission Severity Why It Matters
Application.ReadWrite.All Critical Can change any application in the tenant, so an attacker can plant a lasting backdoor
Directory.ReadWrite.All Critical Full write access to the directory, a path to Global Administrator
RoleManagement.ReadWrite.Directory Critical Can assign any directory role, including Global Administrator
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 change service principal configurations
Group.ReadWrite.All Medium Broad group management

A service principal's abusable permissions share one HasPermission edge. Its severity is that of the most severe permission in the set.

[!NOTE] GraphnAI finds these in data every Entra ID sync already collects. They need no extra permission.

OAuth 2.0 Delegated Permission Grants

Each OAuth 2.0 permission grant becomes a HasPermission edge. Where it starts depends on who consented:

  • Admin consent for all users (AllPrincipals): from the app's service principal to the resource's service principal. The app can use these permissions for any user.
  • User consent: from the consenting user to the resource's service principal. The app acts on behalf of that one user.

GraphnAI rates each delegated scope:

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, AppRoleAssignment.ReadWrite.All
Medium Mail.Send, Calendars.ReadWrite, Contacts.ReadWrite
Low User.Read, openid, profile, email

A scope not in this list counts as Medium, so an unknown scope is never rated below that. A grant's edge carries the severity of its most severe scope, and its permissions list holds every scope in the grant.

To list the apps with admin consent for all users, open Identity Inventory and choose the NHI: Consent for all users preset.

Conditional Access Policy Coverage

With Policy.Read.All approved, each Entra ID sync reads your Conditional Access policies. For every policy that isn't disabled, GraphnAI adds an AppliedPolicy edge from each user and group the policy names to the policy.

This answers questions such as:

  • Which users have no Conditional Access policy?
  • Are privileged users covered by policies that require MFA?
  • Which groups does a policy leave out?

A policy that targets All users gets no per-user edges, which would number in the thousands. Instead, the policy carries an appliesToAll property.

PIM Eligible Role Assignments

On a tenant with Microsoft Entra ID P2 or Microsoft Entra ID Governance, each Entra ID sync reads PIM eligible role assignments. These are roles a principal can activate on demand but doesn't hold right now.

GraphnAI adds an EligibleForRole edge from the principal to the role. Critical Junctions analysis follows it, because an attacker who takes over an account eligible for Global Administrator can activate the role. A HasRole edge is an active assignment, so the two show separately: what a principal holds, and what it could activate.

If Microsoft refuses the PIM request, because the tenant lacks the license or the permission, the sync continues without it. The Privileged Identity Management row on the coverage card shows why.

Guest User Flagging

Users whose userType is Guest in Entra ID get the property isGuest: true. It shows as Is guest in the user's detail panel. Guest flagging needs no extra permission.


Setting Up Conditional Access and PIM

Conditional Access coverage needs Policy.Read.All. PIM needs only the license.

Step 1: Add the Required Permission

The quickest way is Update the app registration on the Data collected from this tenant card. See Updating an existing app registration. To do it by hand:

  1. In the Microsoft Entra admin center, open App registrations.
  2. Select the GraphnAI app registration, named GraphnAI Platform unless you chose another name.
  3. Go to API permissions > Add a permission > Microsoft Graph > Application permissions.
  4. Add Policy.Read.All.
  5. Select Grant admin consent for [your tenant].

[!IMPORTANT] A Global Administrator or Privileged Role Administrator must grant admin consent. The permission does nothing until then.

Step 2: Trigger a Sync

  1. In GraphnAI, open Admin > Identity Providers as an Admin.
  2. Choose your Entra ID tenant from the provider menu.
  3. Select Sync now.

When the sync finishes, the Conditional Access policies row on the coverage card reads Collected.


Viewing This Data in the Graph

HasPermission Edges (Abusable App Permissions and Delegated Grants)

In the Graph Explorer, search for a service principal that holds sensitive Graph permissions. A HasPermission edge runs from it to the Microsoft Graph service principal. The label names one permission and adds a count for the rest, such as Application.ReadWrite.All +1. Select the edge to see every permission it carries. See Relationship Detail Drill-Down.

To see every service principal with abusable Graph permissions, focus the Microsoft Graph service principal. Its incoming HasPermission edges come from them.

EligibleForRole Edges (PIM)

An eligible role isn't active until the principal activates it, so the graph draws it as blocked: a dashed, dimmed slate line labeled Eligible for role (blocked). An active HasRole assignment is a solid line.

AppliedPolicy Edges (Conditional Access)

AppliedPolicy edges join users and groups to Conditional Access policies. They're drawn in the neutral gray the graph uses for edge types without a color of their own.

To see who a policy covers:

  1. Search for the policy by name.
  2. Focus the policy in the graph.
  3. Its incoming edges are the users and groups the policy names.

Guest Users

A guest user's detail panel lists Is guest. Identity Inventory doesn't filter on it.


How These Edges Affect Analysis

Over-Permission Analytics

HasPermission edges from abusable app permissions and delegated grants count toward the effective permission total of service principals and users. A service principal that holds Application.ReadWrite.All stands out as a finding in its peer group.

AppliedPolicy and EligibleForRole edges don't count as permissions.

Critical Junctions Analysis

The junction engine follows HasPermission and EligibleForRole edges when it works out attack paths to critical assets. A service principal with RoleManagement.ReadWrite.Directory can make itself a Global Administrator, so it adds to the junction score of every identity on a path to it.

The junction engine doesn't follow AppliedPolicy edges.

Risk Posture Dashboard

HasPermission edges from Entra ID count toward the over-permission findings on the Risk Posture Dashboard. A tenant with many over-consented apps shows more findings.


Troubleshooting

No abusable app permission edges appear after a sync

Cause: No service principal holds one of the listed permissions, or GraphnAI didn't find the Microsoft Graph service principal in the tenant.

Steps:

  1. Check the server log for Found MS Graph service principal. If the line is missing, GraphnAI didn't find the Microsoft Graph service principal. This is rare.
  2. Check that at least one app holds Graph permissions as application permissions. Delegated permissions show up as grants instead.

Delegated grant edges don't appear

Cause: Directory.Read.All isn't approved, grant collection is turned off, the read failed, or the tenant has no grants.

Steps:

  1. Open Admin > Identity Providers and check the Delegated permission grants row on the coverage card. Its badge and line say what's wrong.
  2. If a grant exists but has no edge, check that the consenting user or app's service principal was collected.

Conditional Access edges are missing after you added Policy.Read.All

Cause: Admin consent wasn't granted, or no sync has run since.

Steps:

  1. In the Microsoft Entra admin center, check that Policy.Read.All shows a green check and Granted for [your tenant].
  2. Select Sync now on Admin > Identity Providers.
  3. Check the Conditional Access policies row on the coverage card. Collected means the policies were read. Disabled policies get no edges.

PIM edges are missing

Cause: The tenant has no Microsoft Entra ID P2 or Microsoft Entra ID Governance license, or PIM collection is turned off.

Steps:

  1. Check the Privileged Identity Management row on the coverage card. Not on this license is expected for a tenant without P2 or Governance, and the sync still succeeds.
  2. Check the tenant's license in the Microsoft Entra admin center under Identity > Overview > License features.
  3. If the row reads Turned off, turn it back on in the Sync features list under Sync attributes, from the gear icon at the top of the page.

A guest user doesn't show Is guest

Cause: The user wasn't in the last sync, or changed to a guest after it.

Steps:

  1. Select Sync now on Admin > Identity Providers.
  2. When the sync finishes, open the user's detail panel and look for Is guest.

You see many more permission findings

Cause: Over-consented apps and broad delegated grants count as permissions. A tenant with many admin-consented apps or broad grants shows more over-permission findings.

Steps:

  1. In Identity Inventory, open the Service principals tab with the Over-permissioned preset to review app findings first.
  2. For each high-severity finding, open the graph and check which permissions it holds.
  3. Work with each app's owner to narrow its scopes.

    ↑↓ to move, Enter to open