Query Details

Copilot Studio - Unapproved MCP server or tool invoked

Copilot Studio Untrusted Mcp Target

Query

let trusted =
    _GetWatchlist('CopilotStudioTrustedConnectors')
    | project ConnectorTarget = tolower(trim(" ", tostring(column_ifexists('ConnectorTarget', ''))))
    | where isnotempty(ConnectorTarget);
let Legacy = AppDependencies
| where AppRoleName == "Microsoft Copilot Studio" or DependencyType == "Connector"
| extend ResourceKey = tolower(tostring(Target)),
         ResourcePrefix = tolower(tostring(split(Target, "/")[0]))
| project TimeGenerated, OperationId, Success, ResultCode, ClientIP,
    Agent = "", User = "", ConvId = tostring(Properties["conversationId"]),
    Tool = Name, ToolType = "MCP - connector telemetry", Target = tostring(Target),
    ResourceKey, ResourcePrefix, Source = "Agent-level connector";
let Modern = AppDependencies
| where tostring(Properties["gen_ai.operation.name"]) == "execute_tool"
| extend Tool = tostring(Properties["gen_ai.tool.name"]),
         ToolType = tostring(Properties["gen_ai.tool.type"])
| where Tool has "mcp" or ToolType has "mcp"
| extend ResourceKey = tolower(iff(Target == "GenAI" or isempty(Target), Tool, tostring(Target))),
         ResourcePrefix = tolower(tostring(split(iff(Target == "GenAI" or isempty(Target), Tool, tostring(Target)), "/")[0]))
| project TimeGenerated, OperationId, Success, ResultCode, ClientIP,
    Agent = tostring(Properties["gen_ai.agent.name"]),
    User = coalesce(tostring(Properties["user.email"]), tostring(Properties["user.id"])),
    ConvId = tostring(Properties["gen_ai.conversation.id"]), Tool, ToolType,
    Target = tostring(Target), ResourceKey, ResourcePrefix,
    Source = "Environment ExecuteTool";
union Legacy, Modern
| extend Trusted = ResourcePrefix in (trusted) or ResourceKey in (trusted)
| where not(Trusted)
| extend AccountName = coalesce(User, Agent, strcat("tool:", Tool))
| summarize Calls = count(), Failures = countif(Success == false),
    Traces = dcount(OperationId), Conversations = make_set(ConvId, 25),
    FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated),
    ClientIP = take_any(ClientIP)
    by AccountName, Agent, Tool, ToolType, Target, ResourceKey, ResourcePrefix, Source
| extend TimeGenerated = LastSeen
| project TimeGenerated, FirstSeen, LastSeen, AccountName, ClientIP, Agent,
    Tool, ToolType, Target, ResourceKey, ResourcePrefix, Source,
    Calls, Failures, Traces, Conversations
| order by LastSeen desc

Explanation

This query is designed to monitor and raise alerts for any unauthorized use of MCP (Microsoft Cloud Platform) connectors or tools within Copilot Studio. Here's a simplified breakdown:

  1. Purpose: The query checks if any MCP connector or tool is being used that is not listed in a predefined "trusted" watchlist. If such usage is detected, it could indicate potential issues like unauthorized changes, rogue servers, or tools added without approval.

  2. Data Source: It uses data from Application Insights, specifically focusing on application dependencies.

  3. Frequency: The query runs every hour and looks back at the past hour of data.

  4. Severity: The alert generated by this query is marked as high severity.

  5. Detection Logic:

    • It first retrieves a list of trusted connectors from a watchlist.
    • It then examines both legacy and modern application dependencies related to Copilot Studio.
    • It checks if any connector or tool used is not in the trusted list.
    • If an untrusted connector or tool is found, it collects details about the usage, such as the account name, tool type, and client IP.
  6. Alert Generation: If any untrusted usage is detected, an alert is generated, summarizing the details of the incident, including the number of calls, failures, and unique conversations involved.

  7. Incident Management: The query is set to create incidents for detected issues, grouping them by account for better management.

  8. Tags and Metadata: The query is tagged with relevant keywords like Sentinel-As-Code, Custom, CopilotStudio, MCP, Allowlist, and SupplyChain for easy identification and categorization.

Overall, this query helps maintain security and compliance by ensuring that only approved MCP connectors and tools are used within Copilot Studio.