The OWASP Agent Control Standard ships with a working demo alongside its written specification, and the demo contains two scenarios. In the first, an agent tries to run rm -rf / and gets stopped. In the second, an agent submits SELECT * FROM customers and gets a narrower query back. The requests arrive in the same shape and the answers come back in the same shape, but the control system is doing two different jobs.
Both requests arrive as JSON-RPC calls — a simple message format where the agent names a method and passes it arguments — through the method steps/toolCallRequest. Each message carries an agent ID, a session ID, the name of the tool being invoked, and the tool's arguments. The Guardian is the component that sits between the agent and its tools. Every call stops there first and gets checked against policy before anything runs.
The shell command comes back deny. The Guardian matched rm -rf / against a known destructive pattern and refused, returning a reason code and a reference to the rule it applied. Nothing about this decision required knowing what the agent was trying to accomplish.
The SQL query comes back modify. The Guardian substituted SELECT id, name FROM customers LIMIT 100 for the original — capping the row count, and also narrowing the columns from everything to two named fields. The ACS documentation attributes this to the deterministic policy layer: a written rule, not a language model making a judgment call in the moment. Which means the rule had to already contain the answer. Someone sat down and decided that on this table, id and name are fine to hand back and the rest of the columns are not.
That is the part I keep turning over. Refusing something requires recognizing it. Replacing something requires knowing what the acceptable version looks like — and that knowledge has to come from somewhere, either baked into the rule in advance or supplied to the Guardian at the moment it intervenes.
The full ACS specification is built around supplying it. The protocol makes room for intent descriptions attached to individual tool calls, session-level intent objects listing which capabilities were authorized, provenance tracking on arguments, user roles, and context accumulated across 19 lifecycle hooks — defined moments in an agent's run where the control system can be consulted. The demo implementation evaluates two of them. Neither scenario touches the rest of that surface.
The deny scenario has no use for it. Matching rm -rf / doesn't get better if you know the session history. The modify scenario is where the richer protocol starts to matter. A hardcoded column projection holds up when schemas are stable and agents all want roughly the same thing. Once table structures drift and agents pursue different objectives, whether the rewritten query is still the right query depends on context the rule was never given.
One more detail from the demo. If the Guardian is unreachable, the implementation defaults to proceed: the agent continues with its original action, unmodified. An environment variable flips this to deny. That default is a judgment about which failure costs more — an agent halted by a control-system outage, or an unchecked action getting through — and it is made once, in a config file, on behalf of every deployment that never revisits it.
- Only two hooks evaluated: The ACS specification defines 19 lifecycle hooks covering user input, retrieval, memory, subagents, and session boundaries, but the reference Guardian currently evaluates only
toolCallRequestandtoolCallResult, leaving most of the information-routing surface unexercised. - GET requests, real consequences: A German-wiki incident earlier this year showed that an agent constrained to GET requests still triggered state-changing actions because the legacy application attached different semantics to the HTTP verb than the control layer assumed.
- NIST on identity foundations: NIST's August guidance argues that agents should become first-class identities with audience-restricted, dynamically scoped credentials rather than inheriting a user's broad access — while warning that excessive confirmation prompts can create consent fatigue analogous to MFA bombing.
- Cancellation isn't reversal: The MCP Tasks extension's July draft describes cancellation as cooperative, where a server acknowledges a stop request but may not be able to halt the work, and a task can finish in another terminal state after cancellation is requested.

