Query Details

Copilot Resource Diversity Burst

Query

id: 5e7d0f4b-9c6e-4d8e-b2f3-0a9e8d7c6b52
name: Microsoft 365 Copilot - Resource diversity burst per user
description: |
  Detects sudden bursts in the breadth of grounding sources a single
  user touches in a one-hour window via Microsoft 365 Copilot. Used to
  surface enumeration / cross-department reconnaissance patterns where
  an actor (or a compromised agent acting on their behalf) is fanning
  out across a large number of SharePoint sites, OneDrive locations,
  and other repositories that they don't normally touch together.

  Different from CopilotAccessDriftDetection (which surfaces newly-seen
  resource TYPES vs a 14d baseline): this rule surfaces a spike in the
  COUNT of distinct grounding sites in a single hour vs the user's own
  14d-hourly P95.

  Limitation: department / business-unit metadata is not exposed on
  AccessedResources, so we use the SharePoint / OneDrive hostname as a
  proxy. Tune the floor (DistinctSitesFloor) to your tenant.
severity: Medium
requiredDataConnectors:
- connectorId: MicrosoftCopilot
  dataTypes:
  - CopilotActivity
queryFrequency: PT1H
queryPeriod: P14D
triggerOperator: gt
triggerThreshold: 0
enabled: true
tactics:
- Discovery
- Collection
relevantTechniques:
- T1087
- T1213
- T1083
query: |
  let lookback = 14d;
  let recentWindow = 1h;
  let floorSites = 10;          // minimum sites/hour to even consider
  let spikeMultiplier = 3.0;     // hour must exceed P95 by this factor
  let perUserHour =
      CopilotActivity
      | where TimeGenerated > ago(lookback)
      | where RecordType == "CopilotInteraction"
      | mv-expand r = LLMEventData.AccessedResources
      | extend SiteUrl = tostring(r.SiteUrl)
      | where isnotempty(SiteUrl)
      | summarize
          DistinctSites = dcount(SiteUrl),
          AnyAgentName = take_any(AgentName),
          AnyAgentId = take_any(AgentId),
          AnyActor = take_any(ActorName)
          by ActorUserId, TenantId, Hour = bin(TimeGenerated, 1h);
  let baseline =
      perUserHour
      | where Hour < bin(now(), 1h) - recentWindow
      | summarize
          P95Sites = todouble(percentile(DistinctSites, 95)),
          MedianSites = todouble(percentile(DistinctSites, 50))
          by ActorUserId;
  let recent =
      perUserHour
      | where Hour >= bin(now(), 1h) - recentWindow;
  recent
  | join kind=leftouter baseline on ActorUserId
  | extend
      P95Sites = coalesce(P95Sites, 0.0),
      MedianSites = coalesce(MedianSites, 0.0)
  | extend SpikeRatio = iff(P95Sites > 0, todouble(DistinctSites) / P95Sites, todouble(DistinctSites))
  | where DistinctSites >= floorSites and DistinctSites > P95Sites * spikeMultiplier
  | project
      Hour, ActorUserId, ActorName = AnyActor, AgentId = AnyAgentId,
      AgentName = AnyAgentName, DistinctSites, P95Sites, MedianSites,
      SpikeRatio, TenantId
entityMappings:
- entityType: CloudApplication
  fieldMappings:
  - identifier: Name
    columnName: AgentName
  - identifier: AppId
    columnName: AgentId
- entityType: Account
  fieldMappings:
  - identifier: Name
    columnName: ActorName
eventGroupingSettings:
  aggregationKind: SingleAlert
incidentConfiguration:
  createIncident: true
  groupingConfiguration:
    enabled: true
    reopenClosedIncident: false
    lookbackDuration: PT12H
    matchingMethod: Selected
    groupByEntities:
    - Account
    groupByAlertDetails: []
    groupByCustomDetails: []
version: 1.0.0
kind: Scheduled
tags:
- Sentinel-As-Code
- Custom
- Copilot
- AI

Explanation

This query is designed to detect unusual activity by users of Microsoft 365 Copilot. Specifically, it looks for sudden increases in the number of different resources (like SharePoint sites or OneDrive locations) that a user accesses within a one-hour period. This can indicate potential reconnaissance or exploration across different departments, possibly by an unauthorized user or a compromised account.

Here's a simplified breakdown of how it works:

  1. Data Collection: It gathers data on user interactions with resources over the past 14 days.

  2. Baseline Calculation: It calculates a baseline for each user, determining the 95th percentile (P95) of distinct sites accessed per hour over the past 14 days.

  3. Recent Activity Check: It examines the most recent hour of activity to see if the number of distinct sites accessed is significantly higher than the user's baseline (specifically, more than three times the P95 value).

  4. Alert Trigger: If a user's activity exceeds this threshold and involves accessing at least 10 different sites in an hour, an alert is triggered.

  5. Incident Management: The query is set to create an incident if such an alert is triggered, grouping related alerts by user account.

This helps identify potential security threats by flagging users who suddenly access a wide range of resources, which they don't typically do, indicating possible unauthorized exploration or data collection.

Details

David Alonso profile picture

David Alonso

Released: May 20, 2026

Tables

CopilotActivity

Keywords

MicrosoftCopilotActivityResourcesSharePointOneDriveUserTenantAccountCloudApplicationAlertIncident

Operators

letmv-expandextendtostringwhereisnotemptysummarizedcounttake_anybyagobinnowjoinkind=leftoutercoalesceifftodoublepercentileproject

Actions