← Back to SOC feed Coverage →

Copilot Studio AI Agents - Published Generative Orchestration without Instructions

kql MEDIUM Azure-Sentinel
T1499T1562
backdoorhuntingmicrosoftofficial
This rule was pulled from an open-source repository and enriched with AI. Validate in a test environment before deploying to production.
View original rule at Azure-Sentinel →
Retrieved: 2026-04-21T09:00:00Z · Confidence: medium

Hunt Hypothesis

Adversaries may publish generative AI orchestration agents in Copilot Studio without proper instructions to execute malicious payloads or exfiltrate data. SOC teams should proactively hunt for this behavior in Azure Sentinel to identify potential misuse of AI capabilities for persistent or covert attacks.

KQL Query

AIAgentsInfo 
| where RegistrySource != "A365"
| summarize arg_max(Timestamp, *) by AIAgentId 
| where AgentStatus == "Published" 
| where IsGenerativeOrchestrationEnabled 
| extend  BotComponents = todynamic(RawAgentInfo).BotComponents 
| mv-expand BotComponent = BotComponents 
| where BotComponent has "GptComponentMetadata" 
| where BotComponent.FormattedValues.componenttype == "Custom GPT" 
| extend InstructionsRaw = tostring(BotComponent.Attributes.data), AIAgentName 
| where InstructionsRaw has "instructions" 
| where BotComponent.Attributes.schemaname endswith ".gpt.default" 
| extend DisplayNamePos = indexof(InstructionsRaw, "displayName", indexof(InstructionsRaw, "instructions:") + strlen("instructions:")) 
| extend CapabilitiesPos = indexof(InstructionsRaw, "gptCapabilities", indexof(InstructionsRaw, "instructions:") + strlen("instructions:")) 
| extend InstructionsStart = indexof(InstructionsRaw, "instructions:") + strlen("instructions:") 
| extend InstructionsEnd = iif( 
    DisplayNamePos != -1 and CapabilitiesPos != -1,  
    iif(DisplayNamePos < CapabilitiesPos, DisplayNamePos, CapabilitiesPos), 
    iif(DisplayNamePos != -1, DisplayNamePos, 
    iif(CapabilitiesPos != -1, CapabilitiesPos, strlen(InstructionsRaw))) 
) 
| extend Instructions = substring(InstructionsRaw, InstructionsStart, InstructionsEnd - InstructionsStart) 
| extend InstructionsTrimmed = replace_string(replace_string(Instructions, "\r", ""), "\n", "")
| extend InstructionsTrimmed = trim(" \t", InstructionsTrimmed)
| where isempty(InstructionsTrimmed)
| project-away DisplayNamePos, CapabilitiesPos, InstructionsStart, InstructionsEnd 
| project-reorder AgentCreationTime, AIAgentId, AIAgentName, AgentStatus, CreatorAccountUpn, OwnerAccountUpns

Analytic Rule Definition

id: 8f0a7b1c-2d3e-4f5a-6b7c-8d9e0f1a2b3c
name: Copilot Studio AI Agents - Published Generative Orchestration without Instructions
description: |
  This query identifies Copilot Studio AI agents that are published with generative orchestration enabled but lack configured instructions. 
  Missing instructions increase the risk of prompt injection attacks, where malicious input can influence the agent to deviate from its intended behavior. 
  Without clear guidance, the agent may respond unpredictably or expose sensitive data.
  Recommended Action: Ensure all generative orchestration components have well-defined instructions that specify the agent`s purpose, boundaries, and allowed actions. 
  Regularly review and update instructions to maintain security and prevent misuse.
requiredDataConnectors: []
tactics:
  - Impact
  - DefenseEvasion
relevantTechniques:
  - T1499
  - T1562
query: |
  AIAgentsInfo 
  | where RegistrySource != "A365"
  | summarize arg_max(Timestamp, *) by AIAgentId 
  | where AgentStatus == "Published" 
  | where IsGenerativeOrchestrationEnabled 
  | extend  BotComponents = todynamic(RawAgentInfo).BotComponents 
  | mv-expand BotComponent = BotComponents 
  | where BotComponent has "GptComponentMetadata" 
  | where BotComponent.FormattedValues.componenttype == "Custom GPT" 
  | extend InstructionsRaw = tostring(BotComponent.Attributes.data), AIAgentName 
  | where InstructionsRaw has "instructions" 
  | where BotComponent.Attributes.schemaname endswith ".gpt.default" 
  | extend DisplayNamePos = indexof(InstructionsRaw, "displayName", indexof(InstructionsRaw, "instructions:") + strlen("instructions:")) 
  | extend CapabilitiesPos = indexof(InstructionsRaw, "gptCapabilities", indexof(InstructionsRaw, "instructions:") + strlen("instructions:")) 
  | extend InstructionsStart = indexof(InstructionsRaw, "instructions:") + strlen("instructions:") 
  | extend InstructionsEnd = iif( 
      DisplayNamePos != -1 and CapabilitiesPos != -1,  
      iif(DisplayNamePos < CapabilitiesPos, DisplayNamePos, CapabilitiesPos), 
      iif(DisplayNamePos != -1, DisplayNamePos, 
      iif(CapabilitiesPos != -1, CapabilitiesPos, strlen(InstructionsRaw))) 
  ) 
  | extend Instructions = substring(InstructionsRaw, InstructionsStart, InstructionsEnd - InstructionsStart) 
  | extend InstructionsTrimmed = replace_string(replace_string(Instructions, "\r", ""), "\n", "")
  | extend InstructionsTrimmed = trim(" \t", InstructionsTrimmed)
  | where isempty(InstructionsTrimmed)
  | project-away DisplayNamePos, CapabilitiesPos, InstructionsStart, InstructionsEnd 
  | project-reorder AgentCreationTime, AIAgentId, AIAgentName, AgentStatus, CreatorAccountUpn, OwnerAccountUpns
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: CreatorAccountUpn
  - entityType: Host
    fieldMappings:
      - identifier: HostName
        columnName: AIAgentName
version: 1.0.0

MITRE ATT&CK Context

References

False Positive Guidance

Original source: https://github.com/Azure/Azure-Sentinel/blob/main/Hunting Queries/AI Agents/Copilot Studio Connector/AIAgentsGenerativeOrchestrationNoInstructions.yaml