Audit Logs End Userconsentstoppedduetorisk Basedconsent
Query
AuditLogs
| where OperationName has "Consent to application" and Result == "failure" and ResultReason has "UserConsentBlockedForRiskyAppsException"
| extend
Initiator = iif(isnotempty(InitiatedBy["app"]), tostring(InitiatedBy["app"]["displayName"]), tostring(InitiatedBy["user"]["userPrincipalName"])),
InitiatorId = iif(isnotempty(InitiatedBy["app"]), tostring(InitiatedBy["app"]["servicePrincipalId"]), tostring(InitiatedBy["user"]["id"])),
IPAddress = tostring(InitiatedBy[tostring(bag_keys(InitiatedBy)[0])]["ipAddress"])
| extend
AppDisplayName = tostring(TargetResources[0]["displayName"])
| mv-apply modifiedProperty = TargetResources[0]["modifiedProperties"] on (
summarize BagToUnpack = make_bag(pack(tostring(modifiedProperty["displayName"]), pack("oldValue", trim(@'[\"\s]+', tostring(modifiedProperty["oldValue"])), "newValue", trim(@'[\"\s]+', tostring(modifiedProperty["newValue"])))))
)
| evaluate bag_unpack(BagToUnpack, columnsConflict='replace_source')
| extend
AdminConsent = tostring(column_ifexists("ConsentContext.IsAdminConsent", dynamic(null))["newValue"]),
OnBehalfOfAllUsers = tostring(column_ifexists("ConsentContext.OnBehalfOfAll", dynamic(null))["newValue"]),
ActionReason = tostring(column_ifexists("ConsentAction.Reason", dynamic(null))["newValue"]),
Permissions = extract_all(@"PrincipalId: ([a-f0-9]{8}\-[a-f0-9]{4}\-[a-f0-9]{4}\-[a-f0-9]{4}\-[a-f0-9]{12})?, ResourceId: ([a-f0-9]{8}\-[a-f0-9]{4}\-[a-f0-9]{4}\-[a-f0-9]{4}\-[a-f0-9]{12}), ConsentType:\s+(\w+), Scope:\s+([^,]+)", extract(@"\=\>\s+(.*)", 1, tostring(column_ifexists("ConsentAction.Permissions", dynamic(null))["newValue"])))
| mv-apply Permissions on (
extend PermissionsDict = bag_pack("ConsentType", tostring(Permissions[2]), "TargetId", tostring(Permissions[0]), "PermissionsResourceId", tostring(Permissions[1]), "Scope", array_sort_asc(split(Permissions[3], ' ')))
| summarize Permissions = make_list(PermissionsDict)
)
| extend
Target = iff(InitiatorId == Permissions[0]["TargetId"], Initiator, ""),
TargetId = tostring(Permissions[0]["TargetId"])
| project
TimeGenerated,
LoggedByService,
Category,
Initiator,
IPAddress,
OperationName,
Result,
ResultReason,
ActionReason,
Target,
AppDisplayName,
Permissions,
AdminConsent,
OnBehalfOfAllUsers,
InitiatorId,
TargetId,
InitiatedBy,
AdditionalDetails,
TargetResources,
CorrelationIdExplanation
This query is designed to analyze audit logs for failed attempts to consent to applications, specifically when the failure is due to a "UserConsentBlockedForRiskyAppsException." Here's a breakdown of what the query does in simple terms:
-
Filter Logs: It starts by filtering the
AuditLogstable to find entries where the operation name includes "Consent to application" and the result is a failure due to a specific reason related to risky apps. -
Extract Information: The query extracts and extends several pieces of information:
- Initiator: Identifies who initiated the operation, either an app or a user.
- InitiatorId: The ID of the initiator, whether it's an app's service principal ID or a user's ID.
- IPAddress: The IP address from which the operation was initiated.
- AppDisplayName: The display name of the application involved in the consent operation.
-
Unpack Modified Properties: It processes the modified properties of the target resources to create a structured bag of old and new values.
-
Extract Consent Details: It extracts specific consent-related details:
- AdminConsent: Whether the consent was given by an admin.
- OnBehalfOfAllUsers: Whether the consent was intended for all users.
- ActionReason: The reason for the consent action.
- Permissions: Details about the permissions involved, including consent type, target ID, resource ID, and scope.
-
Process Permissions: It further processes the permissions to create a list of permission dictionaries, detailing consent type, target ID, resource ID, and scope.
-
Identify Target: It checks if the initiator ID matches the target ID from the permissions and assigns the initiator as the target if they match.
-
Project Results: Finally, it selects and organizes the relevant columns to be displayed in the output, including details about the operation, initiator, application, permissions, and additional context.
Overall, this query is used to analyze and understand failed application consent attempts, focusing on identifying the initiator, the application involved, and the specific permissions and reasons related to the failure.
Details

Jose Sebastián Canós
Released: August 8, 2025
Tables
Keywords
Operators