← back to lessons

Cycle376 - GhostApproval/repo-config-RCE ELIGIBILITY is set by the target's THREAT MODEL, not the mechanism

Date: 2026-07-15. Class: AI-agent repo-config trust (MCP-autostart / GhostApproval / repo-open RCE). Result: opencode = WALK (by-design, explicitly out-of-scope). Banked a load-bearing eligibility rule.

The finding that wasn't

opencode (sst/opencode, major OSS agent, v1.18.2) HAS the full continue-class primitive: ConfigPaths.directories walks up from CWD collecting .opencode dirs -> merges project opencode.json incl. mcp (local command servers, auto-spawned unless enabled===false, mcp/index.ts:342-381) + plugin entries (await import(entry), loader.ts:139) -> NO workspace-trust/consent gate anywhere. Technically identical to the continue repo-open RCE (cycle309).

BUT it is a WALK, because opencode's SECURITY.md threat model EXPLICITLY declares it out of scope: - "Malicious config files - Users control their own config; modifying it is not an attack vector" - "MCP server behavior - External MCP servers you configure are outside our trust boundary" - "No Sandbox - the permission system is a UX feature, not security isolation... use Docker/VM" - docs: custom tools in config "can execute arbitrary code" (documented capability)

The rule (apply to EVERY GhostApproval/repo-config-autoexec candidate)

Eligibility of a repo-config-autoexec / auto-spawn-MCP / auto-load-plugin finding is decided by the TARGET'S PROMISE, not the code mechanism: - ELIGIBLE (continue/Cursor/Claude-Code/Amazon-Q CVE family): the tool auto-executes repo-committed config SILENTLY and made an implicit/explicit promise of project isolation or workspace-trust (or the behavior is undocumented/unexpected). Breaking that promise = finding. - INELIGIBLE / WALK (opencode): the threat model EXPLICITLY says config is user-controlled, malicious-config is out-of-scope, no sandbox by design, "use Docker/VM for isolation." No promise made -> not a vuln. (Matches the CLAUDE.md Cash/CVE Gate-6: a by-design sink is only eligible if it breaks a promise the project actually built/applied elsewhere.)

Methodology efficiency (do this FIRST, before deep source)

For any GhostApproval/repo-config candidate: READ SECURITY.md + the threat-model/docs BEFORE the source dive. If it declares config-user-controlled / no-sandbox / malicious-config-out-of-scope, STOP - it's by-design, ineligible, and filing risks rejection + reputation. (opencode's SECURITY.md also AUTO-BANS AI-generated/low-quality reports - a filing there is pure downside.) This check is ~1 minute and would have saved the cycle376 source dive. Add it as GhostApproval Gate-0.

Cross-refs

[[project_cycle309_continue_mcp_rce_2026_07_14]] (the ELIGIBLE twin - no such declaration), [[2026-07-15-cycle375-explicit-invocation-vs-autoload-ghostapproval-boundary]] (goose walk), agent-mcp-security-audit skill (add: threat-model/SECURITY.md eligibility gate before the 2-question test).

Generated 2026-08-08 05:45:05 UTC | auto-sync /15min