Confirm the consent event
Microsoft's documented consent-phishing behavior maps directly to the Entra application-consent audit trail.
View query
Q-01Recover the OAuth consent event
What this checks
Find successful application-consent events for denis@example.com and preserve the app, service-principal, IP, permissions, consent type, and correlation context.
KQL
let target_user = "denis@example.com";
AuditLogs
| where TimeGenerated >= ago(7d)
| where LoggedByService =~ "Core Directory"
| where Category =~ "ApplicationManagement"
| where OperationName =~ "Consent to application"
| where Result =~ "success"
| extend
InitiatingUser = tolower(tostring(InitiatedBy.user.userPrincipalName)),
InitiatingIP = tostring(InitiatedBy.user.ipAddress)
| where InitiatingUser == tolower(target_user)
| mv-apply TargetResource = TargetResources on (
where TargetResource.type =~ "ServicePrincipal"
| extend
AppDisplayName = tostring(TargetResource.displayName),
ServicePrincipalId = tostring(TargetResource.id),
ModifiedProperties = TargetResource.modifiedProperties
)
| mv-apply Property = ModifiedProperties on (
where Property.displayName =~ "ConsentAction.Permissions"
| extend ConsentFull = trim(@'"', tostring(Property.newValue))
)
| parse ConsentFull with * "ConsentType: " ConsentType ", Scope: " GrantScope "]" *
| project
TimeGenerated,
InitiatingUser,
InitiatingIP,
AppDisplayName,
ServicePrincipalId,
ConsentType,
GrantScope,
CorrelationId
| order by TimeGenerated ascSPL
index=<entra_audit_index> sourcetype=<entra_audit_sourcetype>
earliest=-7d
(OperationName="Consent to application" OR ActivityDisplayName="Consent to application")
| eval
user=lower(coalesce(user, userPrincipalName, InitiatedByUserPrincipalName)),
src=coalesce(src, ipAddress, InitiatingIpAddress),
app_name=coalesce(app_name, TargetResourceDisplayName, AppDisplayName),
service_principal_id=coalesce(service_principal_id, TargetResourceId, ServicePrincipalId),
permissions=coalesce(permissions, ConsentActionPermissions, GrantScope),
consent_type=coalesce(consent_type, ConsentType),
correlation_id=coalesce(correlation_id, CorrelationId),
result=lower(coalesce(result, Result))
| where user="denis@example.com" AND result="success"
| fields _time user src app_name service_principal_id permissions consent_type correlation_id
| sort 0 _timeWhat to look for
A successful consent event for the affected user that identifies the target app and preserves the granted scope string.
Technical details
Tested signal
Successful Consent to application activity initiated by the affected user.
Assumptions
- Microsoft Entra AuditLogs is retained for the review period.
- The consent event retains the target-resource permission details required to recover the granted scopes.
Data requirements and relevant fields
- identity
Entra application-management audit events with initiating user, source IP, target service principal, modified properties, result, and correlation ID.
TimeGeneratedLoggedByServiceCategoryOperationNameResultInitiatedByTargetResourcesAdditionalDetailsCorrelationId
KQL schema
Uses documented Microsoft Entra/Azure Monitor fields; validate connector availability and local retention.
SPL schema
Replace index/sourcetype placeholders and map the documented concepts to the local Entra audit or sign-in source.
Limitations
- Some export pipelines flatten TargetResources differently.
- The app display name is not a stable security boundary; preserve the service-principal identifier and CorrelationId.
The KQL follows Microsoft Entra AuditLogs application-consent semantics. SPL intentionally uses a normalized raw scaffold because consent permission fields are not consistently represented by CIM.
More reasoning
Observation
An unexpected OAuth application consent preceded the persistent-access concern.
Working explanation
The affected user may have granted a third-party service principal access through a legitimate Entra consent flow.
What was checked
Recover the Consent to application event, target service principal, initiating IP, permissions, consent type, and CorrelationId.
Interpretation
The consent event is the primary evidence object and should preserve stable application identifiers rather than rely on display name alone.