Executive Summary
- The OWASP GenAI Security Project published the Agent Control Standard (ACS) v0.1.0 in September 2026. It is a runtime protocol: it defines how an AI agent asks a separate control process, the Guardian, for permission before it acts, how the Guardian answers, and how that exchange is recorded.
- ACS is optional: a Guardian can enforce its controls through its own API. What ACS adds is portability. Because every agent and Guardian speak the same format, you can change Guardian vendors without changing how the agent asks, and hand the signed record to an independent verifier.
- ACS governs only the steps you hook, such as a tool call, an MCP request, a memory write or a reply. Anything unhooked never reaches the Guardian.
- ACS stops nothing by itself. A conformant agent must wait for the Guardian's answer and follow it; if it does not, the exchange is merely recorded. Blocking an action regardless of what the agent does is a separate product capability.
- Conformance is self-declared, and the default when the Guardian does not answer in time is to proceed. Buyers have to test support themselves, and the test at the end takes about a week on one agent.
ACS, the Guardian, and the Observed Agent
Three terms carry this post. ACS is the protocol. The Observed Agent is the AI system that must ask before it acts: an assistant, a workflow agent, or anything that calls tools. The Guardian is the control process that answers, which the ACS specification calls the Guardian Agent. A Guardian vendor is the company that sells one.
A Guardian runs next to your agent as a separate process. It is not the agent, not a SIEM and not a dashboard. Before the agent calls a tool, writes to memory, retrieves knowledge or sends a response, it sends the Guardian an ACS hook asking permission for that specific action, and the Guardian returns one of five decisions: allow, deny, modify, ask or defer. The agent must wait for the decision and honor it. The specification leaves no room here: "A framework that emits hooks but proceeds without applying the verdict is not conformant."
The Guardian should decide with written rules first. The specification describes a deterministic policy layer that always runs first, with Open Policy Agent's Rego as the v0.1 reference engine and Cedar planned for v0.2, and an optional LLM layer that runs only when the deterministic layer delegates to it. That LLM belongs to the Guardian product. It is not part of ACS, and it is not the agent.
What travels over ACS, and what stays inside the Guardian
ACS carries the permission request and the Guardian's decision, and only that decision binds the agent. If the Guardian raises a warning in its own console and still sends allow, the agent may proceed (Figure 1).

- Travels over ACS: the hook (may I do this?), the Guardian's decision, the handshake, and the chain hash and signature on those messages. If the vendor claims the matching profiles, the agent's inventory snapshot, change notices and origin records on payload data travel over it too. Under acs-trace each step is also emitted to your collector as an OpenTelemetry or OCSF event, outside the ACS request path.
- Stays inside the Guardian, and remains the vendor's job or yours: writing and storing policy, and whether it is the right policy; threat-intelligence feeds; baseline scoring; posture management over time; dashboards, alerts, administration and billing; the vendor's own models and logs.
- Never reaches ACS at all: your production databases, the agent's private chain of thought unless a hook includes it, fleet-wide awareness and SIEM correlation across sessions, and independent proof that a deny fired on the path that matters. ACS also does not replace IAM, secrets management or network segmentation around the agent.
ACS-Core
ACS-Core is ACS as spoken in a live session, and the conformance rules make it the mandatory baseline. The optional profiles add fields and methods to the same conversation rather than forming a second protocol. A vendor that claims ACS support without implementing Core is not speaking ACS.
| Core piece | What it is |
|---|---|
| Handshake | handshake/hello. The Observed Agent sends profiles_supported; the Guardian returns profiles_accepted. |
| Request envelope | JSON-RPC 2.0 whose parameters carry acs_version, request_id, timestamp, metadata and payload, in the namespaces steps/*, protocols/MCP/*, agbom/*, handshake/* and system/* (which holds only system/ping in v0.1). |
| Minimum hooks | sessionStart; userMessage or agentTrigger; toolCallRequest and toolCallResult for any tool; agentResponse; sessionEnd; wrapped MCP. The other hooks, memory included, are recommended wherever the framework can observe the event. |
| Decisions | allow, deny, modify, ask, defer, with reasoning required on every decision except allow. |
| Integrity | A rolling SHA-256 chain hash, published and signed on every recorded step; a signature on every hook request and response, with HMAC-SHA256 as the baseline; rejection of any repeated request_id. |
| Timeout and failure posture | The agent waits up to the negotiated timeout, which may differ per method, then applies on_decision_failure: one setting for the whole session, either proceed (the default, fail-open, every proceed logged) or deny (fail-closed). |
Hooking only some calls, such as function calls, connectors or MCP, is valid control of those calls but not a full Core session: without the user-message and response hooks, the Guardian never sees why the agent started or what it finally said.
MCP gets its own namespace for a specific reason. An MCP tool call can be governed through toolCallRequest like any other tool, as the MCP extension allows. But MCP also carries traffic that is not a plain tool call: server instructions and capability grants at initialization, prompt templates a server supplies, and resource reads. The generic tool hooks erase those distinctions, and only the protocols/MCP/* wrapper keeps them visible to the Guardian as MCP. The conformance rules list wrapped MCP under Core while the MCP extension calls it optional, so ask each vendor which it implements.
The failure posture deserves attention before signing. The specification describes the default this way: under fail-open, "an adversary who can disrupt the channel converts control into audit." Because the posture is one value per session, ACS v0.1.0 cannot express a rule such as fail closed on money movement, record changes and egress, and fail open elsewhere. A vendor can build that into its own integration, but then it is a product feature rather than ACS. Handshake failure has a separate setting, and its default is to start the session unguarded.
Profiles
A profile is an optional, named set of additional ACS messages and fields for one session. At the handshake the Observed Agent lists the profiles it can speak, the Guardian lists the ones it will use, and only profiles both sides named are active. They can be enabled independently, except that inspect-dynamic builds on inspect, and a vendor that lists one must implement it. The first row is Core, because the handshake names it too.
| Profile | What the protocol requires | What it shows | Buyer test |
|---|---|---|---|
| acs-core | Handshake, envelope, minimum hooks, all five dispositions, replay rejection, signed chain hash, timeout and failure posture, system/ping, and signatures with HMAC-SHA256 as the baseline. | The channel is authenticated and the agent honors this session's decisions. | Capture the ClientHello and ServerHello against your own agent. Replay a request_id and confirm it is rejected. |
| acs-trace | OpenTelemetry or OCSF events for every supported step, with each decision recorded on the step's span. Emission must never block enforcement. | The step and its decision reached your collector together, linked in one trace. | Follow one toolCallRequest through its decision into your pipeline. |
| acs-inspect | agbom/snapshot, the agent's bill of materials, once per session before any content-bearing hook, renderable as CycloneDX 1.6, SPDX 3.0 or SWID. | At session start you can name the models, MCP servers, tools, knowledge sources, memory stores and skills in play. | Demand the snapshot before the first user message, open it, and look for components nobody mentioned. |
| acs-inspect-dynamic | agbom/changed whenever a model, tool, MCP server or skill changes mid-session. The Guardian may deny the swap. | Hot-swaps are visible to policy inside the session. | Swap a model or MCP server. Confirm the notice fires and the next tool call is re-evaluated. |
| acs-provenance | An origin record (user input, tool output, retrieved content, agent-generated, with lineage) on every data-bearing field of every hook payload, written by framework code rather than the model. Every AgBOM component also records who registered it. | Policy can tell where a value came from, for example that a tool argument was copied from a retrieved document. | Send a tool call whose argument came from retrieved content, and confirm its provenance traces back to the retrieved item. |
| acs-crypto | Asymmetric signatures, with the post-quantum algorithm ML-DSA-65 required and SLH-DSA-128s recommended. | Someone outside the vendor can verify who signed an envelope, which the HMAC baseline cannot show. | Verify one exported response with the published public key, and ask which algorithm is on the wire. |
| acs-audit | A hash of the request content on every audit-chain entry. | The chain commits to what was asked, not only to step metadata. With acs-crypto, rewriting last Tuesday's deny becomes hard even for the Guardian that recorded it. | Export a session with a deny and a modify, recompute the chain, and confirm the payloads are part of it. |
Hook catalog
A hook is the message the Observed Agent sends the Guardian at a defined moment, such as before a tool runs, before memory is written or before a reply goes out, so the Guardian can decide while the action can still be stopped or changed. The hook specification marks each one as decision-eligible or audit-only. The two agbom rows are inventory messages from the inspect profiles, but they share the channel and the Guardian can act on them.
| Hook | When it fires | Can the Guardian still stop it? | Why it matters |
|---|---|---|---|
| sessionStart | When the session begins, just after the handshake. | Yes, and it starts the signed record. | Establishes who is talking and under which policy mode. Profiles and the failure posture were fixed in the handshake just before it. |
| agentTrigger / userMessage | When a person types, or a timer or event starts the agent. | Yes. | The job arriving. Without it the Guardian never sees why the agent started. |
| turnStart / turnEnd | When one exchange with the agent begins or ends. | Yes at the start; the end is audit-only. | Lets you cap what the agent may do in one turn. Inferring turns from chat messages is unreliable. |
| toolCallRequest | Before a function call, API or connector runs. | Yes. | Where money moves, records change or data leaves. |
| toolCallResult | After the tool returns, before the agent uses the result. | Yes. | The Guardian can block or change an unsafe result before the agent plans its next step. |
| protocols/MCP/* | When the agent speaks MCP. | Yes. | Keeps server instructions, prompt templates and resource reads distinguishable as MCP, which generic tool hooks erase. |
| knowledgeRetrieval | When the agent searches a knowledge base or documents. | Yes. | You can block a banned source, and you see the query as well as what the agent later cites. |
| memoryContextRetrieval / memoryStore | When the agent reads or writes long-term memory. | Yes. | A denied write stops the agent parking secrets or bad instructions for a later session. |
| preCompact / postCompact | When the agent shortens its working context. | Yes before; afterward the Guardian can rewrite the summary but not deny. | Compaction can drop evidence, so the Guardian should see what is about to be discarded. |
| agentResponse | Before the reply reaches a person or another system. | Yes. | The last chance to remove secrets or stop a reply that commits the organization. |
| subagentStart / subagentStop | When the agent starts or finishes a child agent. | Yes at the start; the stop is audit-only. | The child often gets the same tools, and an unhooked start leaves it with no Guardian. |
| skillRegister / skillLoad / skillUnload | When a skill is added, turned on or turned off. | Yes when added or turned on; off is audit-only. | If the inventory lists skills but these hooks never fire, the Guardian is blind to that capability. |
| agbom/snapshot | Once at session start, before any work. | Yes: the Guardian can refuse a session with a banned component. | The agent's parts list. Policy that depends on it cannot run without it. |
| agbom/changed | When a model, tool, MCP server or skill changes mid-session. | Yes: the Guardian can block the swap. | Without it, the Guardian may still be guarding the old agent. |
| sessionEnd | When the session finishes. | No; it only records. | Closes the signed record. Export that record rather than a dashboard screenshot. |
Five dispositions
| Disposition | What it means |
|---|---|
| allow | Proceed with the payload as sent. |
| deny | Block, with reasoning. |
| modify | Proceed with a changed payload the agent must apply (different arguments, a different destination, or redactions) rather than sending the original. A malformed change must be treated as a deny. |
| ask | Pause for approval by a named person, agent or service, with a stated route for the answer. |
| defer | No verdict yet, and never an implied allow. The decision states how and by when it resolves, and if that deadline passes the default is deny. |
A Guardian that can only say yes or no is not speaking ACS-Core. Agents that cannot route an approval request, such as IDE plugins or headless automation, remain conformant, because the specification then requires the Guardian to answer defer or deny instead of ask.
What ACS proves, and what it does not
No third party checks a vendor's claim. The conformance rules state it directly: "Who verifies a conformance claim: nobody, in v0.1.0." There is no test suite, registry or steward body, so "ACS-Core conformant" is a statement a vendor makes about itself, and conformance says nothing about how strict the policy is: "A permissive Guardian is a conformant but permissive deployment, not a violation."
| ACS can show, if the profile is on | ACS cannot show |
|---|---|
| The agent asked before it acted, on every hooked step. | That the Guardian's policy is the right policy. |
| The Guardian answered with one of the five decisions, with reasoning on everything except allow. | That a deny fired on the production path that matters, unless you traced that path. |
| The envelope was signed, and under acs-crypto with a key you can verify yourself. | That the AgBOM lists every tool. A tool the agent never reported is simply absent. |
| With acs-inspect: what the agent was made of at that moment. | That last quarter's lab result survives a model or MCP swap. |
| With acs-trace: the same step in your pipeline or SIEM, decision attached. | That an independent party has tested the full live deployment, with all its parts connected. |
| With acs-crypto and acs-audit: a chain that commits to request content and resists rewriting, even by the Guardian. | That fail-open proceeds were acceptable, which remains your governance call. |
How a typical Guardian vendor's control uses ACS
A typical Guardian vendor's control runs in four stages: data ingestion (logs, code, feeds and ACS hooks), posture and policy, runtime action (stop, change or ask) and feedback (validate, audit, log). A hard safety boundary comes first, defining which agents, tools, APIs, connectors and data stores are allowed at all, and it is enforced by rule rather than by score. An activity baseline, asking whether a step is unusual for this agent, applies only after the boundary and the policy allow the step.
| What is happening | Agent to Guardian | Inside the Guardian | Guardian to agent |
|---|---|---|---|
| An action the boundary forbids | A hook with the attempted action (toolCallRequest, wrapped MCP, memoryStore, subagentStart and so on). | An allow-list check, with no scoring of normal behavior. | Deny or modify on the same hook. The agent must stop or use the rewritten request. |
| The boundary allows it, but the pattern is unusual for this agent | The same hook. ACS carries no normality score. | A comparison with the agent's baseline, leading to deny, change or ask. | Deny, modify or ask, with a short reason. A warning on the vendor's screen followed by allow lets the agent continue. |
| Reconstruction later, in a SIEM or audit | No new hook; the earlier envelopes are the raw material. | Validate containment, update the baseline, attach reason codes. | No new command. You export the signed ACS record; a log kept only in the vendor's product is not that record. |
| The inventory or the boundary changes | agbom/changed, or a new handshake/hello if profiles or the failure posture changed. v0.1 refers to a re-handshake but leaves the mid-session mechanism to v0.2. | Reset or shift the baseline, and move the boundary if the allow-list changed. | A signed ACS reply with the new parts list or profiles. A change made without that message does not reach the agent. |
What to require from a Guardian vendor
Write these into the purchase agreement so they become deliverables rather than slides:
- ACS-Core plus the exact profiles this deployment will use, as named in the handshake.
- Which hooks ship now and which come later.
- Fail-closed when the Guardian does not answer in time, at least for actions that move money, change records or send data out. ACS sets one posture per session, so a selective version is something the vendor builds and documents, and every fail-open proceed must appear in the export.
- Ownership of the signed record, and the ability to send it to your SIEM.
- A parts list of your agent on demand, and a change notice whenever the vendor swaps a model or MCP server.
- Read access to the written policy, with the version in force pinned.
- If the Guardian uses an LLM, it runs only after the written rules delegate to it.
Do not accept marketing language such as "ACS-ready", "compatible with ACS" or "aligned to the standard", session logs with no ability to deny, or a parts list of the vendor's demo agent only.
Does this Guardian vendor actually support ACS? A buyer checklist
These questions check the requirements above against your own agent rather than the vendor's dashboard. If they fail, the product is not speaking ACS to your agent.
- Can the vendor open a real ACS session with your agent, not a demo bot, and show which profiles both sides accepted?
- Which hooks fire today on your agent: tools only, or also memory, MCP, child agents and skills?
- When the Guardian does not answer in time, does the agent stop before money moves, records change or data leaves?
- Can you export the signed ACS record into your SIEM?
- Does a deny, modify or ask arrive as an ACS message your agent is waiting for? An emailed alert, an update on the vendor's own screen, or an internal model talking to the agent over a private API is not ACS support, however good the policy behind it.
- When a model, MCP server, tool, skill, knowledge source or memory store is swapped mid-session, does an ACS change notice fire in that same session?
Prove it in a week. On one agent you own, with the vendor's Guardian answering, run six cases: a normal tool call, a call that should be denied, a modify, an ask, a memory write and a mid-session swap. Confirm that all five decisions work, that MCP prompt fetches and resource reads reach the Guardian as MCP rather than as anonymous tool calls, and that you can export the signed record and recompute its chain. If trace or inspect was accepted, check that one step reaches your collector and that the parts list opens.
Sources. OWASP GenAI Security Project, Agent Control Standard (ACS), and the specification repository, v0.1.0: the Instrument specification, the conformance profiles, the hook catalog and the MCP extension. The next release, v0.2.0, targets March 2027.




