# Defense-in-Depth Score: oh-my-openagent (OmO)

**Repo:** https://github.com/code-yeongyu/oh-my-openagent · **Commit:** `a8019016f47a9d814ebcc24bd921a561f065ee80` (v5.1.19) · **Reviewed:** 2026-10-05
**What it is:** Multi-agent orchestration harness/plugin for OpenCode
**Category:** Coding
**Scored configuration:** OpenCode with the oh-my-opencode plugin (packages/omo-opencode) installed, no plugin config, default Sisyphus agent, opened in a repository.
**Agent surface (default):** code execution yes · filesystem write yes · network egress yes · external credentials yes · persistent memory no · untrusted input yes · third party extensions yes · sub agents yes · external communication yes

## Score: 1.8 / 10.0 (Minimal)

| # | Criterion | S | C | D | B | Raw | Cap | Score | Confidence |
|---|---|---|---|---|---|---|---|---|---|
| C1 | Identity & least privilege | L0 | L0 | L0 | L0 | 0.00 | — | **0.00** | High |
| C2 | Approval gates | L2 | L0 | L0 | L1 | 0.20 | C2-POWERBYPASS | **0.20** | Medium |
| C3 | Tool & action scoping | L1 | L1 | L1 | L0 | 0.20 | — | **0.20** | High |
| C4 | Code-execution isolation | L0 | L0 | L0 | L0 | 0.00 | — | **0.00** | High |
| C5 | Untrusted input blast radius | L1 | L1 | L2 | L0 | 0.25 | C5-WORSTCASE | **0.25** | Medium |
| C6 | Memory, context & configuration integrity | L0 | L0 | L1 | L0 | 0.05 | C6-REPOCONFIG | **0.05** | High |
| C7 | Third-party extensions | L1 | L0 | L0 | L1 | 0.12 | — | **0.12** | High |
| C8 | Secrets & sensitive-data protection | L1 | L1 | L1 | L0 | 0.20 | — | **0.20** | High |
| C9 | Audit & traceability | L2 | L2 | L2 | L1 | 0.45 | — | **0.45** | Low |
| C10 | Limits & kill switch | L2 | L1 | L2 | L0 | 0.33 | — | **0.33** | High |


OmO turns OpenCode into a multi-agent orchestrator, and in doing so it widens the host's defaults rather than narrowing them: web fetches and access outside the project are set to allowed, a second shell path through tmux is added, and nothing asks before shell commands run on the host with your full credentials. Opening it in a cloned repository also silently runs that repository's Claude Code hook commands and loads its MCP servers, with no trust prompt. Sub-agents are well bounded, but the main session has no step or spend limit.

## Critical gaps
- Hook commands and the interactive_bash tool run with the user's full ambient environment and credentials. (ASI03, T3; C1) — [packages/utils/src/command-executor/execute-hook-command.ts:94-107](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/utils/src/command-executor/execute-hook-command.ts#L94-L107); [packages/omo-opencode/src/tools/interactive-bash/tools.ts:174-181](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/tools/interactive-bash/tools.ts#L174-L181)
- Shell and interactive_bash run without human approval by default, and the plugin sets web fetches and out-of-project access to allowed. (ASI02, ASI09; C2) — [packages/omo-opencode/src/plugin-handlers/tool-config-handler.ts:156-161](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/plugin-handlers/tool-config-handler.ts#L156-L161); [packages/omo-opencode/src/tools/interactive-bash/tools.ts:174-181](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/tools/interactive-bash/tools.ts#L174-L181)
- No sandbox: hook commands, tmux commands and MCP servers run directly on the host as the user with the full environment. (ASI05, T11; C4) — [packages/utils/src/command-executor/execute-hook-command.ts:102-107](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/utils/src/command-executor/execute-hook-command.ts#L102-L107); [packages/utils/src/command-executor/execute-hook-command.ts:94-107](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/utils/src/command-executor/execute-hook-command.ts#L94-L107)
- A hijacked session can exfiltrate data via webfetch or the shell and take irreversible actions with no human involved. (ASI01, LLM01; C5) — [packages/omo-opencode/src/plugin-handlers/tool-config-handler.ts:156-161](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/plugin-handlers/tool-config-handler.ts#L156-L161); [packages/omo-opencode/src/mcp/websearch.ts:33-38](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/mcp/websearch.ts#L33-L38)
- A repository's .claude/settings.json hooks and .mcp.json servers load and run without any trust decision. (ASI06, ASI04; C6) — [packages/omo-opencode/src/hooks/claude-code-hooks/config.ts:73-79](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/hooks/claude-code-hooks/config.ts#L73-L79); [packages/claude-code-compat-core/src/features/claude-code-mcp-loader/loader.ts:52-57](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/claude-code-compat-core/src/features/claude-code-mcp-loader/loader.ts#L52-L57)

## Criterion details

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

The plugin runs inside OpenCode with the developer's own operating-system authority and adds no credential scoping. Commands from Claude Code-style hooks are launched through a shell with the entire process environment, and the tmux-based interactive_bash tool inherits it too, so API keys, cloud credentials and git/gh logins are all reachable. Only MCP servers that skills start, and hooks shipped by Claude Code plugins, get a trimmed environment. A hijacked session can act as the user across every service the machine is logged into.

- **S L0:** Ambient authority: hook commands spawn with the whole process environment and no scoped identity exists. — [packages/utils/src/command-executor/execute-hook-command.ts:94-107](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/utils/src/command-executor/execute-hook-command.ts#L94-L107) (verified)
  - *To reach the next level:* Give spawned commands a scrubbed environment and narrowed, task-specific credentials.
- **C L0:** No authorization layer governs credentials; only skill-launched MCP servers get a denylist-scrubbed environment, while hooks and interactive_bash inherit everything. — [packages/utils/src/command-executor/execute-hook-command.ts:94-107](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/utils/src/command-executor/execute-hook-command.ts#L94-L107); [packages/omo-opencode/src/tools/interactive-bash/tools.ts:174-181](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/tools/interactive-bash/tools.ts#L174-L181); [packages/mcp-client-core/src/skill-mcp-manager/env-cleaner.ts:50-56](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/mcp-client-core/src/skill-mcp-manager/env-cleaner.ts#L50-L56) (verified)
  - *To reach the next level:* Route every tool and extension through one credential layer instead of passing the ambient environment.
- **D L0:** The default install runs with the user's full privileges and the plugin defaults web fetches and out-of-project file access to allowed. — [packages/omo-opencode/src/plugin-handlers/tool-config-handler.ts:156-161](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/plugin-handlers/tool-config-handler.ts#L156-L161) (verified)
  - *To reach the next level:* Ship a near-minimal default with no ambient secrets in subprocesses and write tools requiring elevation.
- **B L0:** Through hooks and the shell a hijacked session reaches every credential on the machine, i.e. the user's whole account across services. — [packages/utils/src/command-executor/execute-hook-command.ts:94-107](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/utils/src/command-executor/execute-hook-command.ts#L94-L107) (verified)
  - *To reach the next level:* Keep ambient credentials out of subprocesses so a hijack cannot reach them.
- **Cap:** none

### C2 Approval gates — 0.20 (medium)

OmO relies on OpenCode's permission rules for approvals and does not add a gate of its own. The plugin makes its Sisyphus orchestrator the default agent without any ask rules for shell or edits, adds a second shell path through tmux (interactive_bash), and sets web fetches and access to directories outside the project to allowed for every agent. Under OpenCode's default allow-everything ruleset this means shell commands, file writes, tmux keystrokes and web requests run with no human approval. The task-list continuation hook even tells the model to proceed without asking for permission.

- **S L2:** When a user configures ask rules, OpenCode's host prompt applies per call; the plugin itself adds no approval UI or argument policy. — [packages/omo-opencode/src/agents/sisyphus-agent-config.ts:9-15](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/agents/sisyphus-agent-config.ts#L9-L15) (inferred)
  - *To reach the next level:* Show the exact call for every tool kind and add argument-level allow/deny/escalate policy owned by the plugin or enforced on its tools.
- **C L0:** The most powerful paths (shell and the plugin's own interactive_bash) are not gated in the default configuration. — [packages/omo-opencode/src/agents/sisyphus-agent-config.ts:9-15](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/agents/sisyphus-agent-config.ts#L9-L15); [packages/omo-opencode/src/tools/interactive-bash/tools.ts:174-181](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/tools/interactive-bash/tools.ts#L174-L181) (verified)
  - *To reach the next level:* Gate shell and interactive_bash by default so no exec path skips approval.
- **D L0:** Approval is effectively opt-in: the plugin sets webfetch and external_directory to allow and adds no ask rules for exec or edit. — [packages/omo-opencode/src/plugin-handlers/tool-config-handler.ts:156-161](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/plugin-handlers/tool-config-handler.ts#L156-L161); [packages/omo-opencode/src/plugin-handlers/tool-config-handler.ts:156-161](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/plugin-handlers/tool-config-handler.ts#L156-L161); [packages/omo-opencode/src/hooks/todo-continuation-enforcer/constants.ts:7-11](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/hooks/todo-continuation-enforcer/constants.ts#L7-L11) (verified)
  - *To reach the next level:* Default consequential tools to ask and stop forcing webfetch and external_directory to allow.
- **B L1:** Shell and tmux actions (pushes, deletes, network calls) are irreversible and the plugin adds no checkpoint or preview for them. — [packages/omo-opencode/src/tools/interactive-bash/tools.ts:174-181](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/tools/interactive-bash/tools.ts#L174-L181) (verified)
  - *To reach the next level:* Provide checkpoints for file changes and previews or dry-runs for external actions.
- **Cap:** C2-POWERBYPASS — The shell and interactive_bash paths run without approval in the default configuration.

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

The default tool set includes an unrestricted shell, a tmux tool that can type arbitrary commands into a terminal, file editing, and web fetches to any URL. The tmux tool only blocks a few output-capturing subcommands, which is a usability filter rather than a boundary. The plugin's look_at tool reads any absolute path, the webfetch helper follows redirects without blocking internal or cloud-metadata addresses, and the plugin switches off OpenCode's prompt for paths outside the project. Individual tools can be turned off in config, but everything is on by default.

- **S L1:** Filtering only: interactive_bash blocks a short list of tmux subcommands; webfetch and look_at take arbitrary URLs and absolute paths. — [packages/omo-opencode/src/tools/interactive-bash/constants.ts:3-12](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/tools/interactive-bash/constants.ts#L3-L12); [packages/omo-opencode/src/tools/look-at/tools.ts:17-18](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/tools/look-at/tools.ts#L17-L18); searched `rg -n -i "169\.254|isPrivate|private.?ip|localhost"` in `packages/omo-opencode/src/hooks/webfetch-redirect-guard` → 0 hits (the webfetch hook resolves redirects but never blocks internal or metadata addresses) (verified)
  - *To reach the next level:* Validate arguments against allowlists in code: path containment, URL host allowlists with internal-address blocking, narrow tools.
- **C L1:** Only interactive_bash applies any argument filtering; look_at, webfetch, MCP and hook paths do not. — [packages/omo-opencode/src/tools/interactive-bash/constants.ts:3-12](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/tools/interactive-bash/constants.ts#L3-L12); [packages/omo-opencode/src/tools/look-at/tools.ts:17-18](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/tools/look-at/tools.ts#L17-L18) (verified)
  - *To reach the next level:* Validate inputs on most built-in tools, including web and file access.
- **D L1:** Shell, tmux, edit and webfetch are all on by default, and the plugin widens file access outside the project; tools can be listed in disabled_tools. — [packages/omo-opencode/src/config/schema/oh-my-opencode-config.ts:42-48](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/config/schema/oh-my-opencode-config.ts#L42-L48); [packages/omo-opencode/src/plugin-handlers/tool-config-handler.ts:156-161](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/plugin-handlers/tool-config-handler.ts#L156-L161) (verified)
  - *To reach the next level:* Ship a read-only default tool set with write and exec requiring explicit enabling.
- **B L0:** A misused shell or tmux tool reaches the whole machine with the user's privileges. — [packages/omo-opencode/src/tools/interactive-bash/tools.ts:174-181](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/tools/interactive-bash/tools.ts#L174-L181) (verified)
  - *To reach the next level:* Scope general tools to the workspace and bound quantities.
- **Cap:** none

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

Nothing is sandboxed. The plugin's own execution paths (Claude Code-style hook commands run through a login shell, interactive_bash via tmux, local MCP servers and the LSP daemon) start as ordinary processes under the user's account, and OpenCode's shell does the same. No container, OS sandbox profile or restricted user is used anywhere in the plugin. Any command the model or a repository hook chooses runs on the host with full file, network and credential access.

- **S L0:** Commands run as same-user host subprocesses; no isolation primitive exists in the plugin. — [packages/utils/src/command-executor/execute-hook-command.ts:102-107](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/utils/src/command-executor/execute-hook-command.ts#L102-L107); searched `rg -n -i "seccomp|landlock|bwrap|bubblewrap|sandbox-exec|firejail|gvisor"` in `packages/omo-opencode/src packages/utils/src` → 0 hits (no OS sandbox, container or isolation primitive in the plugin or its exec helpers) (verified)
  - *To reach the next level:* Provide an OS-level sandbox (Seatbelt, Landlock+seccomp or a hardened container) for command execution.
- **C L0:** No execution path is sandboxed (hooks, interactive_bash, MCP stdio servers). — [packages/utils/src/command-executor/execute-hook-command.ts:102-107](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/utils/src/command-executor/execute-hook-command.ts#L102-L107); [packages/omo-opencode/src/tools/interactive-bash/tools.ts:174-181](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/tools/interactive-bash/tools.ts#L174-L181) (verified)
  - *To reach the next level:* Route at least the main exec paths through an isolation boundary.
- **D L0:** No sandbox exists to enable. — searched `rg -n -i "seccomp|landlock|bwrap|bubblewrap|sandbox-exec|firejail|gvisor"` in `packages/omo-opencode/src packages/utils/src` → 0 hits (no OS sandbox, container or isolation primitive in the plugin or its exec helpers) (verified)
  - *To reach the next level:* Ship a sandbox on by default.
- **B L0:** Host-equivalent: home directory, credentials in the environment and unrestricted network are reachable. — [packages/utils/src/command-executor/execute-hook-command.ts:94-107](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/utils/src/command-executor/execute-hook-command.ts#L94-L107) (verified)
  - *To reach the next level:* Confine execution to the workspace with no secrets in the environment and egress controls.
- **Cap:** none

### C5 Untrusted input blast radius — 0.25 (medium)

Web pages, search results from the built-in Exa, Context7 and grep.app MCP servers, repository files, AGENTS.md/README/rules files injected by hooks, and tool results all enter the model's context with the same standing as the user. The only marking is a text envelope around monitor output and goal objectives, which nothing enforces. Because the shell and web fetches run without approval, a successful prompt injection can read secrets and send them out and also take irreversible actions, with no human in the loop.

- **S L1:** Detection-style delimiters only: monitor output and goal objectives are wrapped in untrusted labels that no code acts on. — [packages/omo-opencode/src/features/monitor/envelope.ts:13](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/features/monitor/envelope.ts#L13); [packages/omo-opencode/src/hooks/goal/prompt.ts:9-11](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/hooks/goal/prompt.ts#L9-L11) (verified)
  - *To reach the next level:* Disable or gate egress and state-changing tools once untrusted content has been read.
- **C L1:** Only monitor output and goal text are labelled; web, MCP, file and injected instruction content are not. — [packages/omo-opencode/src/features/monitor/envelope.ts:13](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/features/monitor/envelope.ts#L13); [packages/omo-opencode/src/mcp/websearch.ts:33-38](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/mcp/websearch.ts#L33-L38) (verified)
  - *To reach the next level:* Distinguish every untrusted source, including tool and MCP results, from principal input.
- **D L2:** The labels are hard-coded and always on, but they carry no enforcement. — [packages/omo-opencode/src/hooks/goal/prompt.ts:9-11](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/hooks/goal/prompt.ts#L9-L11) (verified)
  - *To reach the next level:* Make the restriction explicit, warned when disabled, and immune to content.
- **B L0:** A hijacked session can exfiltrate through webfetch (set to allow by the plugin) or the shell and take irreversible shell actions unattended; the shell's allow default comes from the OpenCode host. — [packages/omo-opencode/src/plugin-handlers/tool-config-handler.ts:156-161](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/plugin-handlers/tool-config-handler.ts#L156-L161); [packages/omo-opencode/src/mcp/index.ts:39-45](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/mcp/index.ts#L39-L45) (inferred)
  - *To reach the next level:* Require approval for egress and irreversible actions after untrusted input is read.
- **Cap:** C5-WORSTCASE — In the default configuration a hijacked session can both leak data and take irreversible actions with no human involved.

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

Opening OpenCode with this plugin inside a repository silently loads that repository's Claude Code compatibility files: hooks in .claude/settings.json and .claude/settings.local.json run as shell commands on tool use, session start and other events, and servers in .mcp.json are added to the MCP configuration. A project .omo/omo.jsonc layers over the user's config, with only the MCP environment allowlist and Playwright arguments protected from project override. AGENTS.md, README and rule files are injected into context automatically. There is no workspace-trust prompt, and because edits are allowed by default a hijacked session can also write these files and plant behaviour that fires in later sessions and for anyone who clones the repo.

- **S L0:** Repo-controlled files add hook commands and MCP servers with no prompt. — [packages/omo-opencode/src/hooks/claude-code-hooks/config.ts:73-79](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/hooks/claude-code-hooks/config.ts#L73-L79); [packages/claude-code-compat-core/src/features/claude-code-mcp-loader/loader.ts:52-57](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/claude-code-compat-core/src/features/claude-code-mcp-loader/loader.ts#L52-L57); searched `rg -n -i "workspace.?trust|trustedWorkspace|isTrusted"` in `packages/omo-opencode/src packages/claude-code-compat-core/src packages/omo-config-core/src` → 0 hits (no workspace-trust decision gates project config, hooks or MCP loading) (verified)
  - *To reach the next level:* Require an explicit workspace-trust decision before project hooks, MCP servers or config load.
- **C L0:** No auto-loaded path is controlled: settings hooks, .mcp.json, .omo/omo.jsonc and injected instruction files all load unconditionally. — [packages/omo-opencode/src/plugin/hooks/create-transform-hooks.ts:41-48](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/plugin/hooks/create-transform-hooks.ts#L41-L48); [packages/omo-opencode/src/plugin-handlers/mcp-config-handler.ts:38-40](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/plugin-handlers/mcp-config-handler.ts#L38-L40); [packages/omo-config-core/src/loader/paths.ts:108-112](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-config-core/src/loader/paths.ts#L108-L112); [packages/omo-opencode/src/plugin/tool-execute-before.ts:100-102](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/plugin/tool-execute-before.ts#L100-L102) (verified)
  - *To reach the next level:* Put every auto-loaded file and setting behind the same trust decision.
- **D L1:** A few security-relevant keys are kept user-only, but project config otherwise overrides user config and the model can write the auto-loaded files. — [packages/omo-opencode/src/config/validate.ts:89-91](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/config/validate.ts#L89-L91) (verified)
  - *To reach the next level:* Keep all security settings in user scope and stop the model writing them without approval.
- **B L0:** Poisoned hooks or MCP entries persist across sessions and for every user who opens the repo with the plugin, and execute commands. — [packages/omo-opencode/src/hooks/claude-code-hooks/config.ts:73-79](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/hooks/claude-code-hooks/config.ts#L73-L79); [packages/utils/src/command-executor/execute-hook-command.ts:102-107](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/utils/src/command-executor/execute-hook-command.ts#L102-L107) (verified)
  - *To reach the next level:* Make persisted config changes require human review and be easy to roll back.
- **Cap:** C6-REPOCONFIG — Workspace files (.claude/settings.json hooks, .mcp.json) add command hooks and MCP servers without a user trust decision.

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

Extensions are not verified. MCP servers come from user and project .mcp.json files and from skills (including skills in the repository's .claude/.agents/.opencode folders), launched with whatever command they name and no pinning or integrity check. The plugin also updates itself automatically: unless auto_update is turned off or the version is pinned, it installs the newest release from npm in the background. Skill-launched MCP servers and plugin hooks get an environment with common secret names removed, but repository hooks and project MCP entries get no such treatment.

- **S L1:** User- or repo-chosen sources run unpinned, and the plugin auto-installs its latest release from the registry. — [packages/omo-opencode/src/plugin/hooks/create-session-hooks.ts:136-141](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/plugin/hooks/create-session-hooks.ts#L136-L141); [packages/omo-opencode/src/hooks/auto-update-checker/hook/background-update-check.ts:281](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/hooks/auto-update-checker/hook/background-update-check.ts#L281); [packages/claude-code-compat-core/src/features/claude-code-mcp-loader/loader.ts:52-57](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/claude-code-compat-core/src/features/claude-code-mcp-loader/loader.ts#L52-L57) (verified)
  - *To reach the next level:* Pin extension versions and verify integrity before loading.
- **C L0:** No extension type (project MCP servers, skill MCPs, Claude Code plugins, self-updates) is verified. — [packages/omo-opencode/src/plugin-handlers/mcp-config-handler.ts:38-40](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/plugin-handlers/mcp-config-handler.ts#L38-L40) (verified)
  - *To reach the next level:* Verify at least one extension type.
- **D L0:** Workspace files can add MCP servers and hooks silently, and auto-update is on by default. — [packages/omo-opencode/src/plugin-handlers/mcp-config-handler.ts:38-40](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/plugin-handlers/mcp-config-handler.ts#L38-L40); [packages/omo-opencode/src/plugin/hooks/create-session-hooks.ts:136-141](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/plugin/hooks/create-session-hooks.ts#L136-L141) (verified)
  - *To reach the next level:* Enable nothing third-party by default and show the exact package or command before first run.
- **B L1:** Extensions run as separate same-user processes; skill MCPs get a denylist-trimmed environment but other paths keep the full environment. — [packages/mcp-client-core/src/skill-mcp-manager/env-cleaner.ts:28-35](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/mcp-client-core/src/skill-mcp-manager/env-cleaner.ts#L28-L35); [packages/utils/src/command-executor/execute-hook-command.ts:94-107](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/utils/src/command-executor/execute-hook-command.ts#L94-L107) (verified)
  - *To reach the next level:* Give every extension a scrubbed environment containing only its own configuration.
- **Cap:** none

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

Secrets come from environment variables, and MCP OAuth tokens are stored in plaintext files with owner-only permissions. The plugin does try to limit exposure in a few places: environment-variable expansion in MCP configs is restricted to an allowlist, and MCP servers started by skills have common secret variables stripped. But hook commands receive the full environment, tool output reaches the model unfiltered, and the plugin's debug log is written unmasked to a shared temp directory. Anonymous usage pings to PostHog are on by default and can be switched off with an environment variable.

- **S L1:** Secrets come from env vars; masking exists only as an MCP env-expansion allowlist and a denylist for skill MCP environments. — [packages/claude-code-compat-core/src/features/claude-code-mcp-loader/env-expander.ts:12-17](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/claude-code-compat-core/src/features/claude-code-mcp-loader/env-expander.ts#L12-L17); [packages/mcp-client-core/src/skill-mcp-manager/env-cleaner.ts:28-35](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/mcp-client-core/src/skill-mcp-manager/env-cleaner.ts#L28-L35); [packages/mcp-client-core/src/mcp-oauth/storage.ts:145-146](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/mcp-client-core/src/mcp-oauth/storage.ts#L145-L146) (verified)
  - *To reach the next level:* Add masking before logs and model-bound messages and store credentials in the OS keychain.
- **C L1:** Only MCP-related subprocess paths are protected; logs, hook subprocesses and model-bound tool output are not. — [packages/utils/src/logging/logger.ts:94-97](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/utils/src/logging/logger.ts#L94-L97); [packages/utils/src/command-executor/execute-hook-command.ts:94-107](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/utils/src/command-executor/execute-hook-command.ts#L94-L107) (verified)
  - *To reach the next level:* Protect logs, transcripts and all subprocess environments as well.
- **D L1:** Telemetry is on by default (content-free daily-active pings, opt-out by env var) and the log writes unmasked JSON payloads to the temp directory. — [packages/omo-opencode/src/shared/posthog.ts:100-110](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/shared/posthog.ts#L100-L110); [packages/omo-opencode/src/shared/posthog.ts:209](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/shared/posthog.ts#L209); [packages/utils/src/logging/logger.ts:33-35](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/utils/src/logging/logger.ts#L33-L35) (verified)
  - *To reach the next level:* Make telemetry opt-in and keep masking always on.
- **B L0:** Long-lived provider keys and ambient credentials are reachable by the model through hook and shell subprocesses. — [packages/utils/src/command-executor/execute-hook-command.ts:94-107](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/utils/src/command-executor/execute-hook-command.ts#L94-L107) (verified)
  - *To reach the next level:* Keep long-lived keys out of subprocess environments.
- **Cap:** none

### C9 Audit & traceability — 0.45 (low)

The plugin keeps no audit record of its own beyond a free-text debug log in the system temp directory, which drops entries silently if writing fails. Its sub-agents run as child sessions of the OpenCode host, so the host's session store should capture their tool calls along with the main session's, but that store is outside this repository and was not verified here. Approval decisions and hook verdicts are not recorded in a structured way, and nothing protects the records from a shell the model controls.

- **S L2:** Per-tool-call records come from the OpenCode host's session store; the plugin adds only an unstructured log. — [packages/omo-opencode/src/features/background-agent/spawner.ts:58-60](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/features/background-agent/spawner.ts#L58-L60); [packages/utils/src/logging/logger.ts:94-97](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/utils/src/logging/logger.ts#L94-L97) (inferred)
  - *To reach the next level:* Add actor attribution (approver, requesting principal) and correlation across sub-agents in a plugin-owned record.
- **C L2:** Sub-agents are host child sessions so their calls are captured, but approvals, denials and hook verdicts are not persisted. — [packages/omo-opencode/src/features/background-agent/spawner.ts:58-60](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/features/background-agent/spawner.ts#L58-L60) (inferred)
  - *To reach the next level:* Persist approval, denial and hook decisions alongside tool calls.
- **D L2:** Records are on by default and outside the workspace, but the shell (allowed by default) can alter them and the plugin log sits in a shared temp directory. — [packages/utils/src/logging/logger.ts:33-35](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/utils/src/logging/logger.ts#L33-L35) (inferred)
  - *To reach the next level:* Write the record through a component the model cannot control.
- **B L1:** The plugin log is buffered and write failures are swallowed silently. — [packages/utils/src/logging/logger.ts:78-83](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/utils/src/logging/logger.ts#L78-L83) (verified)
  - *To reach the next level:* Flush records per action and surface logging errors.
- **Cap:** none

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

Background and delegated sub-agents have real limits: at most three levels deep, 24 live descendants per root session, five concurrent tasks per model by default, a 4,000-tool-call cap per task, a breaker for repeated identical calls, and stale-task timeouts; hook commands and tmux calls time out. The main session has no step, time or spend limit, and the task-list continuation hook re-prompts the agent to keep going when it stops with open task-list items (it gives up after three rounds without progress). /stop-continuation cancels running descendant tasks.

- **S L2:** Sub-agent tool-call caps, a repeated-call breaker and per-command timeouts are enforced in code; there is no token or cost cap. — [packages/omo-opencode/src/features/background-agent/constants.ts:7-10](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/features/background-agent/constants.ts#L7-L10); [packages/utils/src/command-executor/execute-hook-command.ts:11](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/utils/src/command-executor/execute-hook-command.ts#L11); searched `rg -n -i "max_?cost|cost_?limit|spend_?limit|maxSteps|max_steps"` in `packages/omo-opencode/src` → 0 hits (no step, cost or spend cap for the main session) (verified)
  - *To reach the next level:* Add token/cost caps and a run-level time bound for the main session.
- **C L1:** Limits cover sub-agents and background tasks (with depth and concurrency caps) but not the top-level session loop. — [packages/omo-opencode/src/features/background-agent/subagent-spawn-limits.ts:4-5](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/features/background-agent/subagent-spawn-limits.ts#L4-L5); [packages/omo-opencode/src/features/background-agent/concurrency.ts:35-39](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/features/background-agent/concurrency.ts#L35-L39) (verified)
  - *To reach the next level:* Apply the step, time and cost limits to the main session as well.
- **D L2:** Sub-agent limits are on by default with sensible values and only operator config changes them. — [packages/omo-opencode/src/features/background-agent/subagent-spawn-limits.ts:4-5](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/features/background-agent/subagent-spawn-limits.ts#L4-L5); [packages/omo-opencode/src/features/background-agent/constants.ts:7-10](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/features/background-agent/constants.ts#L7-L10) (verified)
  - *To reach the next level:* Prevent the model from resetting its budget by delegating and add hard ceilings config cannot exceed.
- **B L0:** With no ceiling on the main session and an auto-continuation hook, a runaway session can keep acting and spending. — [packages/omo-opencode/src/hooks/todo-continuation-enforcer/constants.ts:7-11](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/hooks/todo-continuation-enforcer/constants.ts#L7-L11); [packages/omo-opencode/src/hooks/todo-continuation-enforcer/constants.ts:23](https://github.com/code-yeongyu/oh-my-openagent/blob/a8019016f47a9d814ebcc24bd921a561f065ee80/packages/omo-opencode/src/hooks/todo-continuation-enforcer/constants.ts#L23) (verified)
  - *To reach the next level:* Add tight per-run time and cost ceilings for the main session.
- **Cap:** none

## Rule-of-Two check
[A] untrusted input: web fetch and Exa/Context7/grep.app MCP results (packages/omo-opencode/src/mcp/index.ts:39-45), repository files and injected AGENTS.md/rules (plugin/tool-execute-before.ts:100-102) · [B] sensitive data/systems: full process environment passed to hook commands (packages/utils/src/command-executor/execute-hook-command.ts:94-107) · [C] state change / egress: webfetch and out-of-project access set to allow (plugin-handlers/tool-config-handler.ts:156-161); interactive_bash spawns tmux commands (tools/interactive-bash/tools.ts:174-181) · Same default session? Yes

## Highest-impact improvements
1. Stop forcing webfetch and external_directory to allow, and ship ask rules for bash, interactive_bash, edit and webfetch on the default agents. — C2 D L0→L3, +0.150 before caps (Playbook 5, step 1)
2. Add a workspace-trust prompt before loading a repository's .claude/settings.json hooks, .mcp.json servers and .omo/omo.jsonc. — C6 S L0→L3, +0.225 before caps (Playbook 2)
3. Run hook commands and interactive_bash with the same scrubbed environment already used for plugin hooks and skill MCP servers. — C1 C L0→L1, +0.075 before caps (Playbook 4)
4. Add a step and token/cost budget for the main session and stop auto-continuation once it is reached. — C10 C L1→L2, +0.075 before caps (Playbook 3, step 3)
5. Block internal and metadata addresses in the webfetch helper and confine look_at to the project directory. — C3 S L1→L2, +0.075 before caps (Playbook 3)

## Re-audit log
- No changes.

## Limitations
- Static source review of the pinned commit only; nothing was executed, installed, or probed.
- Scope is the OpenCode plugin edition (packages/omo-opencode and the core packages it imports). The README now leads with the standalone omo binary, whose agent engine (senpi, a pi fork) is an external npm package not in this repository; that edition and the Codex Light edition (packages/omo-codex) were not scored.
- The Codex Light installer, unless --no-codex-autonomous is passed, rewrites ~/.codex/config.toml to approval_policy never and sandbox_mode danger-full-access (packages/omo-codex/src/install/codex-config-permissions.ts:6-8); this edition was not scored.
- OpenCode host behaviour (default allow-all permission ruleset, its shell tool, session store and snapshots) is outside this repository; parameters that depend on it are marked inferred.
- Project LSP configuration files (.opencode/lsp.json, .omo/lsp.json) passed to the bundled LSP daemon and the opt-in OpenClaw Discord/Telegram/command gateways were not traced end to end.
- No reviewer-injection text was found; the repository's AGENTS.md files contain contributor-workflow instructions for coding agents, which were treated as data.
