Query Details

Copilot Studio Conversation Flooding Do W

Query

id: a1b2c3d4-1008-4a11-9c01-0123456789a8
name: Copilot Studio - Conversation flooding / denial-of-wallet
description: |
  Raises an incident when a single channel/session drives an abnormally
  high inbound message volume in the hour (>=200 user turns), or a single
  conversation exceeds 100 turns. Sustained high-volume automated traffic
  against a metered agent is a denial-of-wallet pattern (driving token /
  message consumption and cost), and can also be scripted abuse or a
  guardrail-hammering red-team run.

  Reads inbound turns from AppEvents (Name == "BotMessageReceived"),
  grouping by conversation and channel. Tune the thresholds to your
  agent's normal traffic profile.
severity: Medium
requiredDataConnectors:
- connectorId: ApplicationInsights
  dataTypes:
  - AppEvents
queryFrequency: PT1H
queryPeriod: PT1H
triggerOperator: gt
triggerThreshold: 0
enabled: true
tactics:
- Impact
relevantTechniques:
- T1499
query: |
  AppEvents
  | where Name == "BotMessageReceived"
  | extend
      ConvId    = tostring(Properties["conversationId"]),
      ChannelId = tostring(Properties["channelId"]),
      DesignMode = tostring(Properties["DesignMode"])
  | where DesignMode != "True"
  | summarize
        Turns          = count(),
        Conversations  = dcount(ConvId),
        FirstSeen      = min(TimeGenerated),
        LastSeen       = max(TimeGenerated),
        ClientIPs      = make_set(ClientIP, 25)
      by SessionId, ChannelId, UserId
  | where Turns >= 200 or Conversations >= 1 and Turns / Conversations >= 100
  | extend AccountName = iff(isempty(UserId), strcat("session:", SessionId), UserId)
  | project
      LastSeen, FirstSeen, AccountName, SessionId, ChannelId, UserId,
      Turns, Conversations, ClientIPs
  | order by Turns 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
- DenialOfWallet
- Abuse

Explanation

This query is designed to monitor and detect unusual activity in a chatbot or automated agent system. It focuses on identifying scenarios where there is an abnormally high volume of inbound messages within an hour, either from a single channel/session or a single conversation. Specifically, it raises an alert if:

  1. A single channel/session receives 200 or more user messages in an hour.
  2. A single conversation exceeds 100 message exchanges (turns).

Such patterns could indicate a "denial-of-wallet" attack, where excessive automated traffic is generated to increase costs by consuming tokens or messages. It could also suggest scripted abuse or testing by security teams.

The query analyzes data from the "AppEvents" table, specifically looking for events where the "Name" is "BotMessageReceived". It groups the data by conversation and channel, excluding any events marked as "DesignMode". It then calculates the number of message exchanges and distinct conversations, and identifies the first and last time these events were seen, along with the client IPs involved.

If the conditions are met (high message volume), it creates an alert with details such as the session, channel, user ID, and message counts. The alert is configured to trigger if any such activity is detected, and incidents are created and grouped by account for easier management.

Details

David Alonso profile picture

David Alonso

Released: June 8, 2026

Tables

AppEvents

Keywords

AppEventsPropertiesConversationIdChannelIdDesignModeSessionIdUserIdClientIPAccountNameSessionIdChannelIdUserId

Operators

whereextendsummarizedcountminmaxmake_setbyorandiffisemptystrcatprojectorder by

Actions