Skip to main content
Decisions before the action, not alerts after it

Decide what an AI agent may do — before it does it.

Agent Assembly evaluates the actions you route through it against your policy, refuses them, or blocks them pending a decision, and records what it decided. An action you have not routed through it is not inspected — and the record says so.

The problem

An agent can act faster than anyone can review it.

Monitoring answers the question afterwards. The decision that matters happens a moment earlier — while the action can still be refused.

A coding agent decided to upload the repository it was working on to an endpoint nobody had approved. Because the agent was launched through Agent Assembly’s managed launch for Claude Code, the connection was evaluated against the destination list the team configured, and refused before the proxy dialled it.

Where this applies. This applies to connections you route through Agent Assembly — today, via the managed launch for Claude Code — on a host where the proxy is installed: a released artifact on Linux, and on macOS via cargo install aa-proxy. On Windows there is no local mediation. It applies against an approved-destination list you configure. An agent you did not route is not inspected, and the record says so. A durable local record of the refusal exists only where the proxy’s audit path is configured.

A key in a prompt

An agent pasted a live API key into a request to its model provider. On the provider hosts Agent Assembly inspects, the key was recognised and removed before the request was forwarded. Detection is bounded by the patterns it knows, and the default is to redact and forward, not to block.

A tool call against production

An agent called a tool that would have dropped a production table. The call was evaluated against your policy and refused before the proxy forwarded it. This covers MCP tool calls sent as ordinary HTTP POSTs; tool servers you run over stdio (the most common setup), SSE, or Streamable HTTP are not on this path.

A retry loop that keeps spending

An agent in a retry loop reached the spend cap its team had declared, and the next call was refused by the policy decision. A cap exists only where a policy declares one, and the refusal stops the call only where something in front of it waits for that answer.

Each scenario’s decider, default state and known bypasses →

How it works

Route it. Decide it. Show it.

Three steps, in the order they happen. No product vocabulary is required to follow them, and none of the three is skippable — step one is what makes the other two possible.

1 · Route itAn agent is on a governed path when you have put it there: launched through aasm run, started by a developer-tool integration that writes the proxy settings into the tool’s own configuration, or calling a policy checkpoint from an SDK. Routing is a thing you do, per agent and per launch. An agent you did not route is not on the path — and not every tool has a managed launch to offer.
2 · Decide itBefore the action takes effect, something on the path decides whether it may proceed — and which thing depends on the path. The proxy refuses on its own local configuration for connection-time egress and for model-provider hosts. The control plane answers policy, budget and approval questions, and it holds no traffic: its answer stops an action only where a component in front of that action waits for it.
3 · Show itDecisions are written to a hash-chained audit log you can verify yourself with aasm audit verify-chain, which ships in the open-source build. Where nothing inspected an action, the rule is that the record reports it as not inspected rather than as allowed. Emission is best-effort — a decision can be made and its record lost — so the log is a record of what got through, not a ledger of what happened. What reaches the log also depends on which path you took in step 1: an SDK checkpoint answers the question, but a denied SDK call writes no audit record, in any of the three SDKs. That emission is planned — decided, not built — so the SDK route gives you a decision without evidence of it (AAASM-5665).

The same three steps, at evaluator and engineering depth →

Supported outcomes

What a decision can be — and which component makes it

These are not four branches of one verdict. Each has a different decider, a different default and a different reach, and the right guarantee attributed to the wrong component is its own kind of wrong. Redaction in particular is a separate stage, applied after the connection decision.

Denied before execution

Refused before it ran

A connection made on a path you routed through Agent Assembly is checked against the destination list you configured and refused before the proxy dials it.

The refusal is the proxy’s own local egress configuration, not a control-plane decision, and the destination lists are empty by default — this refusal exists because an operator configured it. One egress control is on by default and no configuration relaxes it: requests to loopback, private, link-local and related address space are refused, including where a public hostname resolves into them.

Redacted

Removed before it was forwarded

On the model-provider hosts Agent Assembly inspects, a recognised credential is removed from the request before it is forwarded.

Three built-in hosts, because payload inspection is limited to model-provider hosts by default. The default action is redact and forward, not refuse. Recall is bounded by the pattern set, and model responses on that path are not scanned. This does not keep a credential out of the agent’s own process.

Evaluated

Evaluated against your policy

An MCP tool call can be checked against your policy by the control plane and refused before the proxy forwards it. A tool call through a wrapped framework seam is checked before the tool body runs.

The MCP path is the only gateway-bound pre-dial refusal in the product, and it is off by default; tool servers over stdio — the most common setup — SSE and WebSocket have no interception mechanism. The SDK is advisory by design, a defence-in-depth posture rather than the authoritative gate: an agent that does not call it is not asking, and the Node SDK’s default mode produces no refusal at all.

Approval required

Blocked pending a decision

A policy rule can hold an action rather than answering it. The hold is real and it fails closed: the check blocks, and a timeout resolves to a refusal.

Stated here as an unfinished capability, because that is what it is. No shipped operator surface can answer the queue the hold blocks on, so in practice it blocks and then refuses at the timeout with no person involved. Do not plan on human review yet — tracked as AAASM-5657.

The trust boundary and its enumerated bypasses →

Proof

Five things you can check without taking our word for it

See an action denied, and the effect it did not have

One recorded run: an agent tool call refused before its body ran, with the file that body writes shown missing afterwards by a separate process that took no part in the decision. Two control runs sit beside it — one that allows the same call, one that removes the enforcement point — and both wrote the file. It is one tool on one path at one version, and the page says so.

The denied-action proof →

Verify the audit chain yourself

aasm audit verify-chain ships in the open-source build. It proves the integrity of the entries that are present — not that the log is whole. The chain is tamper-evident, not signed: an unkeyed digest over the JSONL sink, so an emptied log verifies clean and exits zero.

What verification does and does not establish →

Read the policy that produced the decision

Policy is versioned YAML or JSON you review through the Git workflow you already use. The field reference is published, so a rule you are shown on this site is a rule you can look up.

Policy field reference →

Trace any sentence on this page to its bound

Every capability sentence here is one of sixteen entries in a shared claim register, quoted rather than paraphrased. Each entry carries the term it reaches, the bound that travels with it, and the evidence rows behind it — including the two subjects the register records as unmeasured.

The claim register →

Read the runtime that makes the decision

The gateway, proxy, CLI and SDKs are Apache-2.0 on GitHub, with the tests that pin each behaviour described here. What is open source and what is not is stated rather than implied.

The open-core boundary →

And three things this page will not claim yet

  • That every decision reaches the log. Emission is best-effort: the chain head advances before the send, and a dropped entry is indistinguishable from a deleted one. Where a record is attempted, whether it durably arrives is Unmeasured. The SDK path is not that case and that word does not cover it: a denied SDK call emits nothing at all, which is measured rather than unknown (AAASM-5665).
  • Verified agent identity. An agent presents an identity and a possession proof, but the agent plane accepts callers without authentication by design, as a bootstrap path. Treat an agent id as asserted, not established.
  • Any coverage figure — a percentage, a count of governed actions, or a number spanning a set of machines. There is nothing to compute one from, and a component reporting itself available is not evidence that it saw anything.
Current position

What is on out of the box, and what is not

A capability that exists but is off is a different product from one that is on, so here is the default posture before you configure anything. Read it in both directions — two rows below are stronger than an evaluator usually expects.

Out of the boxDefault
Launching a session with no policyRefused. aasm run will not start a tool when no effective policy resolves, and will not start one whose policy parses but declares no rule. An absent policy is not permission.
Private-address egressRefused, always. The guard re-checks every resolved address before dialling, so a public hostname that resolves into private space is refused too. No configuration and no environment variable relaxes it.
Your own allow and deny listsEmpty. You configure them, per destination.
Payload inspectionNarrow. Three built-in model-provider hosts are inspected by default. Any other host is tunnelled without payload inspection: the connection is observed, the payload is not.
Recognised credentialsRedact and forward. Blocking on a detected credential is opt-in. Model responses are not scanned.
SDK enforcementOff in the default mode. A policy refusal blocks a wrapped tool only in the check-capable mode; asking for enforcement without it is refused loudly at init rather than silently allowed.
An action matching no ruleAllowed. Default-open within a policy, default-refuse on having one — both halves, or the pair misleads.
Spend capsNone unless a policy declares one; an undeclared budget is uncapped. Whether a declared cap is checked in the decision path is Unmeasured, and a corrupt budget store resets the cap silently.
Operating-system-level controlsOff unless deployed, and not a decision point. On Linux, kernel probes report TLS plaintext, process execution and file activity; no such signal takes part in any allow or deny decision, and file-I/O probes are x86_64 only. macOS has no equivalent adapter — and is also the one platform where the host-enforcement rung is reachable at all, through an opt-in authorized settings write. Windows has neither.
AuditOn, best-effort. Hash-chained JSONL, verifiable in the open-source build. Writing is not guaranteed, so the log records what got through rather than what happened.

Platforms. The proxy that delivers most of the above is a released artifact on Linux; on macOS it is a cargo install aa-proxy. On Windows there is no local mediation of any kind. UDP, QUIC and HTTP/3 are outside the transport set.

Maturity. The open-source runtime is pre-1.0 and released as a pre-release series. The managed service is planned — decided, not built — so nothing on this site is a commitment to an availability date, a region, an SLA or a compliance position.

Known limits, per integration → · Release status, area by area →

Where to go next

Start from the decision your job actually ends in

Five readers, five different first pages. Each route below ends in a decision rather than in more reading.

Evaluating it

You are on the right page. What is left is the shape of the product itself — what it decides, where the decision is applied, and what it deliberately does not do.

Ends in: a trial started, or a recorded reason not to

What the product is

Security and risk

Go straight to the edge of the boundary: the enumerated bypasses, the failure posture of each control including the ones that fail open, and the platform matrix in both directions.

Ends in: an approval or a refusal for one deployment

The security model

Platform and SRE

The thing to learn first is that routing is per agent and per launch — an agent nobody routed is outside all of this. Then: which artifact, on which platform, from which channel.

Ends in: a governed launch on one host

Install and route one agent

Engineering

Add a policy checkpoint in Python, Node or Go — and choose an SDK mode knowing that the default is advisory and that an unadapted framework is outside the wrapper.

Ends in: code that runs and reaches a decision

SDKs and framework examples

Product, QA and assurance

Take a published claim and reach what backs it. The scenario page records each determination, what it rests on, and which wording is held back until a proof harness runs.

Ends in: a cited row, or a recorded gap

Claims and their determinations

The four role routes above — security, platform, engineering and product — each have a fuller brief: what is going wrong today, what is supported, how far each answer reaches, what it does not cover, and what to read next. Read the evaluator briefs →

Running it as a managed service is a fifth path, and it is not available yet — the control plane is in early access with design partners only. Request Cloud Early Access →

Install the OSS runtime

Start self-hosting the way you already work

The open-source runtime self-hosts a limited-function stack for local evaluation and development — full functionality runs in the managed cloud. Pick your install path; each command is real, with no placeholder URLs, and pre-launch tabs are labeled honestly.

macOS and Linux. The script is served from agent-assembly.com/install.sh — review it before piping to sh if you prefer.

curl -fsSL https://agent-assembly.com/install.sh | sh
From the blog

Build notes, engineering, and security write-ups

Why the runtime boundary matters and how we’re building it.

Put the decision before the action.

Route one agent, refuse one call it should not have made, and read the record it left.