Permission Gate
“Check Before You Execute”
Dangerous actions need a harness decision point before the shell runs.
Before executing a tool, the harness checks whether the action requires permission. Dangerous commands, such as filesystem writes, network access, and code execution, prompt the user for confirmation. Read-only operations pass through automatically. Because this gate lives at the harness level, every tool receives permission checking without additional code.
Architecture Flow
The Problem: Automation Without Recklessness
An agent with arbitrary tool access is powerful but dangerous. A single hallucinated bash command could delete files, install malware, or exfiltrate data. The solution is not to remove tools but to add a permission gate that classifies every action before execution. Read operations, such as glob, grep, and read, pass through automatically. Write operations, including edit, write, and bash, prompt the user. This approach balances safety with workflow efficiency: the agent moves quickly on safe operations but pauses for confirmation on dangerous ones.
Safety at the Harness Level
The permission gate lives in execute_tool(), not in individual handlers. This is intentional: safety is a cross-cutting concern that should not be duplicated across tools. A single gate protects all tools, including future ones that do not yet exist. The classification function classifyAction() uses both the tool name and the input parameters to determine the danger level. Writing to /etc/passwd is more dangerous than writing to /tmp/test.txt, even though both operations use the write tool.
Design Decisions
The permission check is async, using await promptUser, which means the agent yields control to the user interface. The agent literally waits for human input before proceeding, with no silent approvals.
Danger level classification is not hardcoded. Plugins can register custom classifiers or override default ones through hooks. This allows organizations to enforce their own security policies.
Comparison: Claude Code
Both prioritize permission gates over sandbox isolation. Claude Code requires explicit user approval for file writes and shell commands. OpenCode's permission system takes this further with classifyAction(), a structured classification function that uses wildcard path patterns (allow, deny, ask) rather than simple binary prompts. The Deferred<PermissionEval> pattern means permissions can be pre-evaluated and cached, reducing user prompt fatigue.
Deep Dive: Design Decisions
Gate at the Harness Level, Not the Tool Level
Permissions are checked in the harness, before the tool executes. This means every tool gets permission checking for free — no tool needs to implement its own security logic.
User Must Opt In for Dangerous Actions
Commands that modify the filesystem, access the network, or execute arbitrary code require explicit user confirmation. Read-only operations pass through automatically.