Splunk

M365 Copilot Application Usage Pattern Anomalies

Last updated 2 days ago on 2026-07-17

About

Detects M365 Copilot users exhibiting suspicious application usage patterns including multi-location access, abnormally high activity volumes, or access to multiple Copilot applications that may indicate account compromise or automated abuse. The detection aggregates M365 Copilot Graph API events per user, calculating metrics like distinct cities/countries accessed, unique IP addresses, number of different Copilot apps used, and average events per day over the observation period. Users are flagged when they access Copilot from multiple cities (cities_count > 1), generate excessive daily activity (events_per_day > 100), or use more than two different Copilot applications (app_count > 2), which are anomalous patterns suggesting credential compromise or bot-driven abuse.
Platform
Splunk
Tags
Data Source: SplunkDomain: ApplicationRule Type: QueryOS: Any
Severity
medium
Risk Score
47
References
https://www.splunk.com/en_us/blog/artificial-intelligence/m365-copilot-log-analysis-splunk.html(external, opens in a new tab or window)
False Positives
Power users, executives with heavy AI workloads, employees traveling for business, users accessing multiple Copilot applications legitimately, or teams using shared corporate accounts across different office locations may trigger false positives.
Source
View on GitHub(external, opens in a new tab or window)

Definition

Rule Language
SPL
Rule Type
query
text code block:
`m365_copilot_graph_api` (appDisplayName="*Copilot*" OR appDisplayName="M365ChatClient" OR appDisplayName="OfficeAIAppChatCopilot") | eval user = userPrincipalName | stats count as events, dc(location.city) as cities_count, values(location.city) as city_list, dc(location.countryOrRegion) as countries_count, values(location.countryOrRegion) as country_list, dc(ipAddress) as ip_count, values(ipAddress) as ip_addresses, dc(appDisplayName) as app_count, values(appDisplayName) as apps_used, dc(resourceDisplayName) as resource_count, values(resourceDisplayName) as resources_accessed, min(_time) as first_seen, max(_time) as last_seen by user | eval days_active = round((last_seen - first_seen)/86400, 1) | eval first_seen = strftime(first_seen, "%Y-%m-%d %H:%M:%S") | eval last_seen = strftime(last_seen, "%Y-%m-%d %H:%M:%S") | eval events_per_day = if(days_active > 0, round(events/days_active, 2), events) | where cities_count > 1 OR events_per_day > 100 OR app_count > 2 | sort -events_per_day, -countries_count | `m365_copilot_application_usage_pattern_anomalies_filter`

View this rule on Splunk

This rule was sourced from the official Splunk public repository. View the original rule on GitHub(external, opens in a new tab or window).