# Defense-in-Depth Score: Agent Zero

**Repo:** https://github.com/agent0ai/agent-zero · **Commit:** `e3051fb584b1a36be2b0a0c90606f1c2c2d356ec` (v2.13) · **Reviewed:** 2026-10-03
**What it is:** General agent framework with Dockerized Linux desktop, browser and host bridge
**Category:** AI Assistants
**Scored configuration:** The README's direct Docker run (`docker run -p 80:80 -v a0_usr:/a0/usr agent0ai/agent-zero`) with the Web UI, default settings, default agent profile, and bundled plugins at their shipped toggles.
**Agent surface (default):** code execution yes · filesystem write yes · network egress yes · external credentials yes · persistent memory yes · untrusted input yes · third party extensions yes · sub agents yes · external communication opt-in

## Score: 2.0 / 10.0 (Minimal)

| # | Criterion | S | C | D | B | Raw | Cap | Score | Confidence |
|---|---|---|---|---|---|---|---|---|---|
| C1 | Identity & least privilege | L0 | L0 | L0 | L1 | 0.05 | C1-SELFESC | **0.05** | High |
| C2 | Approval gates | L0 | L0 | L0 | L2 | 0.10 | C2-POWERBYPASS | **0.10** | High |
| C3 | Tool & action scoping | L0 | L1 | L1 | L0 | 0.12 | — | **0.12** | High |
| C4 | Code-execution isolation | L2 | L3 | L2 | L0 | 0.47 | — | **0.47** | High |
| C5 | Untrusted input blast radius | L1 | L2 | L0 | L0 | 0.23 | G2 | **0.23** (alt) | High |
| C6 | Memory, context & configuration integrity | L0 | L0 | L1 | L1 | 0.10 | C6-REPOCONFIG | **0.10** | High |
| C7 | Third-party extensions | L0 | L0 | L0 | L0 | 0.00 | C7-RCELOAD | **0.00** | High |
| C8 | Secrets & sensitive-data protection | L2 | L2 | L1 | L0 | 0.35 | — | **0.35** | High |
| C9 | Audit & traceability | L2 | L2 | L1 | L1 | 0.40 | — | **0.40** | High |
| C10 | Limits & kill switch | L1 | L1 | L1 | L0 | 0.20 | — | **0.20** | High |


Agent Zero gives its model a root shell, a browser, and every configured secret inside one Docker container, with no human approval step and no login on the web UI by default. The container is the only real boundary, and it is unhardened and shared with the agent's own code, settings, and secrets, so a prompt injection from a web page can leak keys and take irreversible actions unattended. Secret masking is a genuine strength, but persistent memory, self-editable behaviour rules, and repository-supplied project extensions let a single injection persist.

## Critical gaps
- The agent can rewrite its own tool-access policy and secrets store from its root shell (C1-SELFESC). (ASI03, T3; C1) — [helpers/tool_policy.py:43-56](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/tool_policy.py#L43-L56); [helpers/plugins.py:838-841](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/plugins.py#L838-L841); [docker/run/fs/etc/supervisor/conf.d/supervisord.conf:61-64](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/docker/run/fs/etc/supervisor/conf.d/supervisord.conf#L61-L64)
- The root shell code-execution tool runs with no human approval in the default configuration (C2-POWERBYPASS). (ASI02, ASI09, T10; C2) — [agent.py:1498-1505](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/agent.py#L1498-L1505); [plugins/_code_execution/tools/code_execution_tool.py:563-566](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_code_execution/tools/code_execution_tool.py#L563-L566)
- Code runs as root in the same container as the agent, with API keys in its environment and full network egress (C4 blast radius L0). (ASI05, T11; C4) — [plugins/_code_execution/helpers/shell_local.py:22](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_code_execution/helpers/shell_local.py#L22); [helpers/dotenv.py:13-18](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/dotenv.py#L13-L18); [docker/run/fs/etc/supervisor/conf.d/supervisord.conf:61-64](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/docker/run/fs/etc/supervisor/conf.d/supervisord.conf#L61-L64)
- A hijacked agent can leak secrets and take irreversible actions with no human involved (C5-WORSTCASE). (ASI01, LLM01, T6; C5) — [agent.py:825](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/agent.py#L825); [plugins/_code_execution/helpers/shell_local.py:22](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_code_execution/helpers/shell_local.py#L22); [agent.py:1498-1505](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/agent.py#L1498-L1505)
- Repository-controlled .a0proj files in a cloned project add tools, in-process Python extensions, and MCP servers without a specific trust decision (C6-REPOCONFIG). (ASI06, ASI04, T1; C6) — [helpers/projects.py:138-146](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/projects.py#L138-L146); [helpers/subagents.py:379-383](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/subagents.py#L379-L383); [helpers/extension.py:337](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/extension.py#L337); [helpers/mcp_handler.py:853](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/mcp_handler.py#L853)
- Extensions run unverified and in-process, and repository or model-supplied code loads without per-extension consent (C7-RCELOAD, B L0). (ASI04, T17, LLM03; C7) — [plugins/_plugin_installer/helpers/install.py:184-199](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_plugin_installer/helpers/install.py#L184-L199); [plugins/_plugin_installer/helpers/install.py:298-299](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_plugin_installer/helpers/install.py#L298-L299); [helpers/plugins.py:531-540](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/plugins.py#L531-L540); [helpers/mcp_handler.py:853](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/mcp_handler.py#L853)
- The only untrusted-input control, the opt-in Infection Check, fails open on errors and can be disabled by a project file or the agent's own shell (G2). (ASI01, LLM01; C5) — [plugins/_infection_check/helpers/checker.py:112-122](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_infection_check/helpers/checker.py#L112-L122); [plugins/_infection_check/plugin.yaml:7](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_infection_check/plugin.yaml#L7)

## Criterion details

### C1 Identity & least privilege — 0.05 (high)

Agent Zero runs its agent loop and every tool as root inside one container, and every tool can use every credential it holds: LLM API keys sit in the process environment that each shell inherits, and any stored secret can be spliced into any tool call through a §§secret() placeholder. There is no authorization layer that maps actions to a least-privilege policy, and the web UI has no login unless the operator sets one, so anyone who can reach the published port can direct the agent. The per-profile tool allow/block list is opt-in and lives in files under /a0/usr that the agent's own root shell can rewrite.

- **S L0:** The agent process runs as root and every tool inherits the full process environment, including API keys loaded from usr/.env, plus access to every stored secret via placeholder substitution. — [docker/run/fs/etc/supervisor/conf.d/supervisord.conf:61-64](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/docker/run/fs/etc/supervisor/conf.d/supervisord.conf#L61-L64); [helpers/dotenv.py:13-18](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/dotenv.py#L13-L18); [plugins/_code_execution/helpers/shell_local.py:22](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_code_execution/helpers/shell_local.py#L22); [extensions/python/tool_execute_before/_10_unmask_secrets.py:21](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/extensions/python/tool_execute_before/_10_unmask_secrets.py#L21) (verified)
  - *To reach the next level:* No dedicated or scoped identity: credentials are not narrowed per tool or capability.
- **C L0:** No authorization check sits between the loop and tool execution by default (tool policy inherits 'allow'), and the web UI skips authentication when no AUTH_LOGIN is configured. — [plugins/_tool_access/default_config.yaml:1-3](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_tool_access/default_config.yaml#L1-L3); [helpers/tool_policy.py:175-177](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/tool_policy.py#L175-L177); [helpers/api.py:175-185](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/api.py#L175-L185); [helpers/login.py:13-15](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/login.py#L13-L15) (verified)
  - *To reach the next level:* No authorization layer on the main tool path; actions are not checked against a requesting principal.
- **D L0:** The shipped container runs the agent as root with no login and all tools allowed. — [README.md:92](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/README.md#L92); [docker/run/fs/etc/supervisor/conf.d/supervisord.conf:61-64](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/docker/run/fs/etc/supervisor/conf.d/supervisord.conf#L61-L64); [helpers/login.py:13-15](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/login.py#L13-L15) (verified)
  - *To reach the next level:* Default install grants full root authority in the container and no login; least privilege requires manual hardening.
- **B L1:** A hijacked agent can use every configured credential (LLM keys, user secrets such as git or email tokens) and root in the container; host access is only reachable if the operator connects the opt-in A0 CLI bridge. — [extensions/python/tool_execute_before/_10_unmask_secrets.py:21](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/extensions/python/tool_execute_before/_10_unmask_secrets.py#L21); [plugins/_code_execution/helpers/shell_local.py:22](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_code_execution/helpers/shell_local.py#L22); [helpers/secrets.py:19](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/secrets.py#L19) (verified)
  - *To reach the next level:* Credentials are not scoped to one system or read-only; all secrets reach all tools.
- **Cap:** C1-SELFESC — The tool-access policy is re-read from JSON files under /a0/usr on every check, and the agent's root shell in the same container can rewrite those files and the secrets store, changing its own permissions.
- **Notes:** Port 80 is published on all interfaces by the README command; the UI shows only a dismissible banner when accessed from a non-local address without credentials.

### C2 Approval gates — 0.10 (high)

There is no human approval step for any tool. The loop extracts a tool call from the model output and executes it directly, including the root shell, Python/Node execution, browser and MCP tools. The only approval logic in the core auto-denies provider-hosted MCP approval requests; the optional infection-check plugin is an LLM judge, not a human gate, and is off by default. The Time Travel plugin snapshots workspace files after code execution, so file damage inside /a0/usr workspaces can often be reverted, but network actions and changes elsewhere cannot.

- **S L0:** Tool calls go straight from the parsed model output to tool.execute with no approval step. — [agent.py:1498-1505](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/agent.py#L1498-L1505); searched `rg -n -i approv` in `agent.py helpers/tool.py helpers/extension.py` → 11 hits (All 11 hits are agent.py's handling of provider-hosted Responses MCP approval requests, which are auto-denied; none gates Agent Zero's own tools.) (verified)
  - *To reach the next level:* No per-call human approval of any kind.
- **C L0:** The most powerful tool (root shell code execution) is ungated like every other tool. — [agent.py:1498-1505](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/agent.py#L1498-L1505); searched `rg -n -i approv` in `agent.py helpers/tool.py helpers/extension.py` → 11 hits (All 11 hits are agent.py's handling of provider-hosted Responses MCP approval requests, which are auto-denied; none gates Agent Zero's own tools.) (verified)
  - *To reach the next level:* The shell/code-execution path is not gated.
- **D L0:** No approval exists to be on by default. — searched `rg -n -i approv` in `agent.py helpers/tool.py helpers/extension.py` → 11 hits (All 11 hits are agent.py's handling of provider-hosted Responses MCP approval requests, which are auto-denied; none gates Agent Zero's own tools.) (verified)
  - *To reach the next level:* Approval is not available, let alone on by default.
- **B L2:** Code-execution calls trigger automatic workspace snapshots that can be reverted, but external effects (network requests, messages, deletions outside managed workspaces) are irreversible. — [plugins/_time_travel/extensions/python/tool_execute_after/_50_code_execution_snapshot.py:11-25](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_time_travel/extensions/python/tool_execute_after/_50_code_execution_snapshot.py#L11-L25) (verified)
  - *To reach the next level:* No checkpoints for state outside /a0/usr workspaces and no previews or dry-runs for external actions.
- **Cap:** C2-POWERBYPASS — The root shell/code-execution tool, the single most powerful action path, runs with no approval in the default configuration.

### C3 Tool & action scoping — 0.12 (high)

The default toolset gives the model a general-purpose root shell plus Python and Node execution, a browser that opens any URL, file editing without workspace containment, and any configured MCP tools. Arguments are passed through rather than validated against allowlists, and the text editor resolves real paths only for change tracking, not to keep edits inside a workspace. Tools can be blocked per profile or project through the opt-in Tool Access plugin, but the default policy allows everything.

- **S L0:** The code execution tool passes arbitrary shell, Python, or Node code through to a root shell. — [plugins/_code_execution/tools/code_execution_tool.py:563-566](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_code_execution/tools/code_execution_tool.py#L563-L566); [plugins/_code_execution/helpers/shell_local.py:42-46](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_code_execution/helpers/shell_local.py#L42-L46); searched `rg -n 'realpath|commonpath|is_relative_to|startswith'` in `plugins/_text_editor/tools/text_editor.py plugins/_text_editor/helpers/file_ops.py` → 3 hits (realpath is only recorded as file metadata for freshness tracking; no containment check against a workspace root.) (verified)
  - *To reach the next level:* No argument allowlists, path containment, or host allowlists on general tools.
- **C L1:** A handful of bounds exist (the parallel tool caps batches at eight calls), but no shared validation layer covers tools. — [helpers/parallel_tools.py:95-96](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/parallel_tools.py#L95-L96); searched `rg -n 'realpath|commonpath|is_relative_to|startswith'` in `plugins/_text_editor/tools/text_editor.py plugins/_text_editor/helpers/file_ops.py` → 3 hits (realpath is only recorded as file metadata for freshness tracking; no containment check against a workspace root.) (verified)
  - *To reach the next level:* Most built-in tools do not validate arguments against allowlists.
- **D L1:** Every tool, including exec, write, and network, is enabled by default; Tool Access can block tools individually. — [plugins/_tool_access/default_config.yaml:1-3](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_tool_access/default_config.yaml#L1-L3); [helpers/tool_policy.py:175-177](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/tool_policy.py#L175-L177) (verified)
  - *To reach the next level:* No read-only default tool set or selectable groups that exclude exec by default.
- **B L0:** A misused shell can run any command as root inside the container and reach any network host. — [docker/run/fs/etc/supervisor/conf.d/supervisord.conf:61-64](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/docker/run/fs/etc/supervisor/conf.d/supervisord.conf#L61-L64); [plugins/_code_execution/tools/code_execution_tool.py:563-566](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_code_execution/tools/code_execution_tool.py#L563-L566) (verified)
  - *To reach the next level:* Tools are not scoped to a workspace or bounded in quantity.
- **Cap:** none

### C4 Code-execution isolation — 0.47 (high)

All model-driven code runs inside the Agent Zero Docker container, which is the shipped deployment, so the host is separated by a stock container boundary. That container is not hardened: processes run as root with default capabilities and no seccomp or read-only settings, and it is the same container that holds the agent itself, its configuration, and its secrets. The shell inherits the agent's environment, including API keys, and has unrestricted network access. An opt-in A0 CLI connector can extend execution to the user's host machine; its host-side permission prompts live in a separate repository not reviewed here.

- **S L2:** Execution is a local TTY inside a stock Docker container running as root with default capabilities. — [plugins/_code_execution/tools/code_execution_tool.py:563-566](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_code_execution/tools/code_execution_tool.py#L563-L566); [docker/run/fs/etc/supervisor/conf.d/supervisord.conf:61-64](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/docker/run/fs/etc/supervisor/conf.d/supervisord.conf#L61-L64); [README.md:92](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/README.md#L92); searched `rg -n 'cap_drop|cap-drop|security_opt|no-new-privileges|seccomp|read_only: true|--read-only'` in `docker README.md docs/setup` → 0 hits (No container hardening flags in shipped compose, Dockerfiles, README run command, or setup docs.) (verified)
  - *To reach the next level:* No non-root user, dropped capabilities, no-new-privileges, seccomp, or read-only root filesystem.
- **C L3:** In the Docker deployment every model-reachable exec path (shell, Python, Node, browser, MCP stdio servers) runs inside the container; the documented escape hatch is the opt-in A0 CLI host bridge. — [plugins/_code_execution/tools/code_execution_tool.py:563-566](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_code_execution/tools/code_execution_tool.py#L563-L566); [plugins/_a0_connector/tools/code_execution_remote.py:1](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_a0_connector/tools/code_execution_remote.py#L1) (verified)
  - *To reach the next level:* The opt-in host bridge (code_execution_remote) runs on the host, so not every path is contained.
- **D L2:** The container is the default deployment and the model cannot remove it, but host execution via the connector depends on a separate CLI whose per-call approval could not be verified here. — [README.md:92](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/README.md#L92); [plugins/_a0_connector/tools/code_execution_remote.py:44-46](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_a0_connector/tools/code_execution_remote.py#L44-L46) (verified)
  - *To reach the next level:* Escalation to host execution is not shown to require per-call human approval in this repository.
- **B L0:** Inside the sandbox the code runs as root alongside the agent's own process, with API keys in its environment, the secrets and settings files on disk, and full network egress. — [plugins/_code_execution/helpers/shell_local.py:22](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_code_execution/helpers/shell_local.py#L22); [helpers/dotenv.py:13-18](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/dotenv.py#L13-L18); [docker/run/fs/etc/supervisor/conf.d/supervisord.conf:61-64](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/docker/run/fs/etc/supervisor/conf.d/supervisord.conf#L61-L64); [helpers/secrets.py:19](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/secrets.py#L19) (verified)
  - *To reach the next level:* Secrets are in the sandbox environment and the agent's own state is writable from it.
- **Cap:** none

### C5 Untrusted input blast radius — 0.23 (high)

Content from web pages, search results, documents, and MCP tools enters the conversation as ordinary user-role messages, and nothing limits what a hijacked agent can do afterwards: it holds a root shell, network egress, and every configured secret, with no human in the loop. An optional Infection Check plugin asks a second LLM to judge the agent's output before each tool call, but it is detection only, disabled by default, fails open when the check errors, and can be switched off per project. The web UI also accepts instructions from anyone who reaches it when no login is configured.

- **default configuration** (default; raw 0.00, cap C5-WORSTCASE → 0.00)
  - **S L0:** Nothing structurally limits a hijacked agent in the default configuration. — [agent.py:825](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/agent.py#L825); [agent.py:1498-1505](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/agent.py#L1498-L1505) (verified)
    - *To reach the next level:* No capability is withheld or gated once untrusted content has been read.
  - **C L0:** Tool results are added to history with the same standing as user messages; no source is distinguished. — [agent.py:825](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/agent.py#L825) (verified)
    - *To reach the next level:* Untrusted sources are not distinguished from principal input.
  - **D L0:** No control is on by default. — searched `rg --files --hidden -g .toggle-0` in `plugins` → 1 hits (The only shipped disabled-by-default plugin marker is plugins/_infection_check/.toggle-0.) (verified)
    - *To reach the next level:* No untrusted-input control ships enabled.
  - **B L0:** A hijacked agent can read secrets and exfiltrate them over any network channel and take irreversible actions via the root shell, all unattended. — [plugins/_code_execution/helpers/shell_local.py:22](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_code_execution/helpers/shell_local.py#L22); [agent.py:1498-1505](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/agent.py#L1498-L1505); [plugins/_code_execution/tools/code_execution_tool.py:563-566](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_code_execution/tools/code_execution_tool.py#L563-L566) (verified)
    - *To reach the next level:* Exfiltration and irreversible actions are not gated behind human approval.
- **opt-in Infection Check plugin (LLM judge before each tool call)** (alt; raw 0.23, cap G2 → 0.23) ← counted
  - **S L1:** An LLM audit model reviews the agent's reasoning and pending tool call and can terminate; detection only. — [plugins/_infection_check/extensions/python/tool_execute_before/_50_infection_check.py:6-11](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_infection_check/extensions/python/tool_execute_before/_50_infection_check.py#L6-L11) (verified)
    - *To reach the next level:* Not a structural limit: a model judge can be evaded and does not remove egress or state-change capability.
  - **C L2:** The gate runs before every tool execution regardless of which source influenced the agent, but it judges output rather than tracking sources. — [plugins/_infection_check/extensions/python/tool_execute_before/_50_infection_check.py:6-11](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_infection_check/extensions/python/tool_execute_before/_50_infection_check.py#L6-L11) (verified)
    - *To reach the next level:* Does not track provenance of tool results, tool descriptions, or sub-agent messages.
  - **D L0:** Disabled by default, fails open on checker errors, and is per-project configurable so a project file can toggle it. — searched `rg --files --hidden -g .toggle-0` in `plugins` → 1 hits (The only shipped disabled-by-default plugin marker is plugins/_infection_check/.toggle-0.); [plugins/_infection_check/helpers/checker.py:112-122](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_infection_check/helpers/checker.py#L112-L122); [plugins/_infection_check/plugin.yaml:7](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_infection_check/plugin.yaml#L7) (verified)
    - *To reach the next level:* Not on by default; a workspace file or checker error disables it.
  - **B L0:** When the judge misses, the same unattended leak-plus-irreversible-action outcome remains. — [plugins/_code_execution/helpers/shell_local.py:22](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_code_execution/helpers/shell_local.py#L22); [agent.py:1498-1505](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/agent.py#L1498-L1505) (verified)
    - *To reach the next level:* Exfiltration and irreversible actions are not gated behind human approval.
- **Cap:** G2 — The plugin is per-project configurable and the agent's root shell or a cloned project's .a0proj can drop a .toggle-0 to disable it; it also fails open on checker exceptions.

### C6 Memory, context & configuration integrity — 0.10 (high)

Several persistence paths feed straight back into future behaviour. Memory auto-saves fragments from each conversation and recalls them later; a behaviour-adjustment tool lets the model rewrite rules that are inserted at the top of its own system prompt. Projects load tools, Python extensions, prompts, MCP server lists, and AGENTS.md files from the project's .a0proj folder with the highest priority, and cloning a Git repository as a project keeps the repository's own .a0proj, so a repository can ship code that runs in-process after only a generic warning. Memory is separated per project by default, but the agent's root shell can write any of these stores.

- **S L0:** The model can write persistent memories and behaviour rules re-injected as top-priority system prompt, and repo-controlled .a0proj files can add tools, extensions, and MCP servers. — [plugins/_memory/extensions/python/system_prompt/_20_behaviour_prompt.py:16](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_memory/extensions/python/system_prompt/_20_behaviour_prompt.py#L16); [plugins/_memory/tools/behaviour_adjustment.py:46](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_memory/tools/behaviour_adjustment.py#L46); [plugins/_memory/extensions/python/monologue_end/_50_memorize_fragments.py:211](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_memory/extensions/python/monologue_end/_50_memorize_fragments.py#L211); [helpers/subagents.py:379-383](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/subagents.py#L379-L383); [helpers/extension.py:337](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/extension.py#L337) (verified)
  - *To reach the next level:* Memory and behaviour writes are not validated or gated, and project config can add executable tools without a specific trust decision.
- **C L0:** No memory, behaviour-rule, or project-config path is controlled. — [plugins/_memory/default_config.yaml:1-13](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_memory/default_config.yaml#L1-L13); [helpers/mcp_handler.py:853](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/mcp_handler.py#L853); [helpers/projects.py:18-23](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/projects.py#L18-L23) (verified)
  - *To reach the next level:* Not even the main memory store has write controls.
- **D L1:** Memory is isolated per project by default, but the model's root shell can write to any namespace or file. — [plugins/_memory/default_config.yaml:1](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_memory/default_config.yaml#L1); [docker/run/fs/etc/supervisor/conf.d/supervisord.conf:61-64](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/docker/run/fs/etc/supervisor/conf.d/supervisord.conf#L61-L64) (verified)
  - *To reach the next level:* Isolation is not enforced against the model, which can write other projects' stores.
- **B L1:** Poisoned memories, behaviour rules, or project extensions persist across the user's sessions and can trigger tool use, including in-process code execution. — [plugins/_memory/extensions/python/system_prompt/_20_behaviour_prompt.py:16](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_memory/extensions/python/system_prompt/_20_behaviour_prompt.py#L16); [helpers/extension.py:337](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/extension.py#L337) (verified)
  - *To reach the next level:* Poisoned state is neither session-scoped nor gated behind review.
- **Cap:** C6-REPOCONFIG — A cloned project's own .a0proj/tools, extensions/python, and mcp_servers.json are loaded with top priority after only a generic 'Clone Anyway' dialog, and later git pulls change them with no prompt.

### C7 Third-party extensions — 0.00 (high)

Third-party code reaches the agent through several unverified paths. Plugins install from the tip of a Git repository with no pinning or signature check and run an install hook in-process; any plugin folder under /a0/usr/plugins is enabled by default. MCP stdio servers launch as root in the same container. Cloned projects can bring their own MCP servers and Python extensions, and the model's root shell can install packages or drop plugins on its own. An LLM-based plugin scanner exists but is advisory and run on request.

- **S L0:** Plugins install from git HEAD with no pinning or integrity check, and the model can install packages or plugins itself via its shell. — [plugins/_plugin_installer/helpers/install.py:184-199](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_plugin_installer/helpers/install.py#L184-L199); [plugins/_plugin_installer/helpers/install.py:298-299](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_plugin_installer/helpers/install.py#L298-L299); [plugins/_code_execution/helpers/shell_local.py:42-46](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_code_execution/helpers/shell_local.py#L42-L46) (verified)
  - *To reach the next level:* No version pinning or integrity verification for any extension type.
- **C L0:** No extension type (plugins, MCP servers, project extensions, packages) is verified. — [plugins/_plugin_installer/helpers/install.py:184-199](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_plugin_installer/helpers/install.py#L184-L199); [helpers/mcp_handler.py:853](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/mcp_handler.py#L853) (verified)
  - *To reach the next level:* No extension type is verified.
- **D L0:** Plugins are enabled by default once present, and workspace (.a0proj) files can add MCP servers and extensions silently. — [helpers/plugins.py:531-540](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/plugins.py#L531-L540); [helpers/mcp_handler.py:853](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/mcp_handler.py#L853); [helpers/extension.py:337](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/extension.py#L337) (verified)
  - *To reach the next level:* Workspace files and the model can add extensions without explicit install consent.
- **B L0:** Plugins and their install hooks run in-process with all credentials; MCP stdio servers run as root in the same container with filesystem access to every secret file. — [plugins/_plugin_installer/helpers/install.py:298-299](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_plugin_installer/helpers/install.py#L298-L299); [helpers/mcp_handler.py:1569-1573](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/mcp_handler.py#L1569-L1573); [docker/run/fs/etc/supervisor/conf.d/supervisord.conf:61-64](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/docker/run/fs/etc/supervisor/conf.d/supervisord.conf#L61-L64) (verified)
  - *To reach the next level:* Extensions are not separated from the agent's process, user, or credentials.
- **Cap:** C7-RCELOAD — By default a cloned project's .a0proj/mcp_servers.json launches commands and its extensions/python files execute in-process, and the model can pip-install or git-clone plugins that auto-enable, all without per-extension consent.

### C8 Secrets & sensitive-data protection — 0.35 (high)

Agent Zero has a real secret-masking layer: stored secrets are shown to the model only as §§secret() placeholders that are substituted at tool execution, and secret values are masked in tool output, chat history, utility-model calls, streamed text, error messages, and logs. Secrets and API keys are still stored as plaintext files under /a0/usr, the API keys are loaded into the process environment and inherited by every shell the agent spawns, and masking is exact-string replacement that an encoded print bypasses. An update check posts the version and an anonymized instance ID to the vendor by default.

- **S L2:** Placeholder substitution and value masking on main paths, with plaintext secrets files on disk. — [extensions/python/tool_execute_before/_10_unmask_secrets.py:21](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/extensions/python/tool_execute_before/_10_unmask_secrets.py#L21); [extensions/python/tool_execute_after/_10_mask_secrets.py:15](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/extensions/python/tool_execute_after/_10_mask_secrets.py#L15); [extensions/python/hist_add_before/_10_mask_content.py:28](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/extensions/python/hist_add_before/_10_mask_content.py#L28); [extensions/python/util_model_call_before/_10_mask_secrets.py:18-20](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/extensions/python/util_model_call_before/_10_mask_secrets.py#L18-L20); [helpers/secrets.py:19](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/secrets.py#L19) (verified)
  - *To reach the next level:* No OS keychain or encryption at rest for usr/.env and usr/secrets.env.
- **C L2:** Masking covers logs, history/transcripts, model-bound messages, tool output, and errors, but not subprocess environments. — [helpers/log.py:434](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/log.py#L434); [extensions/python/hist_add_before/_10_mask_content.py:28](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/extensions/python/hist_add_before/_10_mask_content.py#L28); [extensions/python/util_model_call_before/_10_mask_secrets.py:18-20](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/extensions/python/util_model_call_before/_10_mask_secrets.py#L18-L20); [plugins/_code_execution/helpers/shell_local.py:22](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_code_execution/helpers/shell_local.py#L22) (verified)
  - *To reach the next level:* Subprocess environments receive the full os.environ including API keys.
- **D L1:** Content-free update-check telemetry is on by default. — [helpers/update_check.py:12-17](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/update_check.py#L12-L17); [helpers/settings.py:627](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/settings.py#L627) (verified)
  - *To reach the next level:* Telemetry is not opt-in.
- **B L0:** Long-lived provider API keys are in the environment of every spawned shell, readable by model-run code. — [helpers/dotenv.py:13-18](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/dotenv.py#L13-L18); [plugins/_code_execution/helpers/shell_local.py:22](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_code_execution/helpers/shell_local.py#L22); [models.py:275-279](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/models.py#L275-L279) (verified)
  - *To reach the next level:* Keys reachable by subprocesses are long-lived and broadly scoped.
- **Cap:** none

### C9 Audit & traceability — 0.40 (high)

Every tool call, including MCP tools and sub-agent calls in the same chat, is logged as a structured item with its arguments and result, and the chat is saved to disk at the end of each loop iteration. The record names which agent number acted but not a human principal, and there are no approvals to record. The logs are saved under /a0/usr/chats, which the agent's root shell can edit or delete, and there is no tamper-evident or off-host export.

- **S L2:** Structured tool log items with arguments and results, persisted as a local chat transcript. — [helpers/tool.py:61-68](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/tool.py#L61-L68); [helpers/mcp_handler.py:176-177](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/mcp_handler.py#L176-L177) (verified)
  - *To reach the next level:* No principal or approver attribution and no correlation IDs across sub-agents.
- **C L2:** Built-in, plugin, and MCP tools all log through the Tool base class. — [helpers/tool.py:61-68](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/tool.py#L61-L68); [helpers/mcp_handler.py:176-177](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/mcp_handler.py#L176-L177) (verified)
  - *To reach the next level:* Config changes, plugin installs, and policy denials are not recorded as audit events.
- **D L1:** Logging is on by default but stored in usr/chats, writable by the agent's root shell. — [helpers/persist_chat.py:17](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/helpers/persist_chat.py#L17); [extensions/python/message_loop_end/_90_save_chat.py:11-15](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/extensions/python/message_loop_end/_90_save_chat.py#L11-L15); [docker/run/fs/etc/supervisor/conf.d/supervisord.conf:61-64](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/docker/run/fs/etc/supervisor/conf.d/supervisord.conf#L61-L64) (verified)
  - *To reach the next level:* Records live where the agent's own tools can alter them.
- **B L1:** Chats are saved at the end of each message loop; there is no fail-closed or per-action durability guarantee. — [extensions/python/message_loop_end/_90_save_chat.py:11-15](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/extensions/python/message_loop_end/_90_save_chat.py#L11-L15) (verified)
  - *To reach the next level:* Records are not durably flushed per action with surfaced errors.
- **Cap:** none

### C10 Limits & kill switch — 0.20 (high)

There is no limit on agent loop iterations, wall-clock time, tokens, or spend, and delegation to subordinate agents has no depth or budget accounting. Code execution stops waiting after 240 seconds by default, but the process can keep running. Stopping a chat cancels its task, yet shell processes and model-created scheduled tasks continue. Model request rate limits exist but are off by default.

- **S L1:** Only a working cooperative stop and per-command wait timeouts that do not kill the process exist; no step, time, or cost cap. — searched `rg -n -i 'max_iterations|max_steps|max_turns|iteration_limit|max_loops'` in `agent.py helpers/settings.py initialize.py` → 0 hits (No iteration/step cap for the agent loop.); [plugins/_code_execution/prompts/fw.code.max_time.md:1](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_code_execution/prompts/fw.code.max_time.md#L1); [agent.py:238-240](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/agent.py#L238-L240); [models.py:147](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/models.py#L147) (verified)
  - *To reach the next level:* No iteration cap plus wall-clock or token/cost cap enforced in code.
- **C L1:** The stop applies to the chat's top-level task; spawned shells and scheduled tasks are outside it. — [agent.py:238-240](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/agent.py#L238-L240); [plugins/_code_execution/prompts/fw.code.max_time.md:1](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_code_execution/prompts/fw.code.max_time.md#L1); searched `rg -n -i 'depth|budget'` in `tools/call_subordinate.py` → 0 hits (Subordinate delegation has no depth or budget accounting.) (verified)
  - *To reach the next level:* Tool timeouts don't terminate work, and sub-agents/background tasks share no budget.
- **D L1:** The only defaults are exec wait-timeouts and an off-by-default rate limiter, stored in config files the agent can edit. — [plugins/_code_execution/default_config.yaml:16](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_code_execution/default_config.yaml#L16); [models.py:147](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/models.py#L147) (verified)
  - *To reach the next level:* No sensible default budget the model cannot raise.
- **B L0:** A runaway agent can loop, spend, and schedule recurring tasks indefinitely; stopping leaves processes running. — [tools/scheduler.py:304](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/tools/scheduler.py#L304); [plugins/_code_execution/prompts/fw.code.max_time.md:1](https://github.com/agent0ai/agent-zero/blob/e3051fb584b1a36be2b0a0c90606f1c2c2d356ec/plugins/_code_execution/prompts/fw.code.max_time.md#L1); searched `rg -n -i 'max_iterations|max_steps|max_turns|iteration_limit|max_loops'` in `agent.py helpers/settings.py initialize.py` → 0 hits (No iteration/step cap for the agent loop.) (verified)
  - *To reach the next level:* No ceiling on loops or spend, and stop doesn't end spawned or scheduled work.
- **Cap:** none

## Rule-of-Two check
[A] untrusted input: Browser, search, document and MCP results enter history as user-role messages (agent.py:825) · [B] sensitive data/systems: API keys inherited by every shell (helpers/dotenv.py:14, plugins/_code_execution/helpers/shell_local.py:22) and all secrets via placeholders · [C] state change / egress: Root shell with full network, no approval (agent.py:1505) · Same default session? Yes

## Highest-impact improvements
1. Require login (or bind to localhost) by default and ship the infection check enabled, failing closed. — C5 D L0→L2, +0.100 before caps (Playbook 1)
2. Add a per-call human approval gate for code execution, MCP, and other mutating tools, with exact arguments shown. — C2 S L0→L3, +0.225 before caps (Playbook 5)
3. Run model code as a non-root user in a separate, hardened container without the agent's environment or secrets files. — C4 B L0→L2, +0.100 before caps (Playbook 3)
4. Scrub API keys from the environment passed to shells and MCP servers; keep them only in the agent process. — C8 C L2→L3, +0.075 before caps (Playbook 4)
5. Add default iteration, wall-clock, and token caps that subordinate agents share, and kill the process group on stop. — C10 S L1→L3, +0.150 before caps (Playbook 3)

## Re-audit log
- No changes.

## Limitations
- Static source review of the pinned commit only; nothing was executed, installed, or probed.
- The A0 CLI connector (host bridge) and A0 Launcher/installer live in separate repositories and were not reviewed; host-side permission prompts are therefore not credited.
- The published agent0ai/agent-zero and agent-zero-base images were not inspected; container settings are judged from Dockerfiles, compose file, and README run command in this repository.
- Bundled messaging integrations (email, Telegram, WhatsApp) are off until configured and were only skimmed; security-review/LEDGER.md records two recently fixed vulnerabilities in them.
- No reviewer-steering text aimed at AI auditors was found in README, AGENTS.md files, or security-review/.
