Process Sandboxing & Agents (in 5min)

Okay, supply chain attacks are spreading as planned (trivy, litellm, axios [...]). Producing code has never been that affordable, and projects are increasingly filled with AI-generated artifacts. It might be the best time to inject malicious code.

While many of us are executing privileged processes everywhere, hoping for the best, others remain skeptical about adopting agent(s) in critical production paths without good measure.

Your systems contain secrets, documents, and other sensitive data you don't want leaked or altered.

Sandboxing Tooling

Not an exhaustive list, just mine.

To go further, other projects are aiming isolation in other contexts or doing the same.

https://github.com/alibaba/OpenSandbox

more an SDK to build on top

Kubernetes / containers primitive for sandboxing

https://github.com/kubernetes-sigs/agent-sandbox

CRD dedicated to Kubernetes, introduce unique stateful pod declaration instead of current SatefulSets

https://github.com/Use-Tusk/fence - https://github.com/GreyhavenHQ/greywall

native process isolation with bubblewrap

both have the same design

https://github.com/sandboxec/sandboxec

mostly one man project

https://github.com/NVIDIA/OpenShell

isolation based on containers

First things first, I shortlisted srt and nono. I choose the former for its Anthropic support and the latter for its native Rust implementation plus advanced features.

srt

isolation based on user namespace that I already have available

non-invasive in my local workflow

(evil) big corp supporting the project

ease of migration if needed

Configuration

~/.srt-settings.json

Deny by default, allow what necessary in the current directory. Will be enhanced.

{
"network": {
"allowedDomains": [
"github.com",
"*.github.com",
"lfs.github.com",
"api.github.com",
"npmjs.org",
"*.npmjs.org",
"*.golang.org",
"*.z.ai"
],
"deniedDomains": [
"packages.npm.org",
"sfrclak.com"
]
},
"filesystem": {
"denyRead": ["~"],
"allowRead": [
"~/.config/opencode/",
"~/.local/share/opencode/",
"~/.local/bin/",
"~/.flox/run/x86_64-linux.default.run/bin/",
"~/.local/lib/node_modules/",
"~/go/",
"/tmp",
"."
],
"allowWrite": [
"~/.config/opencode/",
"~/.local/share/opencode/",
"~/go/",
"/tmp",
"."
],
"denyWrite": [".env"]
},
"enableWeakerNestedSandbox": false,
"enableWeakerNetworkIsolation": false
}

Just sandbox by default, every time.

~/.bash_aliases

alias opencode='srt -- opencode'

Verify what your agent attempts to do, easily, using strace. I have focused on ~ file operations, where I utilize custom binaries (nix with flox.dev ) along with Node.js, Go, and other libraries. strace is very practical for designing your profile (~/.srt-settings.json)

strace -e file -- opencode --version 2>&1 | grep '/home/'

execve("/home/p00/.local/bin/opencode", ["opencode", "--version"], 0x7ffd7c23d140 /* 156 vars */) = 0
openat(AT_FDCWD, "/home/p00/.local/lib/ollama/glibc-hwcaps/x86-64-v3/libselinux.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (Aucun fichier ou dossier de ce nom)
newfstatat(AT_FDCWD, "/home/p00/.local/lib/ollama/glibc-hwcaps/x86-64-v3/", 0x7fff890b2820, 0) = -1 ENOENT (Aucun fichier ou dossier de ce nom)
openat(AT_FDCWD, "/home/p00/.local/lib/ollama/glibc-hwcaps/x86-64-v2/libselinux.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (Aucun fichier ou dossier de ce nom)