Query Details

02 AAD Prov Mass Disable

Query

id: 9b1a0002-1002-4102-9102-aadprov00002
name: Mass User Disable via Provisioning
version: 1.0.0
kind: Scheduled
description: |
  Detects 10 or more `Disable` provisioning actions completing successfully
  within a single hour against Entra ID user objects. Mass disable is a
  recognised attacker tactic to lock out legitimate users (denial of service)
  or to disable an account immediately before takeover via TAP/credential
  injection. Provisioning is the stealthier channel - bulk disables made via
  HR systems or SCIM rarely raise console alerts.
  MITRE ATT&CK: T1531 (Account Access Removal), T1098 (Account Manipulation),
  T1078.004 (Valid Accounts: Cloud Accounts).
severity: High
requiredDataConnectors:
  - connectorId: AzureActiveDirectory
    dataTypes:
      - AADProvisioningLogs
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
  - Impact
  - Persistence
relevantTechniques:
  - T1531
  - T1098
query: |
  AADProvisioningLogs
  | where TimeGenerated > ago(1h)
  | where ResultType =~ "Success"
  | where ProvisioningAction =~ "Disable"
       or (OperationName has_any ("Disable", "disable") and ProvisioningAction !~ "Other")
  | extend SPName = tostring(parse_json(ServicePrincipal).Name)
  | extend InitiatorUpn = tostring(parse_json(InitiatedBy).userPrincipalName)
  | extend InitiatorApp = tostring(parse_json(InitiatedBy).displayName)
  | extend TargetUpn    = tostring(parse_json(TargetIdentity).userPrincipalName)
  | extend TargetId     = tostring(parse_json(TargetIdentity).id)
  | summarize
      DisabledCount   = count(),
      Targets         = make_set(TargetUpn, 50),
      Jobs            = make_set(JobId, 10),
      Cycles          = make_set(CycleId, 10),
      Initiators      = make_set(coalesce(InitiatorUpn, InitiatorApp), 5),
      FirstSeen       = min(TimeGenerated),
      LastSeen        = max(TimeGenerated)
    by SPName
  // Threshold: 10/hour catches deliberate mass-disable while ignoring routine HR-driven offboarding spikes
  | where DisabledCount >= 10
  | order by DisabledCount desc
entityMappings:
  - entityType: CloudApplication
    fieldMappings:
      - identifier: Name
        columnName: SPName
customDetails:
  DisabledCount: DisabledCount
  Initiators: Initiators
  Targets: Targets
alertDetailsOverride:
  alertDisplayNameFormat: "Mass user disable via provisioning - {{DisabledCount}} accounts ({{SPName}})"
  alertDescriptionFormat: "Provisioning service {{SPName}} disabled {{DisabledCount}} users in 1h. Verify against expected HR / lifecycle workflow. Possible account-access-removal attack."
  alertSeverityColumnName: ""
  alertTacticsColumnName: ""
incidentConfiguration:
  createIncident: true
  groupingConfiguration:
    enabled: true
    reopenClosedIncident: false
    lookbackDuration: PT8H
    matchingMethod: AnyAlert
    groupByEntities:
      - CloudApplication
    groupByAlertDetails: []
    groupByCustomDetails: []

Explanation

This query is designed to detect potential security threats by identifying when 10 or more user accounts are disabled within a single hour through provisioning actions in Azure Active Directory (AAD). This could indicate a mass user disablement attack, which is a tactic used by attackers to lock out legitimate users or prepare for account takeover.

Here's a simplified breakdown of the query:

  1. Data Source: It uses logs from Azure Active Directory provisioning actions.

  2. Time Frame: It looks at logs from the past hour.

  3. Success Check: It filters for provisioning actions that were successful.

  4. Action Type: It specifically looks for "Disable" actions, which indicate user accounts being disabled.

  5. Data Extraction: It extracts details such as the service principal name (SPName), the initiator's user principal name or app name, and the target user's principal name and ID.

  6. Summarization: It counts the number of disable actions and collects details about the targets, jobs, cycles, and initiators involved.

  7. Threshold: It flags cases where 10 or more disable actions occur within an hour, which could suggest a deliberate mass-disable attack rather than routine HR-driven actions.

  8. Alerting: If the threshold is met, it generates an alert with details about the number of accounts disabled and the service responsible.

  9. Incident Management: It creates an incident if such an alert is triggered, grouping related alerts to manage them effectively.

Overall, this query helps security teams identify and respond to potential security incidents involving mass user disablement in a timely manner.

Details

David Alonso profile picture

David Alonso

Released: June 1, 2026

Tables

AADProvisioningLogs

Keywords

AADProvisioningLogsEntraIDUserCloudApplicationServicePrincipalInitiatedByTargetIdentityJobIdCycleIdTimeGenerated

Operators

ago=~has_any!~tostringparse_jsonsummarizecountmake_setcoalesceminmaxbyorder bydesc

Actions