Query Details

Agent Cross Agent Invocation

Query

id: 8c9d0e1f-6666-4d12-9106-0123456789c8
name: Agent - Agent-to-agent invocation chains
description: |
  Hunts Foundry / Agent Service conversations that span more than one
  agent, or where a tool invocation is itself another agent. Agent-to-
  agent (A2A) chains - Copilot -> Security Agent -> Cloud Agent -> Finance
  Agent - are an emerging lateral-movement and privilege-escalation path:
  a low-privilege agent reaching a high-privilege one, or a recursive loop
  amplifying blast radius. This hunt surfaces the chains so you can review
  unusual or recursive ones.

  Reads gen_ai.agent.name, gen_ai.tool.name and gen_ai.tool.type from the
  AppDependencies span property bag (Properties), grouped by
  gen_ai.conversation.id. Conversations touching two or more distinct
  agents, or invoking an agent-typed tool, are returned.
query: |
  let spans =
      AppDependencies
      | where isnotempty(Properties["gen_ai.conversation.id"])
      | extend
          Agent     = tostring(Properties["gen_ai.agent.name"]),
          ConvId    = tostring(Properties["gen_ai.conversation.id"]),
          ProjectId = tostring(Properties["microsoft.foundry.project.id"]),
          ToolName  = tolower(tostring(Properties["gen_ai.tool.name"])),
          ToolType  = tolower(tostring(Properties["gen_ai.tool.type"]))
      | extend IsAgentTool = ToolType == "agent" or ToolName has "agent" or ToolName has "connected_agent";
  spans
  | summarize
      Agents       = make_set(Agent, 20),
      AgentCount   = dcountif(Agent, isnotempty(Agent)),
      AgentToolHits = countif(IsAgentTool),
      AgentTools   = make_set_if(ToolName, IsAgentTool, 20),
      FirstSeen    = min(TimeGenerated),
      LastSeen     = max(TimeGenerated),
      AnyProject   = take_any(ProjectId)
      by ConvId
  | where AgentCount >= 2 or AgentToolHits > 0
  | extend ChainDepth = AgentCount + AgentToolHits
  | extend ProjectId = AnyProject
  | project
      LastSeen, ConvId, ProjectId, AgentCount, Agents,
      AgentToolHits, AgentTools, ChainDepth, FirstSeen
  | order by ChainDepth desc
tactics:
  - LateralMovement
  - PrivilegeEscalation
techniques:
  - T1210
  - T1098
tags:
  - Sentinel-As-Code
  - Custom
  - Foundry
  - AI

Explanation

This query is designed to identify and analyze communication chains between different software agents within a system. It focuses on detecting scenarios where multiple agents are involved in a conversation or where a tool used in the conversation is itself an agent. This is important because such chains can represent potential security risks, such as lateral movement or privilege escalation, where a low-privilege agent might interact with a high-privilege one, or where recursive loops could amplify security vulnerabilities.

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

  1. Data Collection: It starts by gathering data from a table called AppDependencies, focusing on specific properties related to agents and tools involved in conversations.

  2. Data Processing: It extracts and processes information such as agent names, conversation IDs, project IDs, tool names, and tool types. It also checks if a tool is an agent or related to an agent.

  3. Summarization: The query summarizes the data by counting distinct agents and identifying tools that are agents. It also records the first and last time the conversation was seen and any associated project ID.

  4. Filtering: It filters the results to include only those conversations that involve two or more distinct agents or any agent-related tools.

  5. Output: The query outputs details such as the number of agents, the tools involved, and the depth of the agent chain, sorted by the complexity of the chain.

Overall, this query helps security teams identify and review complex agent-to-agent communication patterns that could indicate potential security threats.

Details

David Alonso profile picture

David Alonso

Released: June 8, 2026

Tables

AppDependencies

Keywords

AgentAppDependenciesPropertiesProjectIdToolNameToolTypeTimeGeneratedConvId

Operators

let|whereisnotemptyextendtostringtolower==orhassummarizemake_setdcountifcountifmake_set_ifminmaxtake_anyby>=>projectorder bydesc

Actions