Query Details

Copilot Studio - Off-hours or non-published-channel activity

Copilot Studio Off Hours Activity

Query

let businessStart = 6;   // 06:00 UTC
let businessEnd   = 20;  // 20:00 UTC
AppEvents
| where Name == "BotMessageReceived"
| extend
    ConvId    = tostring(Properties["conversationId"]),
    ChannelId = tostring(Properties["channelId"]),
    DesignMode = tostring(Properties["DesignMode"])
| where DesignMode != "True"
| where ChannelId !in ("pva-studio", "test")
| extend HourUtc = hourofday(TimeGenerated)
| where HourUtc < businessStart or HourUtc >= businessEnd
| summarize
      Turns     = count(),
      Convs     = dcount(ConvId),
      FirstSeen = min(TimeGenerated),
      LastSeen  = max(TimeGenerated),
      ClientIPs = make_set(ClientIP, 25),
      Hours     = make_set(HourUtc, 24)
    by ChannelId, UserId
| extend AccountName = iff(isempty(UserId), strcat("channel:", ChannelId), UserId)
| project LastSeen, FirstSeen, AccountName, ChannelId, UserId, Turns, Convs, Hours, ClientIPs
| order by LastSeen desc

Explanation

This query is designed to monitor and raise alerts for unusual activity involving a Copilot Studio agent. Specifically, it looks for instances where the agent is used outside of normal business hours (between 8 PM and 6 AM UTC) on channels that are not designated for design or testing purposes. The goal is to identify potentially suspicious behavior, such as scripted abuse or misuse of credentials, which might occur during these off-hours.

Here's a simple breakdown of what the query does:

  1. Time Window: It defines business hours as 6 AM to 8 PM UTC. Any activity outside this window is considered off-hours.

  2. Data Source: It reads data from AppEvents where the event name is "BotMessageReceived".

  3. Exclusions: It excludes any traffic marked as design-time (test) and any activity on specific channels like "pva-studio" and "test".

  4. Filtering: It filters events to only include those occurring outside the defined business hours.

  5. Aggregation: It summarizes the data by counting the number of interactions (turns) and unique conversations (convs), noting the first and last time the activity was seen, and collecting unique client IPs and hours of activity.

  6. Output: The results are organized by channel and user, and sorted by the most recent activity.

  7. Alerting: If any activity is detected, it triggers a low-severity alert, which can be grouped into incidents for further investigation.

This query helps organizations proactively monitor for and investigate any unusual or potentially unauthorized use of their corporate agents during off-hours.

Details

David Alonso profile picture

David Alonso

Released: June 8, 2026

Tables

AppEvents

Keywords

AppEventsPropertiesConversationIdChannelIdDesignModeTimeGeneratedClientIPUserIdAccountName

Operators

let|whereextendtostring!inhourofdaysummarizecountdcountminmaxmake_setbyiffisemptystrcatprojectorder by

Severity

Low

Tactics

InitialAccess

MITRE Techniques

Frequency: PT1H

Period: PT1H

Actions

GitHub