Limiting access for tools in a safer way
Question
I have started to do a bit of research on how there could be limitations put in place on what tools and commands are allowed to do during execution.
I'm still very new to the code-base so will probably miss obvious things, but here we go.
I'm thinking of implementing a interface that would run tools within a security-context. bubblewrap would be used on linux. This would be configured on a per agent-basis similar to the current permissions part, but with a lot more control. When launching anything it would then run in a context that could be locked down to just the content it's allowed to touch. We can set per-folder read/write permissions and prevent it from even reading files outside the project-root or even prevent a agent from doing any network-communication, like curl.
A documentation-agent could then be configured similar to:
readOnlyPaths: [ "<project root>/" ]
writeablePaths: [ "<project root>/doc", "<project root>/temp" ]
allowedExecutables: [ "/usr/bin/bash", "/usr/bin/ls", "/usr/bin/curl" ]
And this would then prevent access to anything outside of <project root> and only allow access to specific commands.
If we would do a
readOnlyPaths: [ "<project root>/" ]
writeablePaths: [ "<project root>/doc", "<project root>/temp" ]
allowedExecutables: [ "/usr/bin/bash", "/usr/bin/ls", "/usr/bin/curl", "<project root>/test-script.sh" ]
then even the test-script.sh would not be able to execute anything not included in the allowedExecutables or write outside of the specified writablePath's.
This is just a initial concept that i would like some feedback on before writing any code.
This issue might be a duplicate of existing issues. Please check:
- #2206: [FEATURE] add
exectool as more secure alternative to bash tool - proposes a secure alternative to bash that prevents shell operators and discusses broader sandboxing solutions - #2242: Is there a way to sandbox the agent? - asks about restricting terminal commands and file access outside the current directory, mentions seatbelt and similar sandboxing tools
- #3585: Add pattern-based directory access restrictions to prevent verbose per-tool configurations - proposes pattern-based access restrictions as a global configuration option (CLOSED)
Feel free to ignore if none of these address your specific case.
Hi @pakar, I solved this by using a slightly modified script from what I suggested in https://github.com/sst/opencode/issues/2242#issuecomment-3604770160.
The script is using Nix and Devbox but you can update it to your needs. Maybe this helps!
#!/usr/bin/env bash
# Define your workspace directories
WORKSPACES=(
"/nix"
"$PWD/devbox"
"$PWD/.venv"
"$PWD"
"$PWD/node_modules"
)
# Build workspace bind mounts
WORKSPACE_BINDS=()
for ws in "${WORKSPACES[@]}"; do
if [ -d "$ws" ]; then
WORKSPACE_BINDS+=(--bind "$ws" "$ws")
fi
done
# Execute OpenCode in sandbox
bwrap \
--unshare-all \
--share-net \
--die-with-parent \
--new-session \
\
`# Basic filesystem structure` \
--ro-bind /usr /usr \
--ro-bind /lib /lib \
--ro-bind /lib64 /lib64 \
--ro-bind /bin /bin \
--ro-bind /sbin /sbin \
--proc /proc \
--dev /dev \
--tmpfs /tmp \
--tmpfs /run \
\
`# SSL certificates for API access` \
--ro-bind-try /etc/ssl /etc/ssl \
--ro-bind-try /etc/ca-certificates /etc/ca-certificates \
\
`# Home directory structure` \
--dir "$HOME" \
--setenv HOME "$HOME" \
--chdir "$PWD" \
\
`# OpenCode config and cache directories (read-write)` \
--bind-try "$HOME/.cache/opencode" "$HOME/.cache/opencode" \
--bind-try "$HOME/.local/share/opencode" "$HOME/.local/share/opencode" \
--bind-try "$HOME/.local/state/opencode" "$HOME/.local/state/opencode" \
--bind-try "$HOME/.config/opencode" "$HOME/.config/opencode" \
\
`# Workspace directories (read-write)` \
"${WORKSPACE_BINDS[@]}" \
\
`# Terminal and environment` \
--setenv TMPDIR /tmp \
--setenv PATH "$PWD/node_modules/.bin:$PWD/bin:/usr/local/bin:/usr/bin:/bin" \
\
`# Run OpenCode` \
opencode "$@"