Query Details

HUNT 01 AAD Prov Failures By Job Error 30d

Query

id: aa1f0001-2001-4201-9201-aadprov-hunt01
name: HUNT-01 Provisioning Failures by Job and Error (30d)
description: |
  30-day rollup of provisioning failures grouped by JobId, ServicePrincipal,
  and error signature. Use to retro-hunt persistent connector issues, identify
  campaigns of bad-actor SCIM calls that fell under analytic-rule thresholds,
  and detect schema-drift failures.
severity: Medium
requiredDataConnectors:
  - connectorId: AzureActiveDirectory
    dataTypes:
      - AADProvisioningLogs
tactics:
  - DefenseEvasion
relevantTechniques:
  - T1556
query: |
  AADProvisioningLogs
  | where TimeGenerated > ago(30d)
  | where ResultType =~ "Failure"
  | extend SPName = tostring(parse_json(ServicePrincipal).Name)
  | summarize
      Failures        = count(),
      AffectedTargets = dcount(TargetIdentity),
      ErrorMessages   = make_set(ResultDescription, 5),
      Operations      = make_set(OperationName, 10),
      DistinctDays    = dcount(startofday(TimeGenerated)),
      FirstSeen       = min(TimeGenerated),
      LastSeen        = max(TimeGenerated)
    by JobId, SPName, ResultSignature
  | where Failures >= 10
  | extend Sustained = DistinctDays >= 3
  | order by Failures desc

Explanation

This query is designed to analyze provisioning failures in Azure Active Directory over the past 30 days. It focuses on identifying persistent issues, potential malicious activities, and schema-related errors. Here's a simple breakdown:

  1. Data Source: It uses logs from Azure Active Directory, specifically the provisioning logs.

  2. Time Frame: The analysis covers the last 30 days.

  3. Filter: It looks for entries where the result was a "Failure".

  4. Data Extraction: For each failure, it extracts the name of the service principal involved.

  5. Aggregation: The query groups the failures by Job ID, Service Principal Name, and error signature. It calculates:

    • Total number of failures.
    • Number of unique affected targets.
    • A set of error messages (up to 5).
    • A set of operations involved (up to 10).
    • Number of distinct days the failures occurred.
    • The first and last occurrence of the failures.
  6. Threshold: It only considers groups with 10 or more failures.

  7. Sustained Issues: It flags issues that occurred on at least 3 different days.

  8. Output: The results are ordered by the number of failures, showing the most frequent issues first.

This query helps in identifying recurring problems, potential security threats, and operational anomalies in the provisioning process.

Details

David Alonso profile picture

David Alonso

Released: June 1, 2026

Tables

AADProvisioningLogs

Keywords

AzureActiveDirectoryAADProvisioningLogsServicePrincipalJobIdTargetIdentityResultDescriptionOperationNameTimeGenerated

Operators

whereextendsummarizedcountmake_setminmaxbyorder bytostringparse_jsonagostartofday

Actions