Splunk

M365 Copilot Failed Authentication Patterns

Last updated 2 days ago on 2026-07-17

About

Detects M365 Copilot users with failed authentication attempts, MFA failures, or multi-location access patterns indicating potential credential attacks or account compromise. The detection aggregates M365 Copilot Graph API authentication events per user, calculating metrics like distinct cities/countries accessed, unique IP addresses and browsers, failed login attempts (status containing "fail" or "error"), and MFA failures (error code 50074). Users are flagged when they access Copilot from multiple cities (cities_count > 1), experience any authentication failures (failed_attempts > 0), or encounter MFA errors (mfa_failures > 0), which are indicators of credential stuffing, brute force attacks, or compromised accounts attempting to bypass multi-factor authentication.
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
Legitimate users experiencing network connectivity issues, traveling employees with intermittent VPN connections, users in regions with unstable internet infrastructure, or password reset activities during business travel 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, sum(eval(if(match(status, "(?i)fail | error"), 1, 0))) as failed_attempts, sum(eval(if(match(_raw, "50074"), 1, 0))) as mfa_failures, dc(deviceDetail.browser) as browser_count, values(deviceDetail.browser) as browsers_used, min(_time) as first_seen, max(_time) as last_seen by user | eval first_seen = strftime(first_seen, "%Y-%m-%d %H:%M:%S") | eval last_seen = strftime(last_seen, "%Y-%m-%d %H:%M:%S") | where cities_count > 1 OR failed_attempts > 0 OR mfa_failures > 0 | sort -mfa_failures, -failed_attempts, -countries_count | `m365_copilot_failed_authentication_patterns_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).