Microsoft's Agent Governance Toolkit Validates the Control Plane — and Leaves Out the Meter
In April, Microsoft open-sourced the Agent Governance Toolkit — MIT-licensed, “policy enforcement, identity, sandboxing, and SRE for autonomous AI agents. One pip install, any framework.” It’s at 4.6k stars as I write this, and it’s the strongest statement yet from a platform vendor about where agent safety actually lives.
We read the source — the policy engine spec, the delegation code, the Claude Code plugin — because it sits in exactly our lane. Here’s what it gets right, what a library structurally can’t do, and the one lesson I think the market is about to learn wrong.
What Microsoft got right
The core architecture is a clean PEP/PDP split: your framework adapter is the enforcement point; it assembles a JSON snapshot of the action at one of eight intervention points (pre_tool_call, post_model_call, and so on) and hands it to a stateless, deterministic, fail-closed policy engine that returns one of five verdicts: allow, warn, deny, escalate, or transform.
That verdict set is genuinely good design, and three details deserve specific credit:
transform is a first-class verdict. Not just allow-or-deny — the policy can rewrite the action before it executes: redact a field, downscope a query. Permit-with-modification is how real-world control works, and most guardrail tools don’t model it.
Approvals bind to the exact action. When a call escalates to a human, the approval is bound to a hash of the canonical, post-transform action — so the approver consents to the thing that will execute, not a description that could mutate after approval. That closes a race most human-in-the-loop designs don’t even acknowledge.
Approval fatigue is a governed quantity. The manifest has a fatigue_threshold: too many escalations in a window is itself a policy event. Treating the human reviewer as a rate-limited resource is the kind of primitive you only design after watching approvals fail in practice.
And one more thing worth stealing that isn’t code: the repo has a candid LIMITATIONS.md — it plainly documents that the toolkit can’t catch sequences of individually-allowed actions, can’t verify outcomes, can’t see across sessions. Transparency as a feature. More vendors should write that file. (We wrote ours on the trust page.)
The deeper takeaway: Microsoft’s position is now that agent safety is enforced at the action, deterministically, outside the model. Their docs make the argument bluntly — prompt-level safety is a polite request to a stochastic system; a denied action should be structurally impossible, not unlikely. If you’ve been hand-rolling per-agent checks and wondering whether the choke-point approach is right, that argument is over. Everyone from the Reddit threads to Redmond has landed on the same answer.
What a library structurally can’t do
AGT is a library. The enforcement point lives inside the agent’s process. That’s a legitimate design with real advantages (no network hop, no external dependency) — and three consequences that matter the moment you run more than one agent:
There’s no plane. Each instrumented process governs itself. There’s no fleet view, no cross-agent rollup, no “what did all our agents do today,” no per-agent run analytics. A team running eleven agents across four frameworks gets eleven local enforcers and zero shared picture.
The audit trail is local. The Claude Code plugin writes a hash-chained log — to a JSON file on the developer’s own disk, capped at 10,000 entries, shipped nowhere. Tamper-evident, but also unaggregated, uncorrelated, and invisible to anyone but the person whose laptop it’s on.
A process that isn’t instrumented isn’t governed. In-process enforcement is opt-in per host. The control plane pattern — enforcement in the call path, outside the process — is what makes coverage a property of the path rather than of each agent’s diligence.
None of this is a flaw in AGT; it’s the definition of a library. Microsoft’s own answer to the plane question is the paid stack around it — Entra Agent ID and Agent 365 — which is also the answer to “who is this for”: organizations already in that gravity well.
The lesson the market is about to learn wrong
Here’s the part I actually want to argue with. AGT’s own comparison docs draw the market map like this: action governance is one product (theirs), and cost, routing, and caching are another (the LLM gateways). Governance over here, the meter over there. Two categories, two purchases, two integrations.
I think that split is exactly backwards, and it’s worth saying why before it hardens into conventional wisdom.
The governed call and the metered call are the same event at the same choke point. The moment you intercept a tool or model call to ask “is this allowed?”, you are holding everything needed to answer “what does this cost?” — the tool, the model, the tokens, the caller, the run it belongs to. Splitting them means two interceptors observing the same call, two sources of truth that drift, and — worse — a policy layer that can’t see spend and a cost layer that can’t enforce anything.
The failures teams actually hit live in the overlap. A runaway loop is a cost signal that needs an enforcement response. A budget cap is a policy whose input is a meter. “Which step of this run burned $6 of the $6.60” is a cost question you can only answer from the enforcement point’s position in the call path. Deny-by-policy and halt-by-budget are the same muscle. Separate them and you rebuild the join badly, in a dashboard, after the fact.
So take Microsoft’s validation of the choke point — and refuse the map that puts the meter somewhere else. The action is where risk becomes real and where money becomes real. One layer should own both.
Where this leaves things
If you’re a platform or security team on Azure with the appetite to operate a policy kernel per framework, AGT is a serious, well-designed toolkit and it’s free. Use it; the spec shapes are good, and we expect to align our own delegation-chain spec with the parts they got right — capability narrowing with a human sponsor at the root of every chain is the correct invariant, and they wrote it down cleanly.
If you’re the engineer whose team ships agents that touch real systems, and what you want is one panel where every agent’s every call shows up identified, policy-checked, and priced — that’s the control plane as a product rather than a library, and it’s the thing we build. The homepage shows it live, counter included.
Either way, the category question is settled, and Microsoft settled it in public: control the action, deterministically, outside the model. The remaining question is whether your control layer can also read the bill. Ours can. That’s the point.