Skip to content

Build1 publisher3 min readPublished

Microsoft's agent governance toolkit runs its policy engine inside the agent's own process

Microsoft's Agent Governance Toolkit README says its policy engine shares a process with the agents it governs, even inside a per-agent container. Zarel, which sells a competing design, argues that governance has to take execution away from the agent entirely.

The Engineer · Build desk

Illustration accompanying Microsoft's agent governance toolkit runs its policy engine inside the agent's own process

What happened

  • In the middleware pattern the toolkit uses, each agent action is intercepted before it runs and checked by a policy engine that answers allow or deny, often in well under a millisecond.
  • Zarel, the company behind the post, treats the model as a remote service whose answer is a proposal, schema-validated and handled as untrusted data from the moment it arrives.
  • Between that proposal and any real effect, Zarel runs a deterministic pipeline that takes identity from the signed token and the state of the world from the database.
  • Given retrieved text telling it to pay attacker@example.com $50,000, the model proposed exactly that, and the pipeline swapped in the authenticated user and refused the over-cap amount.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • constraint By Zarel's account, a faster interceptor does nothing against a turned agent, so sub-millisecond policy checks are a latency figure and say little about containment.
  • decision Teams that let agents run code or load plugins inside the governed process have to put the final write in a separate service that reads the token and the database itself.
  • cost Binding puts the work on whoever writes the contracts: each consequential field needs a named source of truth, kept current as the data model changes.

Venkat Peri, who works on agentic AI infrastructure for wealth management at Advisor360, quoted that README passage in his review of the toolkit and wrote: "That sentence matters." [3][4] The post that brought it back up was published on the site of Zarel, which builds the alternative the post goes on to describe [15].

The threat the post cares about is an agent turned by a prompt injection, or by a poisoned tool result it then treats as an instruction [6]. Its argument is that the compromised component is already inside the boundary meant to contain it [6]. I think that holds under one condition. An in-process interceptor still sees each tool call a hijacked model emits, and it can still deny the forbidden ones. Sharing a process becomes the real weakness when the agent can run code there and reach the policy engine's state. Zarel's design removes that condition: no model weights and no agent-authored code execute inside its process [17]. The author also calls the containment model a real upgrade and says the dispute is only about where its boundary sits [16].

Permission checks alone leave one attack open. A permitted action can carry a hostile value, such as the right kind of payment sent to the wrong recipient [9]. Zarel's answer is to declare in the contract where each consequential parameter comes from [9]. The demo contract, param_binding, binds three fields on its payment entity [10]. The recipient has `bind: actor.user_name`, and the model's value is discarded [10]. The quote reference is `immutable_after_set: true` [11]. The amount is USD currency at two decimal places, with a minimum of 0 and `assert: "value <= quote.cap"` [12].

Order is the detail I like most. Every create passes through one pipeline in record-service. The bindings run after the permission checks and before shape validation, the contract's checks and the database write [13]. Because the overwrite comes first, every later check sees the server's recipient and never the model's. A refusal is written as a row holding the field, the rule it failed, and a hash and masked copy of the value, before the refusal goes back [18]. An operator can match repeated injection attempts from those rows without keeping the payload in the clear.

The contract also shows where the approach stops. Binding the recipient to `actor.user_name` makes the recipient whoever holds the signed token [8][10]. A payment to a third party needs some other authoritative record. The demo has one only for the amount: the anchored quote, whose cap bounds what can be sent [12]. `immutable_after_set` stops a turned agent from re-pointing the quote once it is set [11]. The post does not say who sets it first. If the model proposes the quote reference at creation, a poisoned agent can pick the quote with the largest cap and pass every rule.

The shared-process limit comes from Microsoft's own README, as the Zarel post reports it [1]. The conclusion that teams need execution taken away from the agent comes from a company that sells that design [15]. Its published evidence is one contract with three bound fields, run against one injected instruction [10][14].

What to watch

  • Whether Microsoft adds an out-of-process enforcement option to the Agent Governance Toolkit or changes the README's per-agent container guidance.
  • Whether Zarel documents who may set a payment's quote reference at creation, the step immutable_after_set does not cover.
  • Whether Zarel's contracts can bind a third-party recipient to an authoritative record, beyond the demo's actor.user_name binding.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories