Query Details

Copilot Studio Off Hours Activity

Query

id: a1b2c3d4-1009-4a11-9c01-0123456789a9
name: Copilot Studio - Off-hours or non-published-channel activity
description: |
  Raises a low-severity incident when a published Copilot Studio agent is
  used outside business hours (configurable window, default 20:00-06:00
  UTC) on a non-design channel. Off-hours interactive use of a corporate
  agent is worth a proactive look - it can be benign global usage, but it
  is also when scripted abuse and credential-misuse tend to run.

  Reads inbound turns from AppEvents (Name == "BotMessageReceived"),
  excludes design-time (test) traffic, and buckets by hour of day. Adjust
  the business-hours window and excluded channels to your environment.
severity: Low
requiredDataConnectors:
- connectorId: ApplicationInsights
  dataTypes:
  - AppEvents
queryFrequency: PT1H
queryPeriod: PT1H
triggerOperator: gt
triggerThreshold: 0
enabled: true
tactics:
- InitialAccess
relevantTechniques:
- T1078
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
entityMappings:
- entityType: Account
  fieldMappings:
  - identifier: Name
    columnName: AccountName
eventGroupingSettings:
  aggregationKind: SingleAlert
incidentConfiguration:
  createIncident: true
  groupingConfiguration:
    enabled: true
    reopenClosedIncident: false
    lookbackDuration: PT6H
    matchingMethod: Selected
    groupByEntities:
    - Account
    groupByAlertDetails: []
    groupByCustomDetails: []
version: 1.0.0
kind: Scheduled
tags:
- Sentinel-As-Code
- Custom
- CopilotStudio
- AI
- Anomaly

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

Actions