Query Details

Microsoft 365 Copilot - Off-hours or anomalous-geo agent usage

Copilot Off Hours Or Geo Anomaly

Query

let lookback = 30d;
let recentWindow = 1d;
let usual =
    SigninLogs
    | where TimeGenerated between (ago(lookback) .. ago(recentWindow))
    | where ResultType == 0
    | extend Hour = hourofday(TimeGenerated), Country = tostring(LocationDetails.countryOrRegion)
    | summarize UsualHours = make_set(Hour, 24), UsualCountries = make_set(Country, 50)
        by UserPrincipalName = tolower(UserPrincipalName);
CopilotActivity
| where TimeGenerated > ago(recentWindow)
| where RecordType == "CopilotInteraction"
| extend ActorUpn = tolower(tostring(coalesce(column_ifexists('ActorUPN', ''), ActorName)))
| extend Hour = hourofday(TimeGenerated)
| join kind=leftouter usual on $left.ActorUpn == $right.UserPrincipalName
| extend ActorCountry = tostring(coalesce(column_ifexists('Location', ''),
                                          column_ifexists('Country', '')))
| extend
    OffHours      = isnotnull(UsualHours) and not(set_has_element(UsualHours, Hour)),
    AnomalousGeo  = isnotempty(ActorCountry) and isnotnull(UsualCountries)
                    and not(set_has_element(UsualCountries, ActorCountry))
| where OffHours or AnomalousGeo
| project TimeGenerated, AgentId, AgentName, ActorUpn, Hour, ActorCountry,
          OffHours, AnomalousGeo, UsualHours, UsualCountries, TenantId
| order by TimeGenerated desc

Explanation

This query is designed to detect potentially suspicious activity involving Microsoft 365 Copilot. It looks for Copilot sessions that occur outside of a user's normal working hours or from unusual geographic locations. Here's a simplified breakdown of what the query does:

  1. Define Timeframes: It sets a "lookback" period of 30 days to analyze past sign-in data and a "recentWindow" of 1 day to focus on recent Copilot activity.

  2. Establish Baseline: It examines sign-in logs from the past 30 days to determine each user's usual working hours and the countries they typically log in from. This information is used to create a baseline of normal behavior for each user.

  3. Analyze Recent Activity: It then looks at Copilot interactions from the last day, focusing on the time and location of these activities.

  4. Identify Anomalies: The query checks if any recent Copilot sessions occurred outside of the user's usual hours or from a country they haven't logged in from in the past 30 days. These are flagged as potential security concerns.

  5. Output Results: It lists the details of any suspicious sessions, including the time, user, location, and whether the activity was outside normal hours or from an unusual location.

The query is useful for identifying signs of session theft, OAuth token abuse, or impersonation attempts. It aligns with tactics like Initial Access and Defense Evasion and techniques such as Valid Accounts (T1078) and Cloud Accounts (T1078.004).

Details

David Alonso profile picture

David Alonso

Released: May 20, 2026

Tables

SigninLogsCopilotActivity

Keywords

MicrosoftCopilotSessionsActorSigninLogsLocationTimeUserPrincipalNameCopilotActivityRecordTypeActorUpnActorNameActorCountryAgentIdAgentNameTenantId

Operators

letbetweenago==extendtostringsummarizebytolower>coalescecolumn_ifexistsjoinkind=leftouteronisnotnullnotset_has_elementisnotemptyorprojectorder bydesc

Tactics

InitialAccessDefenseEvasion

MITRE Techniques

Actions

GitHub