DEV Community

TECHDEV
TECHDEV

Posted on Originally published at github.com

I measured an AI sandbox's audit export. It contained zero records — so I built the layer that keeps its own.

Your agent's sandbox may block the bad action. The harder question is whether you can prove what it did — and what you stopped.

An independent evaluation of NVIDIA's OpenShell (a sandbox runtime for AI agents) found the blocking held up, but the evidence did not: a blocked DNS query left no event at all, the OCSF audit export silently wrote nothing, and some events existed only on the VM console. If the records are scattered, incomplete, or editable after the fact, you cannot answer the only question that matters after an incident: what exactly did the agent do?

So I built the missing layer.

Agent Seatbelt

Agent Seatbelt is a vendor-neutral policy and evidence layer that sits above whatever agent runtime you already use:

  • Deterministic policy at the boundary. Tool calls, network egress, DNS, file access, budget, and credential grants are decided by OPA/Rego policies running outside the agent process. No LLM judges anything in the decision path.
  • Allow and deny become records. Every decision lands in an append-only, hash-chained evidence ledger, stamped with the hash of the exact policy pack that decided it. Flip one byte and the offline verifier names the tampered record.
  • Coverage accounting. Each adapter publishes a coverage manifest. After a run, the ledger is reconciled against an independent ground truth — an action with no record fails the run, in writing. Coverage is checked, not claimed.
  • Credentials per run + per action. A broker grants a credential for one run, one action, one target. The model never sees the raw secret; the ledger records the grant or the refusal, never a value.
  • One-command offline verification. Chain integrity, checkpoint signatures, external anchor, coverage report, and a raw-secret scan of the whole bundle — no server, no trust in the runtime.

Measured, not promised (phase 1)

  • Coverage reconciliation vs independent ground truth: 11/11 (clean) and 13/13 (planted) on both adapters — 0 actions without a record.
  • Five planted violations (DNS secret exfiltration, a denied tool call, a budget-cap breach, an out-of-scope file write, credential abuse) all blocked and recorded; the clean run had 0 false blocks.
  • The 1-byte tamper case: the verifier fails and names exactly the tampered record.
  • Decision latency p95: 27.5 ms against a 50 ms budget; the README golden path runs in 1.7 s.
  • The acceptance harness once failed on our own sample code — a client silently bypassed the proxy via no_proxy, one fetch left no record, and the coverage accountant caught it. That incident is documented in the release dossier; it is the mechanism working as designed.

Then we ran the real runtime — and measured its export

Phase 1 was first measured against a faithfully reconstructed OCSF stream. That was not good enough, so we booted OpenShell 0.1.5 for real on a GitHub Actions runner (docker driver; workflow and evidence artifact are in the repo):

  • The sandbox reached Ready and executed real commands.
  • A native shorthand event exists for a denied DNS lookup (NET:REFUSE … DENIED, reason policy_dns_ineligible).
  • But the documented OCSF-JSON export produced zero records in both runs, with ocsf_json_enabled set exactly as NVIDIA's documentation prescribes. Per those same docs, the supervisor's file sink lives on a tmpfs external tools cannot read, so it could not be inspected out of band either.
  • Seatbelt-side coverage on the same runner: 13/13 PASS against independent ground truth.

In other words: on the vendor's current build, the native side contributes nothing to an external evidence ledger. That is not a strawman — it is a measurement, and it is exactly the gap the boundary recorder exists to close.

Two honest limits from that round: the original blocked-UDP-DNS case could not be re-run there (the default sandbox image ships no dig, curl, or python3), and a live interactive Claude Code session is still pending — the hook path is exercised through the real hook protocol, but no authenticated live session has been run yet.

Where rivals beat us

  • OpenShell and nono provide the actual isolation. Seatbelt has none and never will. If you need a sandbox, run one of theirs under Seatbelt.
  • nono shipped hash-chained agent audit before us — inside its own sandbox. Seatbelt's claim is the neutral, cross-runtime layer with verified coverage, not being first to a hash chain.
  • Infisical Agent Vault is a polished commercial credential broker with support. Ours is a phase-1, in-memory broker with per-run grants.

Seatbelt's claim is narrower: unify policy, evidence, credential grants, and verified coverage on one layer that does not care which runtime sits underneath.

Try it

The repo has a two-minute quickstart (Python ≥ 3.11 + an OPA binary; everything else is the standard library), a demo GIF recorded from one real terminal session — clean run, planted run, offline verification, and the tamper case failing — plus the full release dossier with every measurement and every limit stated next to its claim.

Repo: https://github.com/techdevfun/agent-seatbelt (Apache-2.0)

If your runtime's audit export has ever surprised you, I would like to hear what it did.

Top comments (0)