# 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: 1. **Blocks** system commands that have sandboxed WasmBox equivalents 2. **Suggests** the correct WasmBox tool to use instead 3. **Logs** every blocked attempt to the compliance run log 4. **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 ```bash curl -sSf https://tangled.org/metaend.eth.xyz/wasmbox-cli/raw/main/install.sh | sh ``` Or manually: ```bash 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 ```bash wasmbox policy init \ --name "Agent Production Policy" \ --approved-by "compliance@yourcompany.com" \ --enforcement enforce ``` ### 3. Enable agent shell enforcement ```bash wasmbox policy agent --enable ``` This adds a `[agent]` section to `~/.wasmbox/policy.toml` with default blocked/allowed command lists: ```toml [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 ```bash wasmbox policy shell > ~/.wasmbox/agent-shell.sh chmod +x ~/.wasmbox/agent-shell.sh ``` ### 5. Point your agent to use it **OpenCode:** ```bash export OPENCODE_SHELL=~/.wasmbox/agent-shell.sh opencode ``` **Claude Code:** ```bash # In your shell profile or project .env export CLAUDE_CODE_SHELL=~/.wasmbox/agent-shell.sh ``` **Any agent that accepts a custom shell:** ```bash 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`: ```jsonl {"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: ```bash 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 ```bash # 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`: ```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: ```bash wasmbox policy shell > ~/.wasmbox/agent-shell.sh ``` ### Add more allowed commands ```toml [agent] allowed_commands = [ # ... existing ... "docker", "kubectl", "terraform", ] ``` ### Disable enforcement temporarily ```bash wasmbox policy agent --disable wasmbox policy shell > ~/.wasmbox/agent-shell.sh # regenerate ``` Or just unset the shell override: ```bash 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 (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.