From 8cc9c17a1cdd7797cd3eaeaa8d9f58e1f7f6b707 Mon Sep 17 00:00:00 2001 From: elliottwaves-20 Date: Thu, 8 Oct 2026 23:59:04 +0200 Subject: [PATCH 1/2] fix(providers): keep OpenCode's internal plugins so OAuth logins work OPENCODE_DISABLE_DEFAULT_PLUGINS=1 skips every internal OpenCode plugin. In OpenCode 1.18.33 those plugins implement the OAuth logins (ChatGPT via CodexAuthPlugin, Copilot, GitLab, ...) and only register auth and chat.headers/chat.params hooks, no tools. With the flag set, an OAuth login is never attached and every call fails with "Unexpected server error", although the sandbox is meant to keep the user's existing login usable. Tool access stays denied by the deny-all agent and OPENCODE_PERMISSION, and external plugins stay off through --pure / OPENCODE_PURE. Fixes #809 Co-Authored-By: Claude Opus 5.5 Signed-off-by: elliottwaves-20 --- src/skillspector/providers/_agent_cli.py | 6 ++++-- tests/provider/test_opencode_cli.py | 5 ++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/skillspector/providers/_agent_cli.py b/src/skillspector/providers/_agent_cli.py index a2f9e02b0..a0b0ac55a 100644 --- a/src/skillspector/providers/_agent_cli.py +++ b/src/skillspector/providers/_agent_cli.py @@ -503,7 +503,10 @@ def _prepare_opencode_env( independently as defense in depth. The real OpenCode authentication store remains available so this CLI - provider can use the user's existing login. All mutable config, cache, + provider can use the user's existing login. OpenCode's internal plugins stay + enabled for the same reason: they implement the OAuth logins (ChatGPT, + Copilot, GitLab, ...) and register no tools. External plugins remain off + through ``--pure`` / ``OPENCODE_PURE``. All mutable config, cache, state, database, and temporary paths are redirected below the invocation's already-isolated temporary root. """ @@ -536,7 +539,6 @@ def _prepare_opencode_env( "OPENCODE_DISABLE_AUTOCOMPACT": "1", "OPENCODE_DISABLE_AUTOUPDATE": "1", "OPENCODE_DISABLE_CLAUDE_CODE": "1", - "OPENCODE_DISABLE_DEFAULT_PLUGINS": "1", "OPENCODE_DISABLE_EXTERNAL_SKILLS": "1", "OPENCODE_DISABLE_LSP_DOWNLOAD": "1", "OPENCODE_DISABLE_MODELS_FETCH": "1", diff --git a/tests/provider/test_opencode_cli.py b/tests/provider/test_opencode_cli.py index 1271f4b16..c4923e9bf 100644 --- a/tests/provider/test_opencode_cli.py +++ b/tests/provider/test_opencode_cli.py @@ -317,7 +317,10 @@ def test_policy_overrides_hostile_ambient_configuration(self, tmp_path: Path) -> assert config["autoshare"] is False assert env["OPENCODE_AUTO_SHARE"] == "0" assert env["OPENCODE_DISABLE_PROJECT_CONFIG"] == "1" - assert env["OPENCODE_DISABLE_DEFAULT_PLUGINS"] == "1" + # Internal plugins carry the OAuth logins (ChatGPT, Copilot, ...) and + # register no tools; disabling them breaks the user's login (#809). + # External plugins stay off through OPENCODE_PURE below. + assert "OPENCODE_DISABLE_DEFAULT_PLUGINS" not in env assert env["OPENCODE_DISABLE_EXTERNAL_SKILLS"] == "1" assert env["OPENCODE_DISABLE_CLAUDE_CODE"] == "1" assert env["OPENCODE_PURE"] == "1" From 22cec466722cf4f6cc9f00bad1fa588e6639ce2b Mon Sep 17 00:00:00 2001 From: elliottwaves-20 Date: Fri, 9 Oct 2026 00:18:40 +0200 Subject: [PATCH 2/2] docs(providers): describe the plugin scope precisely and pin the env scrub The _build_opencode_argv docstring still said the runner disables plugins; only external plugins are off, the internal OAuth/provider plugins stay enabled. The isolation test now also feeds an ambient OPENCODE_DISABLE_DEFAULT_PLUGINS=1, which the sandbox must scrub so a user environment cannot switch the OAuth logins back off. Refs #809 Co-Authored-By: Claude Opus 5.5 Signed-off-by: elliottwaves-20 --- src/skillspector/providers/_agent_cli.py | 4 +++- tests/provider/test_opencode_cli.py | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/skillspector/providers/_agent_cli.py b/src/skillspector/providers/_agent_cli.py index a0b0ac55a..7d2a44319 100644 --- a/src/skillspector/providers/_agent_cli.py +++ b/src/skillspector/providers/_agent_cli.py @@ -676,7 +676,9 @@ def _build_opencode_argv(binary: str, model: str, max_output_tokens: int = 0) -> SKILLSPECTOR_MODEL is set). The shared runner also isolates every OpenCode config/state path, disables - ambient instructions, skills, plugins, auto-sharing, snapshots and updates, + ambient instructions, skills, external plugins (the internal OAuth/provider + plugins stay enabled, see ``_prepare_opencode_env``), auto-sharing, + snapshots and updates, scrubs secret-bearing environment variables, delivers untrusted content via stdin only, and never passes ``--auto``. diff --git a/tests/provider/test_opencode_cli.py b/tests/provider/test_opencode_cli.py index c4923e9bf..9028c4e8b 100644 --- a/tests/provider/test_opencode_cli.py +++ b/tests/provider/test_opencode_cli.py @@ -302,6 +302,8 @@ def test_policy_overrides_hostile_ambient_configuration(self, tmp_path: Path) -> "OPENCODE_CONFIG_CONTENT": '{"permission":"allow","share":"auto"}', "OPENCODE_PERMISSION": '{"*":"allow"}', "OPENCODE_EXPERIMENTAL": "1", + # An ambient value must not switch the OAuth login plugins back off (#809). + "OPENCODE_DISABLE_DEFAULT_PLUGINS": "1", } argv = _build_opencode_argv(OPENCODE_BINARY, "", 0)