Step-by-step security checklists for the most common AI security tasks. Each playbook distils field experience into the minimum viable set of controls โ what to do, in what order, and what to watch for.
Per the Microsoft Learn schema changes notice (June 2026): the AIAgentsInfo table is being replaced by the unified AgentsInfo table. The old table remains accessible until July 1, 2026. Microsoft Agent 365 customers should use AgentsInfo today.
All KQL queries on this page have been migrated to AgentsInfo with column renames applied. The new schema is currently labelled Preview โ queries against dynamic columns (ToolsAuthenticationType, Owners, Capabilities) may need field-path adjustment when tested against your tenant data. Verify the canonical Microsoft example query works first.
Two other things to know about July 1, 2026: (1) Agent security capabilities for Copilot Studio and Foundry agents will require a Microsoft Agent 365 license โ tenants without one lose access. (2) Existing Agent 365 real-time protection rules in Block mode stop blocking; alerts move to the new BehaviorInfo table. Block rules must be redefined under Settings โ Security for AI โ Policies. See Microsoft's transition guide.
| Old (AIAgentsInfo) | New (AgentsInfo) | Notes |
|---|---|---|
| AIAgentId | AgentId | Simple rename |
| AIAgentName | AgentName | Simple rename |
| AgentStatus = "Published" | PublishedStatus = "Published" | Same values: Draft / Published |
| AgentStatus = "Deleted" | LifecycleStatus = "Deleted" | Split into separate column: Active / Blocked / Uninstalled / Deleted |
| UserAuthenticationType (string) | ToolsAuthenticationType (dynamic) | Type change. Now a structured JSON record. Site uses tostring(ToolsAuthenticationType) contains "None" as a robust pattern; exact JSON paths may need adjustment. |
| OwnerAccountUpns (string) | Owners (dynamic) | Type change. Now an array. Use array_length(Owners) == 0 instead of isempty(). |
| CreatorAccountUpn | Owners[0] (within dynamic) | No direct column; first owner is typically the creator. Available via RawAgentInfo JSON if needed. |
| AgentCreationTime | CreatedDateTime | Simple rename, same datetime type |
| AgentActionTriggers | Triggers (dynamic) | Simple rename. Already dynamic in old schema. |
| AgentChannel | Channels (dynamic) | Renamed and now dynamic array (multi-channel agents). |
| AgentToolsDetails | DeclaredTools (dynamic) | Closest equivalent. Same dynamic JSON structure. |
| AgentTopicsDetails | Capabilities (dynamic) | Best approximation โ Capabilities covers intents, actions, skills, orchestrations. |
| RegistrySource | Platform | Semantics change. All AgentsInfo rows are A365-registered (no need to filter). "PowerPlatform" โ "Copilot Studio". New values include "Microsoft Foundry", "Microsoft 365 Copilot". |
| IsBlocked (boolean) | LifecycleStatus == "Blocked" | Filter via LifecycleStatus values (Active / Blocked / Uninstalled / Deleted). |
| AIModel | Model | Simple rename. Same string type. |
| EntraObjectId | EntraAgentId | Same concept โ the enterprise application object identifier. |
| EntraBlueprintId | EntraBlueprintId | Same name in both schemas. |
| AgentUsers | SharedWith | Users / groups the agent has been shared with. Now dynamic. |
| KnowledgeDetails | DeclaredDataSources | Data repositories and knowledge sources the agent can access. |
| LastModifiedTime | LastUpdatedDateTime | Simple rename, same datetime type. |
| LastPublishedTime | LastPublishedDateTime | Simple rename, same datetime type. |
| AgentAppId | EntraAgentId | Both refer to the agent's Entra app identifier. |
| ConnectedAgentsSchemaNames | ConnectedAgents | Multi-agent orchestration links. Now dynamic with full agent records. |
| LastModifiedByUpn / LastPublishedByUpn / CreatorAccountUpn | โ (use RawAgentInfo) | No direct columns. Parse from RawAgentInfo JSON via parse_json(RawAgentInfo).creatorId etc., then join to IdentityInfo for UPN. |
| AuthenticationTrigger / AccessControlPolicy / AuthorizedSecurityGroupIds | ToolsAuthenticationType / Permissions / SharedWith (dynamic fields) | Old per-field columns consolidated into structured dynamic columns. Exact JSON paths require verification against tenant data. |
| IsGenerativeOrchestrationEnabled / AccessCapabilities / ElementTypes | Capabilities (dynamic) / RawAgentInfo | Likely surfaced inside the Capabilities dynamic. Microsoft's published query uses tostring(todynamic(RawAgentInfo).Bot.Attributes.configuration) has '"GenerativeActionsEnabled": true' for the orchestration check. |
| EnvironmentId | โ (use RawAgentInfo) | Power Platform environment ID. Not a top-level column in AgentsInfo; available via RawAgentInfo JSON for Copilot Studio platform agents. |
| โ | EntraAgentId, EntraBlueprintId, Permissions, McpServers, ConnectedAgents, Guardrails, Endpoints, RawAgentInfo | New columns with no old equivalent. Use for cross-platform agent inventory and governance queries. |
Six analytic rules and a dedicated workbook for Copilot telemetry, contributed to the official Microsoft Sentinel GitHub repository by Samik Roy (May 2026). Deploy as a single solution from Sentinel Content Hub โ Microsoft Copilot solution. Requires CopilotActivity table ingestion via the Copilot Data Connector.
Step 1: Ensure CopilotActivity logs are ingested
โ Sentinel Content Hub โ Copilot Data Connector (Public Preview Feb 2026)
โ Requires Global/Security Administrator role
Step 2: Deploy the Microsoft Copilot solution
โ Microsoft Sentinel โ Content Hub โ search "Microsoft Copilot" โ Install
โ Includes: workbook + 6 analytic rules + hunting queries in one solution
GitHub source:
Analytic rules: Azure-Sentinel/Solutions/Microsoft Copilot/Analytic Rules
Hunting queries: Azure-Sentinel/Solutions/Microsoft Copilot/Hunting Queries
Workbook: Azure-Sentinel/Solutions/Microsoft Copilot/Workbooks/MicrosoftCopilotActivityMonitoring.json
Step 3: Open workbook and validate data against your environment
Step 4: Enable and tune analytic rules to your policy and risk appetiteMicrosoft has shipped an Agent 365 data connector for Sentinel that ingests agent telemetry into the Sentinel data lake from three sources at once: Agent 365, Microsoft Foundry, and Copilot. This is the unified connector you want for cross-platform agent investigation โ it replaces the need to wire three separate sources.
Step 1: In Sentinel โ Content Hub โ search "Agent 365"
Step 2: Install the Agent 365 data connector
Step 3: Configure data ingestion to the Sentinel data lake
Step 4: Use the Sentinel MCP server interface to query in natural language
or write KQL directly against the new tables
โ If this connector is enabled and then deactivated, hunting/graph/MCP
workflows that depended on its data will stop functioning.When you enable "Continuously detect managed devices" in Agent 365 Shadow AI, Intune automatically creates a Properties catalog profile called A365 - Monitor OpenClaw. It uses the new Local AI Agent Settings Catalog node, runs via the Intune Management Extension (IME), and refreshes every 24 hours. Read-only โ safe to deploy. Source: Derk van der Woude, May 2026.
Agent Name โ canonical identifier for the agent typeAgent Version โ version string of the installed agentHost Process โ parent process executing the agentInstall Location โ filesystem path of the installationInstall Scope โ per-user vs per-machineInstall Scope Platform User ID โ Windows SID of installing userInstall Scope User ID โ Entra ID user identifier (UPN)Local AI Agent Execution Context โ user / elevated / SYSTEM โ ๏ธ SYSTEM = high risk// Requires Intune device inventory data in Log Analytics
// IntuneDeviceCompliancePolicies or custom inventory table from IME
// Filter for elevated/SYSTEM execution context
IntuneDevices
| where Properties has "Local AI Agent Execution Context"
| extend AgentName = extract("AgentName:([^,]+)", 1, Properties)
| extend ExecContext = extract("ExecutionContext:([^,]+)", 1, Properties)
| extend InstallUser = extract("InstallScopeUserID:([^,]+)", 1, Properties)
| where ExecContext in ("elevated","SYSTEM")
| project DeviceName, AgentName, ExecContext, InstallUser, LastSync
| order by ExecContext desc, LastSync descThe CloudAppEvents table captures Copilot and agent activity from the M365 Unified Audit Log via Defender for Cloud Apps. Requires: Settings โ Cloud Apps โ App connectors โ M365 activities enabled. Metadata only โ no prompt content.
CloudAppEvents
| where Timestamp > ago(7d)
| where ActionType startswith "CopilotAgent" or ActionType startswith "UpdateCopilot"
| project Timestamp, ActionType, AccountDisplayName,
AgentName = tostring(RawEventData.CopilotAgentName),
ChangeDetail = tostring(RawEventData)
| order by Timestamp descCloudAppEvents
| where Timestamp > ago(7d)
| where ActionType startswith "UpdateCopilotAgent"
| project CopilotActionTime = Timestamp,
AdminAccount = AccountDisplayName,
AgentName = tostring(RawEventData.CopilotAgentName),
Action = ActionType
| join kind=inner (
EmailEvents
| where Timestamp > ago(7d)
| where Subject has_any ("confidential","restricted","sensitive")
) on $left.AdminAccount == $right.SenderFromAddress
| project CopilotActionTime, AdminAccount, AgentName, Action,
EmailTime = Timestamp1, EmailSubject = SubjectCloudAppEvents
| where Timestamp > ago(30d)
| where ActionType == "CopilotForSecurityTrigger"
| summarize TriggerCount = count(), UniqueUsers = dcount(AccountObjectId)
by ActionType, Application, bin(Timestamp, 1d)
| order by Timestamp descIdentifies which AI model each Copilot Studio agent is using by extracting modelNameHint from RawAgentInfo. Flags EU Data Boundary (EUDB) compliance status per agent โ critical for EU organisations where Anthropic-hosted models process data outside the EUDB. Source: Blue161616/Agent-Identity.
AgentsInfo
| summarize arg_max(Timestamp, *) by AgentId
| where Platform == "Copilot Studio" and LifecycleStatus != "Deleted"
| extend ModelNameHint = extract(@"modelNameHint:\s*([A-Za-z0-9_\-\.]+)", 1, RawAgentInfo)
| extend HintLower = tolower(ModelNameHint)
| extend Provider = case(
HintLower startswith "sonnet" or HintLower startswith "haiku" or HintLower startswith "opus", "Anthropic",
HintLower startswith "gpt" or HintLower startswith "o1" or HintLower startswith "o3", "OpenAI (Microsoft-hosted)",
isempty(ModelNameHint), "Environment default",
"Other"
)
| extend EUDB_Status = case(
Provider == "Anthropic", "OUT OF EUDB โ cross-geo processing",
Provider == "OpenAI (Microsoft-hosted)", "In EUDB (if environment is in EU)",
Provider == "Environment default", "Depends on tenant default โ verify",
"Verify"
)
| project AgentName, Provider, ModelNameHint, EUDB_Status,
EnvironmentId, Owners, LastModifiedTime
| sort by Provider asc, AgentName ascAgentsInfo table. All rows in AgentsInfo are A365-registered โ to scope to a specific platform, use Platform == "Copilot Studio" or Platform == "Microsoft Foundry". Queries that traverse dynamic JSON columns (Capabilities, DeclaredTools, Triggers) target Power-Platform-era JSON shapes; you may need to adjust nested field paths once your tenant data flows through the new schema. Test against AIAgentsInfo (still accessible until July 1, 2026) for ground truth.Capabilities โ topics with beginDialog.actions, DeclaredTools โ action records with operationId/modelDisplayName). These shapes are preserved during the transition but may evolve as the unified AgentsInfo schema matures. Compare results between AIAgentsInfo (legacy) and AgentsInfo (new) during the migration window to catch shape changes early.pip install pyrit # Required env vars (for Azure OpenAI target + scorer) export AZURE_OPENAI_API_KEY="your-key" export AZURE_OPENAI_ENDPOINT="https://your-instance.openai.azure.com/" export AZURE_OPENAI_DEPLOYMENT="gpt-4o"
Config-driven โ switch strategies, datasets, or thresholds with no code changes. Point target at your agent entry point.
# scan.yaml
scan:
name: "my-agent-security-scan"
target:
module: "my_agent.main" # Your agent module
function: "handle_prompt" # Your agent entry function
strategies:
- name: "prompt_sending" # Single-turn baseline
- name: "crescendo" # Gradual escalation
max_turns: 5
- name: "tap" # Tree of Attacks with Pruning
converters: # Stack โ applied in order
- name: "Base64Converter"
- name: "LeetspeakConverter"
- name: "TranslationConverter"
datasets:
- "airt_illegal" # Microsoft AI Red Team dataset
- "harmbench" # Harm evaluation benchmark
- "advbench" # Adversarial benchmark
- path: "datasets/custom.yaml" # Your domain-specific prompts
gate:
fail_on:
critical_findings: 0 # Zero tolerance for critical
high_findings: 3
max_score: 0.3 # Defense rate must exceed 70%Run in sequence โ if plain prompts pass, layer evasion. Each phase builds on the previous.
Phase 1: Plain prompts โ Baseline โ establishes what passes without evasion โ Catches basic prompt injection and policy violations Phase 2: Encoded prompts โ Base64, ROT13, Leetspeak, Unicode confusables โ Tests whether your agent/guardrails decode before evaluating Phase 3: Semantic attacks โ LLM-powered rephrasing, translation, multimodal injection โ Converters stack: translate โ Base64 โ embed in image Phase 4: Multi-turn dialogue attacks โ CrescendoAttack: gradual escalation over 5โ10 turns โ TreeOfAttacksWithPruning (TAP): branching attack trees โ Tests whether context accumulation bypasses initial guardrails
Map findings to OWASP LLM Top 10 (2025) for structured risk reporting. Turns PyRIT output into a risk register your security team understands.
LLM01 Prompt Injection โ PromptSendingAttack + injection datasets (airt_illegal) LLM02 Sensitive Info โ Data exfiltration datasets + PII scorers LLM06 Excessive Agency โ Tool-calling attack datasets (advbench) LLM07 System Prompt Leakage โ System prompt extraction datasets LLM10 Unbounded Consumption โ High-volume automated attack patterns
Integrate into your pipeline. Exit code 0 = pass (deploy), exit code 1 = fail (block). No custom actions needed.
# GitHub Actions example
jobs:
security-scan:
steps:
- name: Run AI security scan
run: |
pip install pyrit
python scanner.py --config scan.yaml --output reports/
- name: Evaluate release gate
run: |
python gate.py --report reports/scan_results.json
# Exit 1 blocks deployment automatically
# When to run:
# Every merge to main: Quick scan only (phases 1โ2, ~10 min)
# Pre-release branch: Full scan (all 4 phases, architect approval)
# Weekly scheduled: Full scan across full agent estate