WasmBox + OpenCode: Sandboxed Agent Tool Enforcement #
How to make AI agents use sandboxed WasmBox tools instead of raw system commands.
The Problem #
AI agents (OpenCode, Claude Code, Cursor, Copilot) shell out to system commands freely. An agent running jq, base64, python -c, or node -e executes arbitrary code on your machine with full user permissions. No sandbox, no audit trail, no capability restrictions.
For EU AI Act Article 14 compliance, you need to prove:
- What tools your AI agents ran
- What permissions those tools had
- Who approved them
- That the approved binary is the one that actually executed
System commands give you none of this. WasmBox gives you all of it.
The Solution #
WasmBox's agent shell enforcement generates a restricted shell wrapper that:
- Blocks system commands that have sandboxed WasmBox equivalents
- Suggests the correct WasmBox tool to use instead
- Logs every blocked attempt to the compliance run log
- Allows basic shell operations (echo, cat, grep, git, cargo, etc.)
The agent tries jq '.name' file.json, gets a clear error with the replacement command, self-corrects, and uses wasmbox run jfmt -- -q name instead. After one or two blocks, the agent learns the pattern for the session.
Setup #
1. Install WasmBox and tools #
curl -sSf https://tangled.org/metaend.eth.xyz/wasmbox-cli/raw/main/install.sh | sh
Or manually:
cargo install --path crates/cli
wasmbox registry add https://qstorage.quilibrium.com/wasmbox
wasmbox install jfmt --allow-all
wasmbox install yamlfmt --allow-all
wasmbox install b64 --allow-all
wasmbox install secretscan --allow-all
wasmbox install compact --allow-all
wasmbox install errparse --allow-all
wasmbox install hashit --allow-all
wasmbox install epoch --allow-all
wasmbox install diffsummary --allow-all
wasmbox install worldid-verify --allow-all
2. Create a compliance policy #
wasmbox policy init \
--name "Agent Production Policy" \
--approved-by "compliance@yourcompany.com" \
--enforcement enforce
3. Enable agent shell enforcement #
wasmbox policy agent --enable
This adds a [agent] section to ~/.wasmbox/policy.toml with default blocked/allowed command lists:
[agent]
shell_enforcement = true
blocked_commands = [
"jq",
"yq",
"base64",
"sha256sum",
"date",
"trufflehog",
"python -c",
"node -e",
]
allowed_commands = [
"wasmbox",
"echo", "cat", "find", "ls", "cd", "pwd",
"mkdir", "cp", "mv", "rm",
"grep", "head", "tail", "wc", "diff", "sort", "uniq", "tr", "cut", "sed", "awk",
"git", "cargo", "rustc", "rustup",
"curl", "wget",
"tar", "gzip", "gunzip", "zip", "unzip",
"chmod", "chown", "touch",
"env", "export", "source", "which", "type", "command",
"true", "false", "test", "[",
"read", "printf",
"pipe", "xargs",
]
Edit ~/.wasmbox/policy.toml to customize these lists for your environment.
4. Generate the shell wrapper #
wasmbox policy shell > ~/.wasmbox/agent-shell.sh
chmod +x ~/.wasmbox/agent-shell.sh
5. Point your agent to use it #
OpenCode:
export OPENCODE_SHELL=~/.wasmbox/agent-shell.sh
opencode
Claude Code:
# In your shell profile or project .env
export CLAUDE_CODE_SHELL=~/.wasmbox/agent-shell.sh
Any agent that accepts a custom shell:
export SHELL=~/.wasmbox/agent-shell.sh
What Happens #
Agent tries a blocked command #
$ jq '.name' data.json
BLOCKED by WasmBox policy: 'jq' is not allowed.
Use instead: wasmbox run jfmt
Available tools: b64, compact, diffsummary, epoch, errparse, hashit, jfmt, secretscan, worldid-verify, yamlfmt
The agent sees this error, understands the replacement, and self-corrects:
$ cat data.json | wasmbox run jfmt -- -q name
alice
Agent tries an allowed command #
$ echo "hello" | grep "hello"
hello
Passes through normally. No interference.
Agent tries an unknown command #
$ some-random-tool --flag
WARNING: 'some-random-tool' is not in the WasmBox allowed commands list.
Runs with a warning. Not blocked, but logged.
Command Mapping #
| Blocked Command | WasmBox Replacement | Tool |
|---|---|---|
jq |
wasmbox run jfmt |
jfmt |
yq |
wasmbox run yamlfmt |
yamlfmt |
base64 |
wasmbox run b64 |
b64 |
sha256sum |
wasmbox run hashit |
hashit |
date |
wasmbox run epoch |
epoch |
trufflehog |
wasmbox run secretscan |
secretscan |
python -c |
appropriate wasmbox tool | - |
node -e |
appropriate wasmbox tool | - |
Compliance Story #
Every blocked command is logged to ~/.wasmbox/run.log:
{"ts":"2026-03-31T14:00:00.000Z","tool":"jq","version":"shell","hash":"none","hash_verified":false,"capabilities":[],"exit_code":null,"duration_ms":null,"policy":"blocked","policy_reason":"agent shell: jq blocked, use jfmt"}
When you generate an audit report:
wasmbox audit --export --sign
The report shows:
- Total blocked commands and their replacements
- All sandboxed tool executions with hash verification
- Policy enforcement status
- Compliance verdict (PASS/FAIL)
For a regulator: "Our AI agents attempted 12 raw jq calls. All were blocked by policy. All were redirected to sandboxed jfmt with SHA-256 verification. Here's the signed audit report."
That's Article 14 oversight in action.
Verifying the Setup #
# Check your policy
wasmbox policy show
# Check agent enforcement is active
wasmbox policy agent
# See what the shell wrapper looks like
wasmbox policy shell | head -20
# Test it manually
bash ~/.wasmbox/agent-shell.sh jq . # Should be BLOCKED
bash ~/.wasmbox/agent-shell.sh echo hello # Should work
# Check the run log for blocked entries
wasmbox log --blocked
# View stats
wasmbox log --stats
Customizing #
Add more blocked commands #
Edit ~/.wasmbox/policy.toml:
[agent]
blocked_commands = [
"jq",
"yq",
"base64",
"sha256sum",
"date",
"trufflehog",
"python -c",
"node -e",
"ruby -e", # add your own
"perl -e", # add your own
]
Then regenerate the wrapper:
wasmbox policy shell > ~/.wasmbox/agent-shell.sh
Add more allowed commands #
[agent]
allowed_commands = [
# ... existing ...
"docker",
"kubectl",
"terraform",
]
Disable enforcement temporarily #
wasmbox policy agent --disable
wasmbox policy shell > ~/.wasmbox/agent-shell.sh # regenerate
Or just unset the shell override:
unset OPENCODE_SHELL
Architecture #
Agent (OpenCode/Claude Code/etc.)
|
| executes command
v
~/.wasmbox/agent-shell.sh
|
|-- blocked? --> BLOCKED message + log to run.log + exit 2
|-- allowed? --> exec command normally
|-- unknown? --> WARNING + exec command normally
|
v
wasmbox run <tool> (sandboxed, hash-verified, logged)
The shell wrapper is a plain bash script. No daemon, no background process, no network calls. It checks the command name against two lists and either blocks or passes through. Blocked attempts are appended to ~/.wasmbox/run.log in the same JSONL format as wasmbox tool executions.