Query Details
let query_frequency = 1h;
let query_period = 14d;
AADServicePrincipalRiskEvents
| where TimeGenerated > ago(query_period)
| summarize
ConfirmedTimeGenerated = maxif(TimeGenerated, RiskState == "confirmedCompromised"),
arg_min(TimeGenerated, *)
by Id
| where case(
isnotempty(ConfirmedTimeGenerated), false,
isempty(ActivityDateTime) and isempty(DetectedDateTime) and isnotempty(LastUpdatedDateTime) and RiskState == "dismissed", false,
//RiskDetail == "aiConfirmedSigninSafe" and RiskState == "dismissed", false,
true
)
| summarize arg_min(TimeGenerated, *) by ServicePrincipalId, RiskEventType, DetectionTimingType, RiskLevel, RiskState
| where TimeGenerated > ago(query_frequency)
| extend AlertSeverity = strcat(toupper(substring(RiskLevel, 0, 1)), substring(RiskLevel, 1))
| project
TimeGenerated,
ServicePrincipalDisplayName,
IpAddress,
Location,
OperationName,
RiskEventType,
RiskLevel,
DetectionTimingType,
RiskState,
RiskDetail,
AdditionalInfo,
Activity,
ServicePrincipalId,
AppId,
CorrelationId,
RequestId,
ActivityDateTime,
DetectedDateTime,
LastUpdatedDateTime,
Id,
AlertSeverity
This KQL (Kusto Query Language) query is designed to analyze risk events related to Azure Active Directory (AAD) service principals over a specified period. Here's a simplified breakdown of what the query does:
Define Timeframes:
query_frequency is set to 1 hour, and query_period is set to 14 days. These are used to filter the data based on time.Filter Recent Events:
AADServicePrincipalRiskEvents table that have occurred within the last 14 days.Summarize Events:
Id, capturing the latest time an event was confirmed as compromised (ConfirmedTimeGenerated) and the earliest occurrence of each event.Filter Out Certain Events:
ActivityDateTime and DetectedDateTime are empty, but LastUpdatedDateTime is not empty, and the risk state is "dismissed", it is excluded.Further Summarization:
Filter Recent Summarized Events:
Add Alert Severity:
AlertSeverity by capitalizing the first letter of the RiskLevel and appending the rest of the string.Select Relevant Columns:
In essence, this query identifies and processes recent risk events related to AAD service principals, focusing on those that are not confirmed as compromised or dismissed under certain conditions, and presents them with relevant details and a calculated alert severity.

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