Join our Newsletter — 33% off our NHI Course
Home› Guides› How to detect OAuth consent phishing in Entra…
Guide Identity Visibility, Posture & Threat Detection

How to detect OAuth consent phishing in Entra ID: audit events, detection rules and response steps

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 11 November 2026 15 min read
On this page

A user who clicks "Accept" on a malicious app's consent screen hands the attacker a refresh token for their mailbox and files, and no password, MFA prompt or password reset stands in the way afterwards. This guide shows how to detect OAuth consent phishing in Microsoft Entra ID: which audit events and fields record a consent, which rules separate a phishing grant from a user adding a calendar tool, how to sweep grants that already exist, and how to respond without letting the app come straight back. It is written for SOC analysts, detection engineers and Entra administrators working in Microsoft Sentinel, Defender XDR or another SIEM fed with Entra audit logs. The attack itself, and how it differs from token theft and device code phishing, is explained in the Consent Phishing and Illicit OAuth Grants Guide; consent settings and the application model are in the Entra ID Applications and Consent Guide. This page is the detection runbook.

Key takeaways

  • One event carries the signal: every grant writes "Consent to application" in the Entra audit log (category ApplicationManagement, service Core Directory), with the scopes in ConsentAction.Permissions and admin consent in ConsentContext.IsAdminConsent.
  • Scopes decide severity: Microsoft reports that a combination of Mail, Contacts, MailboxSettings, People, Files and Notes permissions is the pattern most consent phishing attacks request; offline_access next to mailbox scopes is the high-fidelity pairing.
  • Rarity beats allow lists: a consent by a user who has never consented before, or to an app nobody else in the tenant uses, is a better trigger than a list of bad app names, which attackers change daily.
  • Sweep existing grants: delegated grants have no creation date on the Graph object and the portal shows admin consents for only 90 days, so pair the audit history with a full export of oauth2PermissionGrant objects.
  • Disable before you delete: Microsoft advises disabling a malicious service principal rather than deleting it, because a deleted app can return the next time another user consents.

When you need this

  • User consent is still on: by default, Entra users can consent to permissions that do not need admin consent. Until consent is restricted, every user is a possible approver for an attacker's app.
  • After a phishing campaign with no credential prompt: consent phishing links go to the real Microsoft sign-in page, so users and mail filters report "it was a genuine Microsoft page". The 2022 case where fraudulent partner accounts obtained the verified publisher badge shows the badge alone is not proof of trust. See the Microsoft Verified Publisher OAuth Phishing 2022 breach analysis.
  • When mailbox rules or data access appear with no risky sign-in: an app acting on a delegated token produces Graph or EWS activity under the user's identity, often without any interactive sign-in. This is where business email compromise investigations stall if nobody checks consents.

Before you start

ItemWhere it livesWhat you need from it
Consent eventEntra audit log; in Sentinel the AuditLogs table; also the Microsoft Purview audit logOperationName "Consent to application", Result, InitiatedBy user and IP, TargetResources of type ServicePrincipal, AdditionalDetails User-Agent
Related eventsSame log"Add service principal" (first time the app appears in your tenant), "Add delegated permission grant" or "Add OAuth2PermissionGrant", "Add app role assignment to service principal" (application permissions), "Add service principal credentials"
Key modified propertiesTargetResources[].modifiedPropertiesConsentContext.IsAdminConsent, ConsentAction.Permissions (string containing ConsentType: and Scope:), TargetId.ServicePrincipalNames
Blocked attemptsSame log, status reason "Risky application detected"Risk-based step-up consent stopped a user and showed AADSTS90094; repeated attempts for one app mean a campaign
Current grantsMicrosoft Graph oauth2PermissionGrant and appRoleAssignmentclientId, consentType (AllPrincipals or Principal), principalId, resourceId, scope
App behaviourDefender for Cloud Apps app governance, if licensedAlerts such as "OAuth App with suspicious Reply URL" and "App with suspicious OAuth scope made graph calls to read email and created inbox rule"
  • Latency: Microsoft states audit entries can take from 30 minutes to 24 hours to appear in audit search. Stream Entra audit logs to the SIEM through diagnostic settings rather than relying on portal searches, and set rule look-back windows that tolerate late events.
  • Auditing must already be on: scoping what an app did depends on mailbox auditing and activity auditing having been enabled before the consent. Check this now, not during the incident.
  • Test consent: register a harmless test app in a lab tenant, consent to User.Read and offline_access as a normal user, and confirm the event reaches the SIEM with the scope string parsed. Field layouts change; match on property display names, not array positions.
  • Least privilege for the sweep: reading every grant needs directory-wide read permissions such as Application.Read.All. Run the export under a dedicated identity with read-only scopes and a named owner. See the Service Account Security Guide.

Step-by-step

  1. Collect the events. Send Entra audit logs, sign-in logs and non-interactive user sign-in logs to the SIEM. Filter the consent rules on LoggedByService == "Core Directory" and Category == "ApplicationManagement", as Microsoft's own Sentinel rules do.
  2. Parse the consent string. Extract ConsentAction.Permissions from the ServicePrincipal target, then parse out ConsentType and Scope. Split the scope string on spaces and compare exact scope names: Microsoft notes in its rule comments that term matching on "Mail.Read" also matches Mail.ReadBasic.
  3. Build a consent baseline. Summarise 7 to 30 days of consents by initiating user and by app. Microsoft's "Rare application consent" rule excludes any user or app that consented more than three times in the previous seven days and alerts on the rest.
  4. Deploy the rules below in report mode for two weeks, labelling each hit as legitimate, policy violation or malicious.
  5. Run the grant sweep (next section) so you are not only watching new consents.
  6. Wire the response so that a confirmed hit disables the app, removes the grants and starts the mailbox scoping in one ticket.

Detection rules

RuleLogicWhy it worksPriority (ours)
Mailbox scopes with offline access"Consent to application" where parsed scopes contain offline_access and any of Mail.Read, Mail.ReadWrite, Mail.Send, MailboxSettings.ReadWrite, consent type not AllPrincipalsThe pairing gives long-lived silent mailbox access; Microsoft ships this as a High severity ruleHigh
Offline access to collaboration data by unknown appSame, with Files, Chat, ChannelMessage, Notes, EWS.AccessAsUser.All or EAS.AccessAsUser.All scopes, app client ID not in your known-app listCovers file and Teams exfiltration appsHigh
Rare consenter or rare appConsent by a user with no consent in the look-back, or to an app with no prior consent in the tenantPhishing targets people who do not usually consent and apps that are new to youMedium
Unexpected admin consentConsentContext.IsAdminConsent is True, or consent type AllPrincipals, without a matching change ticket or admin consent workflow approvalOne admin click grants the app every user's dataHigh
Application permissions granted"Add app role assignment to service principal" for a Microsoft Graph app role such as Mail.Read or Files.Read.AllApp-only access needs no user at allHigh
BurstSame app consented by several users within an hour, or many "Risky application detected" entries for one appA mass phishing campaign in progressHigh
Consent after risky sign-inConsent within 24 hours of a risky, unfamiliar-country or unfamiliar-ASN sign-in by the same userAn attacker in a session consents to keep access after the password is resetHigh
Consent then credentialConsent to an app, followed by "Add service principal credentials" on the same service principal by a different actorShipped by Microsoft as "Credential added after admin consented to Application"Medium
High-impact userAny consent by executives, finance approvers or administratorsMicrosoft's guidance singles out consents by high-value usersMedium

A minimal KQL starting point for the first rule, adapted from Microsoft's published Sentinel rule "End-user consent to app with mailbox and offline access delegated scopes":

AuditLogs
| where TimeGenerated > ago(1d)
| where LoggedByService =~ "Core Directory" and Category =~ "ApplicationManagement"
| where OperationName =~ "Consent to application" and Result =~ "success"
| mv-apply T = TargetResources on (where T.type =~ "ServicePrincipal"
    | extend AppName = tostring(T.displayName), SpId = tostring(T.id), Props = T.modifiedProperties)
| mv-apply P = Props on (where P.displayName =~ "ConsentAction.Permissions"
    | extend Consent = trim(@'"', tostring(P.newValue)))
| parse Consent with * "ConsentType: " ConsentType ", Scope: " Scope "]" *
| extend Scopes = split(Scope, " ")
| where set_has_element(Scopes, "offline_access")
| where set_has_element(Scopes, "Mail.Read") or set_has_element(Scopes, "Mail.ReadWrite")
    or set_has_element(Scopes, "Mail.Send") or set_has_element(Scopes, "MailboxSettings.ReadWrite")
| where ConsentType != "AllPrincipals"
| project TimeGenerated, User = tostring(InitiatedBy.user.userPrincipalName),
    IP = tostring(InitiatedBy.user.ipAddress), AppName, SpId, ConsentType, Scope, CorrelationId

Use the same parse block for the other scope rules and change only the scope test. For the admin consent rule, read the ConsentContext.IsAdminConsent property the same way. The KQL for Threat Hunting Guide covers the operators used here.

Sweep existing grants

Alerts only see new consents. Grants made months ago, under looser settings, are still valid. Microsoft recommends a weekly review of consent grants in large tenants.

  1. Export delegated grants. List all oauth2PermissionGrant objects with Microsoft Graph (Get-MgOauth2PermissionGrant -All) or Microsoft's Get-AzureADPSPermissions.ps1 script, which writes Permissions.csv. Resolve clientId (the service principal object ID, not the appId) to the app name, publisher tenant and verified publisher status.
  2. Export application permissions with GET /servicePrincipals/{id}/appRoleAssignments for every non-Microsoft service principal.
  3. Flag the high-risk set: consent type AllPrincipals on non-Microsoft apps; any Mail.* except Mail.ReadBasic*, Contacts.*, MailboxSettings.*, People.*, Files.*, Notes.*, Directory.AccessAsUser.All or user_impersonation; and grants held by a single user to an app nobody else uses.
  4. Inspect app metadata for Microsoft's red flags: misspelled, bland or "hacker-sounding" names, a reply URL on a recently registered, temporary or unrelated domain, no terms of service link, and a publishing tenant that is new.
  5. Join to the audit history for when and from where each flagged grant was made. Where the audit log no longer covers it, treat the grant as unexplained and ask the user.
FindingLikely meaningAction
One user, unknown app, mailbox scopes plus offline_accessConsent phishing until proven otherwiseTriage now; disable the app pending answers
Many users, same unverified app, read scopesPopular unsanctioned tool or a campaignCheck consent dates for a burst; route to app owner review
AllPrincipals grant, no change recordAdmin consent outside process, or a compromised adminReview the consenting admin's sign-ins; confirm with the admin
Grant to an app Microsoft has disabledApp removed by Microsoft for a terms violationRemove grants and check what the app did before it was disabled
Old grant, app shows no sign-in activity for 90 daysAbandoned integrationRemove through normal access review
  • Did the user mean to do it? Ask through a channel the attacker cannot see: a call, or the user's manager. Ask what the app was supposed to do and where the link came from.
  • What is the app? Publisher, verified status, home tenant, reply URLs, creation date, number of users in your tenant who consented. Check Defender for Cloud Apps for app governance alerts on the same app ID.
  • What did it do? Look for non-interactive sign-ins and Microsoft Graph activity with the app's ID after the consent time, mail read and send volume, new inbox rules, file downloads and sharing. App governance alerts such as "App creates inbox rule and made unusual email searches activities" answer this quickly where licensed.
  • What else happened? Sign-ins before the consent, MFA method changes and new credentials on the service principal. See How to detect new credentials added to an app registration.
  • Is it wider? Search the same app ID and the same sender or URL across all users and all consents in the look-back.

Respond to a malicious grant

  1. Preserve evidence: export the audit entries, the grant objects and the app's service principal details (including reply URLs) before you change anything.
  2. Disable the service principal (set sign-in to disabled on the enterprise application). Microsoft states a disabled app cannot obtain new tokens and users cannot sign in or consent to it, while a deleted app may return when another user consents.
  3. Remove the grants: delegated grants with Remove-MgOauth2PermissionGrant or DELETE /oAuth2PermissionGrants/{id}, and application permissions by deleting the app role assignments. User consent grants cannot be revoked in the portal's User consent tab, so use Graph or PowerShell.
  4. Revoke the user's sessions and refresh tokens for every affected user so already-issued tokens stop working sooner, and reset passwords where the sign-in history suggests the account itself was also compromised. See the OAuth Token Theft Incident Playbook.
  5. Clean the mailbox: remove inbox and forwarding rules the app created and check sent items for internal phishing. Follow the Business Email Compromise Response Playbook if mail was sent or read.
  6. Block re-consent: restrict user consent before closing the incident, because revoking a grant does not stop users consenting again.
  7. Contact Microsoft Support about the app, as Microsoft's guidance advises after disabling it.

Rollback: if an app turns out to be legitimate, re-enable the service principal and have the user or an administrator consent again through the admin consent workflow; record the decision so the rule can allow-list the app ID rather than the name.

Prevention that makes detection easier

Consent settingPolicy ID or featureEffect on detectionFits
Allow user consent for appsmicrosoft-user-default-legacyHighest alert volume; every user can approve any non-admin permissionNot recommended
Allow user consent for apps from verified publishers, for selected permissionsmicrosoft-user-default-low, with permission classificationsOnly low-impact permissions from verified publishers and your own apps; most phishing scopes need admin approvalMost organisations
Do not allow user consentNo policy assigned to the default user roleEvery request becomes an admin decision; user consent alerts become rare and high signalRegulated or high-risk tenants with a responsive approval team
Admin consent workflowEnterprise apps, Consent and permissions, Admin consent settingsGives a legitimate path, so unexplained admin consents stand outAll, alongside restricted user consent
  • Small organisations: choose verified publishers with low-impact permissions, turn on the admin consent workflow and run the High priority rules plus a monthly sweep.
  • Large organisations: disable or tightly restrict user consent, put all consent requests through the workflow with a defined approval time, use app governance where licensed and run the sweep weekly.

Verify it worked

  • Replay: in a test tenant, consent as a normal user to a test app requesting Mail.Read and offline_access; the High rule should fire within your target time allowing for audit latency.
  • Blocked path: after restricting consent, the same test should produce an admin consent request or "Risky application detected", not a grant.
  • Removal: after response, re-list grants for the app and confirm none remain and no new tokens have been issued since the disable time.

Measures that show it is working

  • Median time from "Consent to application" to analyst triage for High rules.
  • Number of non-Microsoft apps holding AllPrincipals grants or mailbox scopes, trending down.
  • Percentage of consents that went through the admin consent workflow.
  • Grants found by the sweep that no alert had raised (should fall to near zero).
  • Median admin consent request approval time.

Common failure patterns

  • Allow listing by display name: attackers copy legitimate names. Allow-list app IDs and publisher tenant IDs.
  • Term matching on scopes: has "Mail.Read" also matches Mail.ReadBasic and inflates noise until the rule is muted. Split and compare exact scopes.
  • Short look-back windows: a one-hour rule window with up to 24 hours of audit latency silently misses events. Use a daily window or ingestion-time filtering.
  • Deleting the app: the next user who clicks the link recreates it. Disable it and block consent first.
  • Revoking grants but not sessions: tokens already issued keep working for their lifetime; combine grant removal with session revocation.
  • Ignoring admin consent: the Midnight Blizzard intrusion at Microsoft shows how OAuth applications granted broad permissions turn one foothold into executive mailbox access. See the Microsoft Midnight Blizzard Breach 2024.

Framework mapping

FrameworkReferenceHow this detection supports it
MITRE ATT&CK v20T1528 Steal Application Access Token; T1566.002 Spearphishing Link; T1550.001 Application Access Token; T1078.004 Cloud AccountsDetects the grant that yields the token and the later use of it
NIST SP 800-53 Rev 5AC-6 Least Privilege; AC-2(12) Account Monitoring for Atypical Usage; AU-6 Audit Record Review, Analysis, and Reporting; SI-4 System Monitoring; CM-7 Least FunctionalityRestricts and monitors third-party access granted by users
NIST CSF 2.0PR.AA-05; DE.CM-03; DE.AE-02Permission management, activity monitoring and event analysis

Practitioner checklist

  • Stream Entra audit, sign-in and non-interactive sign-in logs to the SIEM with a retention that covers your sweep look-back.
  • Confirm mailbox and activity auditing is enabled for all users.
  • Parse ConsentAction.Permissions and ConsentContext.IsAdminConsent; match exact scope names.
  • Deploy mailbox plus offline_access, admin consent and burst rules first, in report mode.
  • Export all delegated grants and app role assignments and review the high-risk set weekly or monthly.
  • Respond in order: preserve, disable, remove grants, revoke sessions, clean mailbox, block re-consent, report.
  • Restrict user consent to verified publishers and low-impact permissions, or disable it, and run the admin consent workflow.
  • Scope the identity that runs the sweep to read-only permissions with a named owner.

Standards and references

Related NHI Mgmt Group resources: Consent Phishing and Illicit OAuth Grants Guide · Entra ID Applications and Consent Guide · Entra ID Sign-In and Audit Log Detection Guide · How to detect use of a stolen OAuth refresh token · MITRE ATT&CK T1528 Steal Application Access Token Guide

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 11 November 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org