Observed since 20 Oct, 21:34 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Policy-sandboxed runtime for AI agent processes: enforce a policy file, capture a tamper-evident trace, deterministically replay any run.
A sandbox runtime for AI agent processes. One policy file says what the agent may touch; agentbox wraps the process, enforces the policy at the interpreter level, captures a tamper-evident trace of every side effect, and can deterministically replay any recorded run.
allow: read ./src, net: api.github.com
Zero dependencies. Pure Python stdlib. Python 3.11+.
Agents run with your whole user account: your SSH keys, your ~/.aws, your
network. Reviewing what an agent did after the fact means scrolling logs
that the agent itself could have written. agentbox gives you three properties
that compose:
agentbox verify catches it.pip install agentbox-runtime
agentbox init # writes a starter agentbox.policy
agentbox run -p agentbox.policy -- python agent.py # record
agentbox show # inspect the trace
agentbox verify # check the hash chain
agentbox replay -p agentbox.policy -- python agent.py # deterministic re-run
A run looks like this:
$ agentbox run -p agentbox.policy -- python demo_agent.py
wrote out/summary.txt at 1786243519.9181929
blocked as expected: agentbox: policy denies read /etc/passwd
agentbox: recorded 4 effects, 1 observations, 1 denials -> trace.jsonl
$ agentbox replay -p agentbox.policy -- python demo_agent.py
wrote out/summary.txt at 1786243519.9181929 # same clock value, replayed
agentbox: replay ok — 5/5 recorded steps matched
One rule per line, # comments, everything not allowed is denied:
read: ./data # file reads under this root
write: ./out # writes (implies read) under this root
net: api.github.com # DNS + connect to this host
net: *.githubusercontent.com
net: 127.0.0.1:8080 # optional port pin
net: unix:/tmp/app.sock # unix sockets
exec: git status # argv prefix match
exec: echo # bare program name: any args
env: HOME # env vars passed into the sandbox
env: AWS_* # globs work everywhere
allow: read ./src is an alias for read: ./src, and rules can share a line:
allow: read ./src, net: api.github.com.
agentbox run spawns your command with a scrubbed environment (only
env:-allowed variables survive) and injects a sitecustomize shim via
PYTHONPATH. Before any user code runs, the shim installs a
sys.addaudithook
guard — CPython audit hooks cannot be removed once installed, so the
agent's own code can't disarm it. The guard:
open() outside the policy roots (stdlib and sys.path imports
are exempt), and records allowed reads with a content sha256;subprocess/os.system/os.exec* spawns that don't match an
exec: rule, plus deletes/renames outside write roots;ctypes dlopen/dlsym — the classic audit-hook bypass;For replayable effects, agents use the SDK (anything outside it is still guarded and observed):
import agentbox.client as box
text = box.read_text("data/notes.txt")
resp = box.get("https://api.github.com/repos/x/y") # {"status", "body", "sha256"}
out = box.run(["git", "status"]) # {"code", "stdout", "stderr"}
t = box.now() # frozen on replay
r = box.random() # frozen on replay
box.write_text("out/report.md", text.upper())
Policy says what the agent may touch — but allowed ≠ wanted. With
snapback installed,
--checkpoint snapshots the working tree right before the agent's first
mutating effect, so every recorded run is one command away from never
having happened:
pip install snapback-cli
$ agentbox run --checkpoint -p agentbox.policy -- python agent.py
agent done: rewrote data/notes.txt, wrote out/report.md
agentbox: recorded 4 effects, 0 observations, 0 denials -> trace.jsonl
agentbox: checkpoint 20260809-143103 taken before first mutation — `snapback undo` reverts this run
$ snapback diff # what did it actually change?
A out/report.md
M data/notes.txt
$ snapback undo # put it all back
snapback: restored 20260809-143103
Properties worth knowing:
write_text/run, not at
startup. Runs that only read cost nothing.hook.checkpoint effect
in the same hash-chained trace, so "what can I roll back to" is part of the
same tamper-evident record as "what did it do" (agentbox show shows it).CheckpointError rather than proceeding un-undoable.agentbox replay neither re-snapshots nor
diverges on the hook entry.snapback.toml with ignore = ["trace.jsonl"] next to your agent
so rolling back the agent's writes never truncates the audit trail
(see examples/).Full demo: examples/checkpoint_agent.py.
The same runner sandboxes Node processes — no extra install:
agentbox run -p agentbox.policy -- node agent.js
agentbox replay -p agentbox.policy -- node agent.js
A CommonJS shim is injected via NODE_OPTIONS --require; it enforces the
same policy file (fs, net, child_process, env scrub), appends to the same
hash chain the runner starts, and exposes the SDK as globalThis.agentbox:
const box = globalThis.agentbox;
const text = box.readText("data/notes.txt");
const resp = await box.get("https://api.github.com/repos/x/y");
const out = box.run(["git", "status"]);
const t = box.now(); // integer ms, frozen on replay
const r = box.random(); // integer in [0, 2^48), frozen on replay
box.writeText("out/report.md", text.toUpperCase());
Caveat: the Node guard monkeypatches fs/net/child_process — it contains
well-behaved agents and prompt-injected tool calls, but unlike CPython's
irremovable audit hooks it is not a boundary against code that deliberately
unpatches it. Hardening it (Node permission model flags) is a welcome PR.
agentbox is an interpreter-level sandbox for Python processes, not a kernel one. What that means in practice:
| Stops | Doesn't stop |
|---|---|
An agent (or its prompt-injected tool call) reading ~/.ssh, posting to an unapproved host, spawning rm -rf | A malicious C extension making raw syscalls |
| Secret env vars leaking into the process at all | Bugs in CPython itself |
| Post-hoc log tampering (hash chain) | A hostile human with local root |
| Silent behavioral drift between runs (replay divergence) | Non-Python child processes (their spawn is policy-checked; their own IO is not yet guarded) |
Kernel backends (Landlock on Linux, Seatbelt on macOS) are on the roadmap as defense-in-depth; the policy file and trace format won't change.
(op, args) and served from the trace.Each of these is a single focused PR:
net: cidr/…, rate limits (net: api.x.com @10/min),
read-once:, size caps on write:.--require shim), Deno
(permissions bridge), Bun; the policy/trace/replay core is
runtime-agnostic.agentbox show --html
timeline.See CONTRIBUTING.md.
python -m pytest # 59 tests, all stdlib + pytest (Node tests auto-skip without node)
MIT © Sophie Nguyen Thu Thuy
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.3.0 | 9 Aug 2026 | 0 |
This describes our collected data; it is not a security assessment.
Shared repository data · GitHub
Observed since 20 Oct, 21:34 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:15645529599edb145f5e76883cbeb2ac811dd32cf161a53d7efcb48fd2db0ca5