[FEATURE]: Add per-agent filesystem boundaries (allow/deny paths) + optional run-as user for bash
Feature hasn't been suggested before.
- [x] I have verified this feature I'm about to request hasn't been suggested before.
Describe the enhancement you want to request
Here’s a ready-to-paste GitHub issue (plus a few title options). I wrote it to fit how OpenCode already talks about agents + per-agent permissions/tools ([OpenCode][1]), and to extend the existing “external_directory” safety layer into something more granular ([OpenCode][2]).
Title options (pick one)
I’d like stronger per-agent isolation so that different agents can operate with different levels of access.
OpenCode already supports:
- multiple agents (eg. build / plan) ([GitHub][3])
- per-agent tool enable/disable ([OpenCode][4])
- per-agent permissions for
edit,bash,webfetch, and per-commandbashpermission patterns ([OpenCode][1]) - a global safety layer for files outside the working directory (
permission.external_directory) ([OpenCode][2])
What’s missing (request):
-
Custom shell / execution identity per agent (eg. run the
bashtool as a different OS user / different shell config per agent) -
Ability to allow/deny filesystem paths per agent (eg. agent A can only read
src/**, agent B can edit onlydocs/**, etc.)
Problem / motivation
Right now, if an agent can run bash or file tools, it effectively inherits the same OS permissions as the OpenCode process. Even with “ask/deny” prompts, I still want a hard boundary for certain agents (especially subagents), so that mistakes or prompt injection can’t reach sensitive areas.
This also aligns with common “two agent” workflows (plan vs build) where you want a safer agent to explore unfamiliar repos ([GitHub][3]), but I want to extend that idea into real sandboxing and per-path scope.
Use cases
-
Read-only reviewer / auditor agent
- Can read only
src/**andREADME.md - Cannot read
.env,.ssh,~/.config, etc. - Cannot edit anything
- Can read only
-
Docs-only agent
- Can edit
docs/**andREADME.md - Cannot touch
src/**or build scripts
- Can edit
-
Monorepo service agent
- Agent for
services/payments/**only - No access to sibling services (reduces accidental cross-service changes)
- Agent for
-
“Untrusted input” / offline agent
- Used to inspect third-party code or pasted logs
- No
webfetch, no access outside a specific scratch directory - Ideally runs under a low-privilege OS user (and optionally no network, if supported)
-
CI / GitHub Actions safety
- When OpenCode runs in GitHub Actions, restrict an agent to the checked-out workspace only (and optionally disallow secrets paths)
Proposed behavior (my suggestions)
A) Per-agent filesystem boundaries (allow/deny paths)
Add a per-agent “filesystem policy” that applies to all file-related tools (at minimum: read, write, edit, patch, glob, list, grep, todo tools, etc.).
My suggestion: allow glob patterns and treat rules as:
-
denyrules overrideallow - evaluate after resolving real paths (handle
..+ symlinks safely) - default behavior unchanged unless configured
Example (JSON config):
{
"$schema": "https://opencode.ai/config.json",
"agent": {
"docs": {
"description": "Docs-only agent",
"tools": { "bash": false },
"fs": {
"allow": ["docs/**", "README.md"],
"deny": ["**/.env", "**/.ssh/**", "**/secrets/**", ".git/**"]
}
},
"payments": {
"description": "Payments service agent",
"fs": {
"allow": ["services/payments/**"],
"deny": ["**/.env", ".git/**"]
}
}
}
}
My suggestion for UX when a tool hits a blocked path:
- If denied: show a clear error like
Access denied by agent fs policy: read ".env" (matched deny "**/.env") - Optional: if a policy mode is “ask”, prompt the user once and optionally “remember for session”.
B) Per-agent bash execution context (shell + run-as user)
Add the ability to configure how the bash tool runs per agent.
My suggestion: support at least:
-
shell.path+shell.argsper agent (today shell config exists globally in OpenCode) ([Go Packages][5]) - optionally a “run as user” / execution wrapper (for people who want real OS-level isolation)
Example:
{
"agent": {
"safe": {
"description": "Lower-privilege agent",
"permission": { "bash": "ask" },
"bash": {
"shell": { "path": "/bin/bash", "args": ["-lc"] },
"run_as": "opencode_safe" // or: "wrapper": ["sudo", "-n", "-u", "opencode_safe", "--"]
}
}
}
}
If true OS-user switching is too platform-specific, my suggestion is to allow a configurable wrapper command (so users can plug in sudo, runuser, doas, bwrap, firejail, etc. depending on OS).
C) Relationship to permission.external_directory
OpenCode already has permission.external_directory to require approval when accessing files outside the working directory ([OpenCode][2]).
My suggestion: keep that as a simple safety net, but introduce per-agent allow/deny as the “strong, explicit boundary” (works inside the repo too, not just outside).
Examples of how it should work
Example 1: docs agent tries to edit code
- Agent:
docs - Action: tries to
edit src/main.ts - Result: blocked immediately with a message indicating which rule denied it.
Example 2: payments agent tries to read .env
- Agent:
payments - Action: tries to
read .env - Result: blocked with explanation (
deny **/.env)
Example 3: safe agent runs bash
- Agent:
safe - Action:
bash "cat ~/.ssh/id_rsa" - Result: fails even if user accidentally approves, because OS user / sandbox cannot read it (hard boundary).
Acceptance criteria
-
[ ] Users can define per-agent allowed/denied path patterns
-
[ ] Path enforcement applies consistently across file-related tools
-
[ ] Deny rules override allow rules; safe path resolution prevents traversal/symlink escapes
-
[ ] Clear user-facing errors when blocked
-
[ ] (Optional / phase 2) per-agent bash execution context:
- [ ] per-agent
shellconfig - [ ] optional “run-as” or wrapper approach for OS-level isolation
- [ ] per-agent
Alternatives considered
- Relying only on “ask” prompts (helps, but still permits mistakes)
- Disabling
bashentirely (too limiting; I still want safe command execution) - Only
external_directorychecks (doesn’t solve “within-repo” boundaries likedocs/**vssrc/**) ([OpenCode][2])
Related issues / context
This issue might be a duplicate of existing issues. Please check:
- #2242: Is there a way to sandbox the agent?
- #4667: Limiting access for tools in a safer way
- #4743: Allow /tmp or folder access option
- #5395: Split external_directory permission into read vs write
- #5076: OpenCode should have better/safer defaults to be more security minded
- #1445: Allow for setting read-only files and directories
- #3808: Task should inherit current agent permissions/tools for MCP
Feel free to ignore if none of these address your specific case.