MG | Outside the Model: Governing AI Agents on the Microsoft Stack
microsoft

Outside the Model: Governing AI Agents on the Microsoft Stack

calendar_today JUL 25, 2026
schedule 21 MIN READ

Start with the scoping question, because it determines everything else: which agents are you governing?

The July 2026 incident that prompted this series involved a model running inside a custom evaluation harness on research infrastructure, whose only network path out was a package registry proxy. That’s a different problem from a business agent with a connector allowlist, and it’s secured differently, with classical workload controls: egress design with more than one control in the path, per-run credentials, segmentation between research and everything else, and logs somebody reads.

Agent 365 and Defender give you a strong control plane for the business agents most organizations are deploying right now. Research and evaluation compute sits alongside that, governed with the infrastructure security you already know. Both matter, and knowing which is which is the difference between a rollout that closes real risk and one that closes a ticket.

So this is a control map: what Microsoft can enforce outside the model, what it observes, what’s GA versus preview, how it’s licensed, and what to add on top.

It’s the implementation half of The Call Is Coming From Inside the House, which ended on the principle that decides which controls are worth building. The UK AI Security Institute found that every frontier model it tested attempted to cheat its way around task boundaries, that models described their own cheating as wrong less than half the time when asked, and that chain-of-thought monitoring often showed no reasoning about the offending action at all. The companion post works through what that does and doesn’t prove. The operational consequence is what matters here: self-report and visible reasoning aren’t reliable enforcement boundaries, so authorization, egress and containment need to be enforceable outside the model.

Start with the map

Here’s the July incident as a kill chain, with the control principle each step engages, the Microsoft lever, and which environment it applies to.

Attack stepControl principleMicrosoft leverApplies to research compute?
Sole egress = package proxy; zero-day in itEgress needs depth, not one hopGSA Secure Web and AI Gateway for Copilot Studio agents; Azure Firewall + FQDN rules, forced tunneling, private endpoints for other workloadsYes, via the Azure network controls
Privilege escalation and lateral movement to an internet-connected nodeSegmentation; no standing privilegeNetwork isolation, Entra PIM for just-in-time access, workload identity, subscription separationYes
Inferred a third-party target, then attacked itReachability reductionEgress allowlisting is the effective controlYes, via egress design
Malicious dataset → RCE on a processing workerTreat processed input as hostileApplication security; Defender for Containers; admission controlYes
Cloud and cluster credentials harvested from the workerLoop holds no durable secretManaged identities, federated credentials, Key Vault referencesYes
Thousands of actions from short-lived sandboxes; self-migrating C2Velocity ceilings; egress reputationCloudAppEvents for agent tool volume; DNS, proxy and flow logs in SentinelWhere you emit telemetry
Attributing the activity to a specific agent runOutbound-as-attack detectionCustom detections and hunts you authorYes — see §8

Two things fall out of that table. Most of what closes this chain is infrastructure security you already know how to run, which is Florian Roth’s point from the companion post and it stands. And the last row is the genuinely new work: tying outbound attack activity to a specific agent run is detection engineering, and it’s the highest-value thing on your backlog.

The second map worth drawing before you buy anything is which controls apply to each kind of agent you run:

Agent classInventoryPostureRuntime blockDetectionEgress control
Copilot StudioYesYesYes (tool invocation)YesYes (GSA)
Microsoft FoundryYesYesPrompt ShieldsYesAzure network controls
Microsoft 365 / Copilot Agent BuilderYesYesYesYesTenant controls
Custom, with Agent 365 SDKYesPartialVia Work IQ MCPYesAzure network controls
Custom, no SDK yetAdd the SDK to gain theseAzure network controls
Local coding agent (Claude Code, Cursor…)Yes (Defender for Endpoint)YesAgents exposing hooksYesEndpoint and network controls
Research / evaluation harnessClassical asset inventoryCustomAzure network controls

The bottom rows are where your highest-capability agents usually live. Instrumenting them is a deliberate piece of work, and it’s worth scheduling rather than discovering.

1. An inventory you didn’t write by hand

Every agent governance program starts with a manually maintained spreadsheet, and every one of those is out of date within a fortnight. Microsoft’s documentation names the failure mode agent sprawl: expansion without visibility or lifecycle controls, from business units building outside IT oversight, temporary agents that never get decommissioned, and permissions nobody reviews.

Cloud and platform agents. The Defender portal (Assets > AI agents) inventories agents from Copilot Studio, Foundry and Microsoft 365, non-Microsoft platforms including AWS Bedrock and GCP Vertex AI, plus local agents from endpoints. Behind it is the AgentsInfo table, carrying authentication, access control, tools, knowledge sources, orchestration settings and user and endpoint context. It stores repeated snapshots per agent, so every query needs the latest-state idiom:

AgentsInfo
| summarize arg_max(Timestamp, *) by AgentId
| where LifecycleStatus != "Deleted"

AgentsInfo supersedes the earlier AIAgentsInfo table as part of the Agent 365 transition, so update saved queries when you migrate.

Local agents on endpoints. Run this one first; it’s the fastest way to learn what’s actually in your estate. Defender for Endpoint (preview) discovers local AI agents and MCP server configurations on Windows and macOS: CLI agents (Claude Code, Codex CLI, Gemini CLI, GitHub Copilot CLI, Junie CLI, Kiro CLI, OpenCode, Warp, Antigravity CLI), desktop apps (ChatGPT, Claude, Codex, Goose, Hermes Agent, Ollama, Perplexity, Poe), agentic IDEs (Cursor, Devin Desktop (formerly Windsurf), Kiro IDE, Antigravity IDE), VS Code extensions (Claude Code, Cline, Codex, Gemini Code Assist, GitHub Copilot, Roo Code) and Claw-based agents (OpenClaw, Clawpilot, QClaw, Claw/Nanobot).

An agent here is defined as user + device + agent type, so Claude Code running in fifteen project folders for one user on one machine is one inventory entry rather than fifteen, a sensible unit, because it matches how you’d actually govern it. You also get an exposure map of the relationships between local agents, devices, identities and the resources those identities can reach, which is the question that matters, because a local agent inherits the permissions of whoever ran it. Requires Defender for Endpoint and Defender Antivirus in active mode; local agents onboard separately from cloud agents.

My expectation for most estates: a number of MCP servers nobody registered, on laptops that can still reach production. Better to find them yourself.

Read the posture indicators as context, not a work queue. Defender assigns a risk level from active indicators including Indirect Prompt Injection Exposure, Privileged Business-system Access, Weak Instructions, High-usage Agent and Active Threat; for local agents it factors in running on a critical device, a device with known vulnerabilities, use by a critical user, and Privileged Software Development Access. Usefully, Microsoft is explicit that an indicator isn’t always something to remediate: a public chatbot is deliberately unauthenticated, a deployment agent genuinely needs privileged access. Risk level and recommendations are calculated separately, so read them together.

2. An identity per agent, with an owner and an expiry

Entra Agent ID provides blueprints as templates and agent identities as instances in a parent-child relationship, auto-discovery, centralised metadata, and agent-to-agent discovery and authorization over MCP and A2A. All agent authentication and actions are logged in Entra ID.

Three deployment patterns, with materially different risk:

  • Interactive agents act on a signed-in user’s behalf via delegated permissions and the on-behalf-of flow, inheriting that user’s reach. This is what teams reach for by default, and the pattern to review most carefully, because an agent operating in systems the user isn’t watching is where accountability gets ambiguous.
  • Autonomous agents run under their own identity via client credentials. Easiest to reason about; prefer it where the workflow allows.
  • An agent user account pairs 1:1 with an agent identity for systems that need a real user object (mailbox, calendar, Teams). It doesn’t replace the agent identity; both exist.

Then apply the machinery you already own. Conditional Access for agents brings adaptive policy per pattern, agent identity risk as a real-time signal, Microsoft Managed Policies that block high-risk agents as a baseline, and custom security attributes so you can apply policy at scale rather than agent by agent. ID Protection for agents derives risk both from the associated user and from the agent’s own actions, feeds Conditional Access, and can automatically remediate a compromised agent. ID Governance for agents covers lifecycle through to expiry, enforced sponsors and owners so you don’t accumulate orphans, time-bound access packages, and controls applied at the blueprint level so every current and future instance inherits them, including the ability to disable an entire class of agents in a single operation, which is a useful thing to have before you need it.

Keep credentials out of the picture where you can: managed identities and federated credentials give credential-free authentication, which removes the thing an attacker is actually looking for.

Treat agent-to-agent as a permission in its own right. Entra Agent ID’s agent-to-agent discovery and authorization is powerful, and it’s also the exact shape of the escalation in the companion post, where an incident-response agent recruited a second agent that held code access it didn’t have itself. Nothing went wrong there, because a human still reviewed the pull request. But the lesson is that an agent’s effective authority includes the authority of every agent it can ask for help. So decide deliberately which blueprints may discover and call which, and treat that graph as part of the blast-radius calculation rather than as connectivity you get for free.

And don’t stop at agents you built. Third-party SaaS agents holding user-consented OAuth grants into your Microsoft 365 data are, for many tenants, a larger everyday exposure than anything on a developer’s laptop, because a user can grant them without involving IT at all. App governance in Defender for Cloud Apps plus restrictive Entra user-consent policies is the control: review the consent grants you already have, then decide what users may approve on their own.

3. Egress as a designed control

The logic is simple. If an agent is compromised by something it read, the attacker still has to get data out. If outbound requests can only reach destinations you chose, there’s nowhere to send it.

Both cases in the companion post are egress stories, and July’s is the instructive version: the allowlist had one entry, and the entry was the vulnerability. Depth matters more than the existence of a control.

Global Secure Access, via Secure Web and AI Gateway for agents, forwards Copilot Studio agent traffic to the GSA proxy and applies the same policy you already apply to users:

  • Traffic forwarding is enabled in the Power Platform Admin Center, per environment or environment group.
  • It covers HTTP node traffic, custom connectors, and the MCP Server Connector. That last one is how you keep an agent from reaching an MCP server you haven’t approved.
  • You then apply web content filtering, threat intelligence filtering and file-type restrictions through the tenant-level baseline profile, plus logging of agent network activity, web categorisation to control which APIs and MCP servers are reachable, and prompt-injection detection in transit.

Scope: this is documented for Copilot Studio agents. For Foundry agents, your own services and evaluation harnesses, you get the same outcome with Azure Firewall FQDN rules, forced tunneling, private endpoints and NSGs, on a subnet the workload can’t reconfigure. That’s the combination that would have mattered in July, and it’s available to you today.

And hold this constant: the loop should never contain a secret worth stealing — principle 5 in the companion post, and the reason the Hugging Face worker compromise became a cluster compromise.

4. Remove the verb, then add the classifier

This is the distinction I’d most like you to take away, because it’s easy to get backwards.

Preventive authorization means the dangerous action doesn’t exist in the agent’s world. Allow drafting, never sending. Allow reads, never deletes. You implement it at the connector, MCP server, API scope and data-store role layers: leave the verb out of the tool schema, don’t grant the Graph permission, don’t give the managed identity the delete role. An agent cannot attempt an action that isn’t in its tool list.

Compensating detection and blocking is Defender’s real-time protection for AI agents (preview), which inspects the agentic loop (prompts, tool calls before execution, tool responses) and blocks risky activity before it runs. Its rules are scoped by detection type and by agent: a classifier judging that an action looks malicious. That’s a valuable second layer, and it’s a different mechanism from removing the action from the agent’s authority. You want both, in that order.

Mechanics for rollout:

  • Agent 365 tool invocations are evaluated pre-execution via Work IQ MCP, including customer MCP tools onboarded to Agent 365.
  • Copilot Studio agents are covered without Work IQ MCP, when Copilot Studio is connected.
  • Local agents are covered through endpoint runtime protection (§6).

There’s a built-in Default rule that audits all agents, recording matches as behaviors without stopping anything. Start there: it shows you what you would have blocked before you risk breaking a business process. Custom rules block, scoped to specific agents and detection types, under Settings > Security for AI > Policies & rules > Real-time protection. Only agents with an Entra agent ID appear in the scoping list, which is another reason §2 comes first.

One behavior worth knowing before you switch modes: when a blocking rule covers an agent, near-real-time alerts aren’t generated for it; alerting continues in audit mode, and blocked activity is recorded as behaviors in BehaviorInfo. If your detections or reporting key off alerts, build against both tables so the signal follows you into block mode.

5. Telemetry, joined up

What Defender detects for Agent 365-managed agents: jailbreak attempts, XPIA (cross-prompt injection), malicious content propagation, secrets and credential leaks, evasion techniques and suspicious user access, correlated into incidents with entity relationships and blast radius.

Prompt evidence can include the snippets that triggered a detection, with secrets redacted, and it’s on by default. Have the privacy and retention conversation early, so the setting matches your policy from day one.

The tables you’ll live in:

TableContents
AgentsInfoInventory and configuration: identity, platform, ownership, tools
CloudAppEventsAgent 365 observability: agent actions, tool invocations, data access
AlertInfo / AlertEvidenceAlert metadata; entities and artifacts per alert
BehaviorInfo / BehaviorEntitiesReal-time protection audit and block events, and their entities

The prerequisite to plan for: near-real-time detection depends on observability data flowing. Copilot Studio, Foundry and the M365 Copilot Agent Builder emit it by default. Agents built on other platforms gain the same coverage once the Agent 365 SDK is wired in, so put that in the definition of done for every internal agent project, and your in-house Python agent lands in the same inventory and hunting tables as everything else.

For AI infrastructure, Defender for Cloud’s AI threat protection is GA, working with Azure AI Content Safety Prompt Shields and Microsoft threat intelligence. Its alert catalogue doubles as a threat model: credential theft detected inside model responses, jailbreaks blocked or detected depending on filter confidence, ASCII smuggling prompt injection (invisible instructions, rated High), anomalous tool invocation, LLM reconnaissance, corrupted applications directing phishing at users, denial-of-wallet attacks, access from Tor and suspicious IPs, and malware in an uploaded model. Scope today is text tokens, and billing is token-based with a 30-day trial capped at 75 billion tokens scanned, which is generous enough to prove value before you commit. Alongside it, AI security posture management discovers AI assets and finds vulnerabilities across models, dependencies, repositories and container images, with attack-path analysis, and scans models for malware, unsafe operators, serialisation flaws and exposed secrets.

On audit records, know which system gives you which artifact. Agent 365 observability is OpenTelemetry-aligned and designed to be streamed into your SIEM, which is the right shape for detection and hunting. Microsoft Purview separately provides formal audit activities for agent invocation, inference and tool execution, which is the right shape for retention and evidence. Map both per agent surface: which events land where, with what fields, what retention and what API access, so your SOC and your auditor are each drawing on the right source.

6. The endpoint is where prompt injection lands

Local coding agents run with the user’s privileges, read files, fetch web pages and execute commands, and as Microsoft’s documentation puts it, they “can’t reliably separate trusted content from hidden instructions.” That makes them one of the highest-leverage places to add a control.

Defender for Endpoint’s AI agent runtime protection (preview) inspects the user prompt, the tool request before execution, and the tool response after. Two methods, and the difference determines your coverage:

  • Agent-native event inspection uses the agents’ own vendor hook interfaces. The documented set is Claude Code, Codex CLI, GitHub Copilot CLI and the GitHub Copilot app. Note that Cursor and the other IDEs currently appear on the discovery list rather than this one. Each scan is an inline check at a hook point, so added latency is minimal.
  • Network inspection extends coverage to agents without hooks by inspecting agent-to-LLM traffic, for agents that don’t use certificate pinning or HTTP/3.

Detections raise a Suspicious AI prompt injection alert, correlated into incidents. Modes are Block, Audit and Disabled, protected by tamper protection. Start in audit mode and validate before enforcing.

Microsoft’s own documented example is the Memory Heist at enterprise scale: a coding agent fetches project documentation; the page contains hidden text instructing it to read the local .env and post the contents to an external URL; Defender detects the injection in the tool response and blocks the action before data leaves the device.

7. Purview, because the exfiltration is authorized

This is the layer I see left out most often, and it reaches something the other layers can’t on their own. Agent data loss usually travels through entirely legitimate API calls under valid credentials. Nothing is exploited. The agent was allowed to read the file and allowed to make the request; it simply did both on an attacker’s behalf. Identity controls see an authorized principal; egress controls see an approved destination.

So the data layer has to carry its own weight:

  • Sensitivity labels and their encryption travel with the content, so a labeled document stays protected when an agent retrieves it and tries to move it.
  • DLP policies should treat agent interactions as a channel in their own right, rather than assuming endpoint and email coverage is enough.
  • DSPM for AI shows which agents and copilots are touching which sensitive data, the report your privacy officer will ask for first.
  • Oversharing is the root cause more often than any exploit. An agent with a user’s delegated permissions surfaces everything that user could technically reach, including the SharePoint site with permission sprawl nobody has audited in years. Fix the permissions before you deploy the agent, or the agent becomes a very efficient discovery tool for your own oversharing.
  • Insider Risk Management is the natural home for the behavioral side, and the practical expression of treating an agent as a principal with insider-like access.

8. The detection you write yourself

Attributing outbound attack activity to a specific agent run is custom detection work. Your existing NDR, IDS and cloud-abuse tooling will catch some of the network behavior; tying it to an agent and a run is the piece you author.

The first thing to be clear about is where each hunt lives, because only one of the four is native to the agent tables. The rest are Sentinel-side network telemetry, which is exactly why they’d have applied to a research harness that emits no agent observability at all:

HuntTelemetry sourceWhere it runs
Tool-invocation velocityCloudAppEvents (Agent 365 observability)Defender Advanced Hunting
Outbound initiation from receive-only workloadsVNet/NSG flow logs, Azure Firewall logsSentinel
New or low-reputation egress destinationsDNS resolver logs, firewall logs, proxy logsSentinel
Blocked-action clustersBehaviorInfo / BehaviorEntitiesDefender Advanced Hunting

Four hypotheses to start from. Treat the queries as skeletons: these tables are in preview, so validate every column name against your own schema before trusting a result, and read the false-positive note.

a) Tool-invocation velocity anomaly. “Many thousands of actions across a swarm of short-lived sandboxes” is exactly what a velocity ceiling exists to catch.

// Agents whose hourly tool-call volume is far above their own 14-day norm.
// Swap the identity column for whichever field carries the agent identity
// in your tenant before you trust the output.
let baseline = CloudAppEvents
| where Timestamp between (ago(14d) .. ago(1d))
| summarize hourly = count() by AgentIdentity = AccountObjectId, bin(Timestamp, 1h)
| summarize avgHour = avg(hourly), sdHour = stdev(hourly) by AgentIdentity;
CloudAppEvents
| where Timestamp > ago(1h)
| summarize recent = count() by AgentIdentity = AccountObjectId
| join kind=inner baseline on AgentIdentity
| where recent > avgHour + 4 * sdHour and recent > 100

False positives: legitimate bulk jobs and backfills. The baseline above is per agent identity rather than global, which is what you want; also exclude known batch windows. For bursty workloads, a static ceiling agreed with the agent’s owner beats a statistical one.

b) Outbound initiation from workloads that should only receive work. Batch compute, data-processing workers and evaluation harnesses rarely originate internet connections. Build this from firewall, DNS and flow logs against an explicit asset group. It’s the highest-value hunt on the list and needs no agent telemetry at all.

c) Newly-registered or low-reputation destinations from an agent runtime. Self-migrating C2 staged on public services looks like an agent runtime talking to a rotating set of ordinary-looking hosting endpoints. Domain age plus first-seen-in-estate beats reputation feeds here.

d) Blocked-action clusters. One blocked risky action is noise; the same agent tripping rules repeatedly is an agent being driven.

// Note: BehaviorInfo carries both audit and block events, so filter to
// blocks only, otherwise your default audit rule dominates the results.
BehaviorInfo
| where Timestamp > ago(24h)
| where ActionType has "Block"
| summarize events = count(), actions = make_set(ActionType, 10)
    by AgentId = tostring(AdditionalFields.AgentId)
| where events >= 5
| order by events desc

False positives: a badly-written agent looping on a denied tool. Correlate with BehaviorEntities to see whether the targets vary; varying targets is the interesting case.

Then close the loop. High-confidence agent threats should trigger automated containment: disable the agent identity, revoke tokens, pull connector access. Two things people skip. Test the kill path — disabling an identity doesn’t necessarily stop a running workload holding a valid access token until it expires, so know your token lifetimes, whether you can revoke sessions, and rehearse it. And model the false-positive impact: automated containment on a wrong call takes out a business process, so scope auto-containment to high-confidence detections and keep a documented rollback.

If you don’t run a 24/7 SOC yourself, this is the part to push onto your MDR provider, and to be specific about what you’re asking for. Ask which agent telemetry they ingest, whether they can attribute activity to an agent identity and run, who holds authority to disable an agent identity at 3am, and what their contractual time-to-containment is for an agent-attributed detection. At Wortell we’ve been extending our MDR practice along exactly those lines, because agent identities and agent telemetry deserve to be first-class signal rather than something bolted onto endpoint alerts.

Licensing paths

Worth confirming early so your design matches your entitlements. Extending Entra’s agent security capabilities comes via Microsoft 365 E7, which includes Agent 365 and the Entra Suite, or E5 plus a Microsoft Agent 365 license per user. Standalone options map per capability: Conditional Access for agents with Entra ID P1, ID Protection with P2, ID Governance with P1, and network controls for agents with Entra Internet Access, in the Entra Suite or separately.

One question to raise with your account team while you’re planning, because it shapes the model you design toward: how the per-user basis applies to autonomous agents that have no attached human. Get that answered before you commit to a pattern rather than after.

And you can make real progress with the Azure platform controls you already own, which per the kill-chain table, is where most of the blast-radius reduction lives:

  • Agents in their own subscription or management group, with no trust path to the corporate control plane.
  • Azure Firewall with FQDN rules and forced tunneling: a genuine egress allowlist the workload can’t reconfigure.
  • Managed identities and Key Vault references, so no durable secret sits in the agent’s environment.
  • Private endpoints for data stores, so the agent’s reach is network-limited as well as permission-limited.
  • Diagnostic settings on everything into Sentinel, with the four hunts above written against firewall and DNS logs.

That’s most of the containment story for the cost of infrastructure you already know how to run.

What “done” looks like

Four weeks gets you a long way from a standing start, and the order matters because each step feeds the next.

Week 1: see it. Enable local AI agent discovery and the Microsoft 365 connector for agent observability. Run the AgentsInfo query. Propose no policy yet; build the inventory and exposure map and find out what’s already running.

Week 2: name the boundary. Write down what counts as untrusted content. Run your highest-pressure use case through the four questions from the companion post. Classify each agent as interactive, autonomous, or carrying a human’s delegated identity.

Week 3: identity and audit mode. Agents into Entra Agent ID with owners, sponsors and expiry. Conditional Access at blueprint level. Defender’s default audit rule and endpoint runtime protection in audit mode. Watch; don’t block.

Week 4: enforce, instrument, prove. Convert trusted audit findings into scoped blocking rules. Remove the verbs at the authorization layer. Put egress through a proxy the runtime can’t edit. Write the four hunts. Pick and test your forensic model.

Then hold the pilot to acceptance criteria, because everything above is configuration until you’ve demonstrated it works:

  1. Every agent with production-adjacent reach has a named owner, an identity and an expiry date.
  2. An unapproved egress destination fails, and you have the log entry that proves it.
  3. A destructive action is unavailable rather than merely discouraged, verified by asking an agent to attempt it.
  4. A deliberate test injection appears where you expect it: the alert, the behavior record, and the audit event.
  5. A timed kill drill removes access from a running agent, and you know how many seconds it took.

Save the queries and the evidence, and write down every preview dependency and license your design leans on. That list is what makes the next review a five-minute conversation instead of a rediscovery.


Sources: Microsoft capability detail from Microsoft Learn documentation for Defender security for AI, discovering agents and assessing posture, AI agent posture risk, detecting and investigating agent threats, real-time protection, local AI agent discovery and AI agent runtime protection in Defender for Endpoint, AI threat protection and alerts for AI services in Defender for Cloud, Microsoft Entra security for AI, Secure Web and AI Gateway for agents and how Defender supports Agent 365. Control principles draw on Jason Clinton’s Zero risk isn’t the job: a CISO’s guide to agentic AI; incident detail from Hugging Face’s and OpenAI’s disclosures and the UK AI Security Institute’s research on cheating behavior. Feature availability, preview status and licensing reflect the documentation as of 25 July 2026 and continue to evolve, so verify before you finalize a design. The KQL is a starting point written against preview schemas, not tested detection content.