Switch to custom Bash tool. Mask secrets from Bashsubprocs. Simplify security handling.

This commit is contained in:
Colin McDonnell
2026-01-07 19:15:58 -08:00
parent 2cc081c912
commit 879d33403c
17 changed files with 50158 additions and 37973 deletions
+17 -26
View File
@@ -7,6 +7,7 @@ import { addInstructions } from "./instructions.ts";
import {
agent,
type ConfigureMcpServersParams,
createAgentEnv,
installFromNpmTarball,
setupProcessAgentEnv,
} from "./shared.ts";
@@ -42,24 +43,25 @@ export const opencode = agent({
// 6. set up environment
setupProcessAgentEnv({ HOME: tempHome });
// build env vars: start with process.env (includes all API_KEY vars loaded by config())
// exclude GITHUB_TOKEN - OpenCode should use MCP server for GitHub operations, not direct token
// then override with apiKeys, HOME, and XDG_CONFIG_HOME
// SECURITY: build env vars from whitelisted base env to prevent API key leakage
// this prevents leaking other API keys (ANTHROPIC, GEMINI, etc.) to OpenCode subprocess
// XDG_CONFIG_HOME must be set because GitHub Actions sets it to a different path,
// and OpenCode follows XDG spec (checks XDG_CONFIG_HOME before falling back to $HOME/.config)
const env: Record<string, string> = {
...(Object.fromEntries(
Object.entries(process.env).filter(
([key, value]) => value !== undefined && key !== "GITHUB_TOKEN"
)
) as Record<string, string>),
HOME: tempHome,
...createAgentEnv({ HOME: tempHome }),
XDG_CONFIG_HOME: join(tempHome, ".config"),
};
// OpenCode doesn't support GitHub App installation tokens
delete env.GITHUB_TOKEN;
// add/override API keys from apiKeys object (uppercase keys)
// add API keys from apiKeys object
for (const [key, value] of Object.entries(apiKeys || {})) {
env[key.toUpperCase()] = value;
const upperKey = key.toUpperCase();
env[upperKey] = value;
// also set GOOGLE_GENERATIVE_AI_API_KEY for Google provider compatibility
if (upperKey === "GEMINI_API_KEY") {
env.GOOGLE_GENERATIVE_AI_API_KEY = value;
}
}
// run OpenCode in the repository directory (process.cwd() is set to GITHUB_WORKSPACE or repo dir)
@@ -218,22 +220,11 @@ function configureOpenCode({ mcpServers, sandbox }: ConfigureOpenCodeParams): vo
};
}
// build permissions config
// SECURITY: OpenCode spawns subprocesses with full process.env, leaking API keys.
// disable native bash; agents use MCP bash tool which filters secrets.
const permission = sandbox
? {
edit: "deny",
bash: "deny",
webfetch: "deny",
doom_loop: "allow",
external_directory: "allow",
}
: {
edit: "allow",
bash: "allow",
webfetch: "allow",
doom_loop: "allow",
external_directory: "allow",
};
? { edit: "deny", bash: "deny", webfetch: "deny", doom_loop: "allow", external_directory: "allow" }
: { edit: "allow", bash: "deny", webfetch: "allow", doom_loop: "allow", external_directory: "allow" };
// build complete config in one object
const config = {