Back
Id56cb646e-56a0-4f0e-8866-9bc1dd15da78
RulenamePower Automate - Unusual bulk deletion of flow resources
DescriptionIdentifies bulk deletion of Power Automate flows that exceed a predefined threshold defined in the query and deviate from activity patterns observed in the last 14 days.
SeverityMedium
TacticsImpact
DefenseEvasion
TechniquesT1485
T0828
T1562
Required data connectorsPowerAutomate
KindScheduled
Query frequency1h
Query period14d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft%20Business%20Applications/Analytic%20Rules/Power%20Automate%20-%20Unusual%20bulk%20deletion%20of%20flow%20resources.yaml
Version3.2.0
Arm template56cb646e-56a0-4f0e-8866-9bc1dd15da78.json
Deploy To Azure
// minThreshold: Minimum number of apps to be deleted to be considered an anomaly;
// This is to prevent one-off isolated delete flow to be considered outlier.
// The Min Threshold can be reduced or increased according to the traffic in the organization.
let minThreshold=10;
let interval = 1h;
let startTime = ago(14d);
let endTime = now();
let query_frequency = 1h;
let flow_deletion_events = PowerAutomateActivity
    | where TimeGenerated >= startTime
    | where EventOriginalType =~ "DeleteFlow"
    | extend IngestionTimeGenerated = TimeGenerated;
flow_deletion_events
| make-series DeletedFlowCount=count() on IngestionTimeGenerated from startTime to endTime step interval by ActorName, UserUpn, ActorUserId
| extend(Anomalies, AnomalyScore, ExpectedUsage) = series_decompose_anomalies(DeletedFlowCount)
| mv-expand
    DeletedFlowCount to typeof(double),
    IngestionTimeGenerated to typeof(datetime),
    Anomalies to typeof(double),
    AnomalyScore to typeof(double),
    ExpectedUsage to typeof(long)
| where IngestionTimeGenerated >= ago(query_frequency)
| where Anomalies != 0 and DeletedFlowCount >= minThreshold
| lookup (flow_deletion_events
    | where IngestionTimeGenerated >= ago(query_frequency))
    on ActorName, UserUpn, ActorUserId
| extend
    AccountName = tostring(split(ActorName, "@")[0]),
    UPNSuffix = tostring(split(ActorName, "@")[1]),
    PowerAutomateAppId = 27592
| project
    TimeGenerated,
    ActorName,
    DeletedFlowCount,
    ExpectedUsage,
    Anomalies,
    AnomalyScore,
    AccountName,
    UPNSuffix,
    PowerAutomateAppId,
    UserUpn,
    ActorUserId
name: Power Automate - Unusual bulk deletion of flow resources
triggerOperator: gt
kind: Scheduled
queryFrequency: 1h
description: Identifies bulk deletion of Power Automate flows that exceed a predefined threshold defined in the query and deviate from activity patterns observed in the last 14 days.
id: 56cb646e-56a0-4f0e-8866-9bc1dd15da78
triggerThreshold: 0
queryPeriod: 14d
query: |
  // minThreshold: Minimum number of apps to be deleted to be considered an anomaly;
  // This is to prevent one-off isolated delete flow to be considered outlier.
  // The Min Threshold can be reduced or increased according to the traffic in the organization.
  let minThreshold=10;
  let interval = 1h;
  let startTime = ago(14d);
  let endTime = now();
  let query_frequency = 1h;
  let flow_deletion_events = PowerAutomateActivity
      | where TimeGenerated >= startTime
      | where EventOriginalType =~ "DeleteFlow"
      | extend IngestionTimeGenerated = TimeGenerated;
  flow_deletion_events
  | make-series DeletedFlowCount=count() on IngestionTimeGenerated from startTime to endTime step interval by ActorName, UserUpn, ActorUserId
  | extend(Anomalies, AnomalyScore, ExpectedUsage) = series_decompose_anomalies(DeletedFlowCount)
  | mv-expand
      DeletedFlowCount to typeof(double),
      IngestionTimeGenerated to typeof(datetime),
      Anomalies to typeof(double),
      AnomalyScore to typeof(double),
      ExpectedUsage to typeof(long)
  | where IngestionTimeGenerated >= ago(query_frequency)
  | where Anomalies != 0 and DeletedFlowCount >= minThreshold
  | lookup (flow_deletion_events
      | where IngestionTimeGenerated >= ago(query_frequency))
      on ActorName, UserUpn, ActorUserId
  | extend
      AccountName = tostring(split(ActorName, "@")[0]),
      UPNSuffix = tostring(split(ActorName, "@")[1]),
      PowerAutomateAppId = 27592
  | project
      TimeGenerated,
      ActorName,
      DeletedFlowCount,
      ExpectedUsage,
      Anomalies,
      AnomalyScore,
      AccountName,
      UPNSuffix,
      PowerAutomateAppId,
      UserUpn,
      ActorUserId
version: 3.2.0
customDetails:
  DeletedFlowCount: DeletedFlowCount
status: Available
eventGroupingSettings:
  aggregationKind: SingleAlert
severity: Medium
requiredDataConnectors:
- connectorId: PowerAutomate
  dataTypes:
  - PowerAutomateActivity
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft%20Business%20Applications/Analytic%20Rules/Power%20Automate%20-%20Unusual%20bulk%20deletion%20of%20flow%20resources.yaml
alertDetailsOverride:
  alertDescriptionFormat: User {{ActorName}}  deleted {{DeletedFlowCount}} flows in the last hour, surpassing the bulk delete threshold. This is anomalous compared to the past 14 days.
  alertDisplayNameFormat: Power Automate - unusual bulk deletion of {{DeletedFlowCount}} flows
relevantTechniques:
- T1485
- T0828
- T1562
tactics:
- Impact
- DefenseEvasion
entityMappings:
- fieldMappings:
  - identifier: Name
    columnName: AccountName
  - identifier: UPNSuffix
    columnName: UPNSuffix
  entityType: Account
- fieldMappings:
  - identifier: AppId
    columnName: PowerAutomateAppId
  entityType: CloudApplication
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "workspace": {
      "type": "String"
    }
  },
  "resources": [
    {
      "apiVersion": "2024-01-01-preview",
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/56cb646e-56a0-4f0e-8866-9bc1dd15da78')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/56cb646e-56a0-4f0e-8866-9bc1dd15da78')]",
      "properties": {
        "alertDetailsOverride": {
          "alertDescriptionFormat": "User {{ActorName}}  deleted {{DeletedFlowCount}} flows in the last hour, surpassing the bulk delete threshold. This is anomalous compared to the past 14 days.",
          "alertDisplayNameFormat": "Power Automate - unusual bulk deletion of {{DeletedFlowCount}} flows"
        },
        "alertRuleTemplateName": "56cb646e-56a0-4f0e-8866-9bc1dd15da78",
        "customDetails": {
          "DeletedFlowCount": "DeletedFlowCount"
        },
        "description": "Identifies bulk deletion of Power Automate flows that exceed a predefined threshold defined in the query and deviate from activity patterns observed in the last 14 days.",
        "displayName": "Power Automate - Unusual bulk deletion of flow resources",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "AccountName",
                "identifier": "Name"
              },
              {
                "columnName": "UPNSuffix",
                "identifier": "UPNSuffix"
              }
            ]
          },
          {
            "entityType": "CloudApplication",
            "fieldMappings": [
              {
                "columnName": "PowerAutomateAppId",
                "identifier": "AppId"
              }
            ]
          }
        ],
        "eventGroupingSettings": {
          "aggregationKind": "SingleAlert"
        },
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft%20Business%20Applications/Analytic%20Rules/Power%20Automate%20-%20Unusual%20bulk%20deletion%20of%20flow%20resources.yaml",
        "query": "// minThreshold: Minimum number of apps to be deleted to be considered an anomaly;\n// This is to prevent one-off isolated delete flow to be considered outlier.\n// The Min Threshold can be reduced or increased according to the traffic in the organization.\nlet minThreshold=10;\nlet interval = 1h;\nlet startTime = ago(14d);\nlet endTime = now();\nlet query_frequency = 1h;\nlet flow_deletion_events = PowerAutomateActivity\n    | where TimeGenerated >= startTime\n    | where EventOriginalType =~ \"DeleteFlow\"\n    | extend IngestionTimeGenerated = TimeGenerated;\nflow_deletion_events\n| make-series DeletedFlowCount=count() on IngestionTimeGenerated from startTime to endTime step interval by ActorName, UserUpn, ActorUserId\n| extend(Anomalies, AnomalyScore, ExpectedUsage) = series_decompose_anomalies(DeletedFlowCount)\n| mv-expand\n    DeletedFlowCount to typeof(double),\n    IngestionTimeGenerated to typeof(datetime),\n    Anomalies to typeof(double),\n    AnomalyScore to typeof(double),\n    ExpectedUsage to typeof(long)\n| where IngestionTimeGenerated >= ago(query_frequency)\n| where Anomalies != 0 and DeletedFlowCount >= minThreshold\n| lookup (flow_deletion_events\n    | where IngestionTimeGenerated >= ago(query_frequency))\n    on ActorName, UserUpn, ActorUserId\n| extend\n    AccountName = tostring(split(ActorName, \"@\")[0]),\n    UPNSuffix = tostring(split(ActorName, \"@\")[1]),\n    PowerAutomateAppId = 27592\n| project\n    TimeGenerated,\n    ActorName,\n    DeletedFlowCount,\n    ExpectedUsage,\n    Anomalies,\n    AnomalyScore,\n    AccountName,\n    UPNSuffix,\n    PowerAutomateAppId,\n    UserUpn,\n    ActorUserId\n",
        "queryFrequency": "PT1H",
        "queryPeriod": "P14D",
        "severity": "Medium",
        "status": "Available",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "DefenseEvasion",
          "Impact"
        ],
        "techniques": [
          "T1485",
          "T1562"
        ],
        "templateVersion": "3.2.0",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}