Copilot Studio - URL / domain / IP matched against threat intelligence
Copilot Studio Threat Intel Url Match
Query
let dt_lookBack = 1h;
let ioc_lookBack = 14d;
let networkIocTypes = dynamic(["url:value", "domain-name:value", "ipv4-addr:value", "ipv6-addr:value"]);
let TI =
ThreatIntelIndicators
| where TimeGenerated > ago(ioc_lookBack)
| where IsActive == true and Revoked == false
| where ObservableKey in (networkIocTypes)
| where isempty(ValidUntil) or ValidUntil > now()
| summarize arg_max(TimeGenerated, *) by IndicatorId = Id
| extend IOC = tolower(ObservableValue)
| where isnotempty(IOC);
let Content =
AppEvents
| where TimeGenerated > ago(dt_lookBack)
| where Name in ("BotMessageReceived", "BotMessageSend")
| extend
ConvId = tostring(Properties["conversationId"]),
ChannelId = tostring(Properties["channelId"]),
Direction = iff(Name == "BotMessageReceived", "UserPrompt", "AgentResponse"),
Text = tostring(Properties["text"])
| where isnotempty(Text)
| mv-expand Url = extract_all(@"(https?://[^\s\)\]\}""'<>]+)", Text) to typeof(string)
| extend
Url = tolower(Url),
Host = tolower(tostring(extract(@"https?://([^/:\s]+)", 1, Url)))
| mv-expand IOC = pack_array(Url, Host) to typeof(string)
| where isnotempty(IOC);
Content
| join kind=inner TI on IOC
| extend AccountName = iff(isempty(UserId), "unknown-agent", UserId)
| project
TimeGenerated, Direction, AccountName, ConvId, ChannelId,
MatchedIOC = IOC, ObservableKey, Confidence,
ThreatType = tostring(todynamic(Data).indicator_types[0]),
Description = tostring(todynamic(Data).description),
Url, Host, ClientIP, SessionId, AppVersion
| order by TimeGenerated descExplanation
This query is designed to monitor and identify potentially malicious URLs, domains, or IP addresses that appear in conversations involving Copilot Studio, a chatbot or virtual assistant platform. Here's a simplified breakdown of what the query does:
-
Data Sources: It uses data from two sources:
- Application Insights (AppEvents): This captures the text content of conversations, both incoming user prompts and outgoing agent responses.
- Threat Intelligence (ThreatIntelIndicators): This provides a list of known malicious or suspicious URLs, domains, and IP addresses.
-
Time Frame:
- The query checks conversation data from the last hour.
- It compares this data against threat intelligence indicators from the last 14 days.
-
Process:
- Extracts URLs and their hosts/IPs from the conversation content.
- Converts these to lowercase for consistent matching.
- Compares these extracted URLs/hosts/IPs against the active threat intelligence indicators.
-
Matching:
- If a match is found, it indicates that the conversation involved a known malicious or suspicious URL, domain, or IP.
- This could suggest a phishing attempt, compromised information source, or exposure to attacker infrastructure.
-
Output:
- For each match, it provides details such as the time of the event, the direction of the message (user prompt or agent response), account name, conversation ID, channel ID, matched indicator, threat type, and description.
-
Severity and Alerts:
- The severity of these findings is marked as high.
- If any matches are found, an alert is triggered, and an incident is created in Microsoft Sentinel.
-
Additional Features:
- The query is scheduled to run every hour.
- It supports incident grouping based on accounts and URLs to manage alerts efficiently.
Overall, this query helps in proactively identifying and responding to potential security threats within the Copilot Studio environment by leveraging threat intelligence data.
Details

David Alonso
Released: June 8, 2026
Tables
AppEventsThreatIntelIndicators
Keywords
ThreatIntelIndicatorsAppEventsAccountNameUrlHostClientIPSessionIdAppVersionTimeGeneratedDirectionConvIdChannelIdObservableKeyConfidenceThreatTypeDescription
Operators
letdynamicagoisactiveandisemptynowsummarizearg_maxbyextendtolowerisnotemptytostringiffextract_allmv-expandextractpack_arrayjoinonprojectorder bydesctdynamic
Severity
HighTactics
CommandAndControlInitialAccess
Frequency: PT1H
Period: P14D