From 7a1b18f9317f2e1768cf19ccfad7123e1fc959b3 Mon Sep 17 00:00:00 2001 From: StanPonomarev Date: Tue, 21 Jul 2026 00:42:56 +0200 Subject: [PATCH] fix: opencode config 2 --- README.md | 31 ++++++++++++++++--------------- opencode/opencode.json | 13 +------------ tests/test_opencode_deployment.py | 10 ++++------ 3 files changed, 21 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index ffae856..23c77c4 100644 --- a/README.md +++ b/README.md @@ -69,13 +69,14 @@ to `^1`. The build verifies that the resolved version is still OpenCode 1.x and requests a no-cache build so the configured range is resolved again on each build. Runtime auto-update is disabled so an image cannot cross into OpenCode 2.x after it is built. -The trusted configuration is `opencode/opencode.json`. It grants `permission: "allow"` globally -and to every built-in or custom agent that Agent CI can invoke. Repository-local OpenCode config -and external plugins are disabled so a clone cannot replace the service policy. OpenCode's default -plugins remain enabled for provider authentication. Its scanned home and global configuration paths -are root-owned and read-only, and external skill discovery is disabled, so an agent cannot persist -instructions for later repositories. CodeGraph, Context7, and `gh_grep` are configured as MCP -servers. Set `AGENTCI_CONTEXT7_API_KEY` to raise Context7 rate limits. +The trusted configuration is `opencode/opencode.json`. OpenCode's default global and built-in-agent +permission policies remain in effect; Agent CI does not replace them with an allow-all policy. +Repository-local OpenCode config and external plugins are disabled so a clone cannot replace the +service policy. OpenCode's default plugins remain enabled for provider authentication. Its scanned +home and global configuration paths are root-owned and read-only, and external skill discovery is +disabled, so an agent cannot persist instructions for later repositories. CodeGraph, Context7, and +`gh_grep` are configured as MCP servers. Set `AGENTCI_CONTEXT7_API_KEY` to raise Context7 rate +limits. The `research` subagent can only use Exa web search, Context7, and the `gh_grep` public-code search MCP. All filesystem, shell, editing, task, and other tools are denied for that agent. Exa is enabled @@ -84,11 +85,10 @@ and locally excludes `.codegraph/` from Git. ### Security boundary -OpenCode does not provide an OS sandbox. It can execute shell commands, edit Git metadata and -environment files, access external directories, use loopback and network services, bind ports, and -invoke subagents without approval. It can access every shared workspace, development tool, runtime -credential, and mounted file readable by the non-root container user. Environment filtering is -only accidental-exposure hygiene and cannot protect readable files from shell commands. +OpenCode does not provide an OS sandbox. Its default permission system controls agent tools and +approval requests, while Docker limits what the non-root process can reach. Any shell command that +OpenCode permits still has the Unix-level access of that container user, so environment filtering +is only accidental-exposure hygiene and cannot protect readable files from an allowed shell command. Docker remains the OS boundary. The services run as non-root without added capabilities, privileged mode, an unconfined seccomp/AppArmor profile, or a nested `bubblewrap` sandbox. The only @@ -113,11 +113,12 @@ Every name resolves to a file in `install-scripts/`, mounted read-only at run after each implementation clone or branch sync and fail the job on an unknown script, timeout, or non-zero exit. They receive no Agent CI or Gitea secret values in their environment, but remain trusted operator code. Tools persist under `/var/lib/agentci/dev-tools`, and OpenCode can read or -modify them through its unrestricted shell. See `install-scripts/README.md` for the script contract. +modify them through shell commands permitted by its active agent policy. See +`install-scripts/README.md` for the script contract. Agent CI continues to create branches, validate diffs, commit, and push after OpenCode returns. This -keeps workflow behavior deterministic, but unrestricted OpenCode is not prevented from running Git -commands itself. +keeps workflow behavior deterministic, but an OpenCode agent with shell permission can still run +Git commands itself. ## State and recovery diff --git a/opencode/opencode.json b/opencode/opencode.json index 34fded6..ab18194 100644 --- a/opencode/opencode.json +++ b/opencode/opencode.json @@ -4,21 +4,10 @@ "share": "disabled", "subagent_depth": 1, "instructions": ["/etc/opencode/AGENTS.md"], - "permission": "allow", "agent": { - "build": { - "permission": "allow" - }, - "plan": { - "permission": "allow" - }, - "general": { - "permission": "allow" - }, "explore": { "model": "{env:AGENTCI_EXPLORE_MODEL}", - "variant": "{env:AGENTCI_EXPLORE_VARIANT}", - "permission": "allow" + "variant": "{env:AGENTCI_EXPLORE_VARIANT}" }, "research": { "description": "Research current documentation, web evidence, and public code examples.", diff --git a/tests/test_opencode_deployment.py b/tests/test_opencode_deployment.py index 68006f7..b45702f 100644 --- a/tests/test_opencode_deployment.py +++ b/tests/test_opencode_deployment.py @@ -2,15 +2,13 @@ import json from pathlib import Path -def test_config_grants_parent_agents_access_and_restricts_research() -> None: +def test_config_preserves_builtin_permissions_and_restricts_research() -> None: root = Path(__file__).parents[1] config = json.loads((root / "opencode" / "opencode.json").read_text()) - assert config["permission"] == "allow" - assert all( - config["agent"][name]["permission"] == "allow" - for name in ("build", "plan", "general", "explore") - ) + assert "permission" not in config + assert all(name not in config["agent"] for name in ("build", "plan", "general")) + assert "permission" not in config["agent"]["explore"] assert config["agent"]["research"]["permission"] == { "*": "deny", "websearch": "allow",