Airlock Live on a Vultr VM · gVisor sandbox · source

Don't trust the agent. Verify what it actually did.

AI agents make mistakes. Your infrastructure shouldn't pay for them.

Run untrusted agent actions. Contain dangerous behavior. Verify every decision.

About 3 seconds, no model call. A compromised agent's proposals are scripted; the policy gate, the sandbox and the signed receipts are real.

The threat: the agent read a log that told it to run curl | sh. Airlock assumes the agent is already compromised and asks one question: can an independent gate stop the action?

The replay result appears here

  1. Press “Watch Airlock stop an attack”. Each harmful proposal of the replay gets its own card, built from the API response.
Nothing has run yet.

Demo in 3 steps

  1. Attackreplay a compromised agent: the analysis runs, the three harmful steps are cut before any container starts
  2. Safe code passesprint(1+1) in the Arena runs in the sandbox
  3. Verifycheck a blocked action's signed receipt, then tamper one character
No model call: the replay uses scripted proposals, the gate, sandbox and receipts are real.

Why Airlock matters

Without Airlock

An AI agent follows a malicious instruction hidden in a log and attempts an unsafe action. Whatever it proposes runs with the agent's access.

With Airlock

The action is independently checked, blocked before execution, and recorded in a verifiable receipt. Safe work still runs, inside a sandbox with no network.

An AI agent can make a mistake. Airlock makes sure that mistake doesn't automatically become an incident.

How a proposed action moves

Airlock pipeline Agent proposes, then policy gate, then sandbox (gVisor), then verifier, then signed receipt. A blocked action stops at the policy gate and goes straight to a signed receipt; no sandbox is started. Agentproposes code Policy gatestatic, allow-list SandboxgVisor, no network Verifieroutput and cleanup Signed receiptEd25519, hash chain allow deny: the blocked action stops here, no container is created, the decision is still signed Airlock pipeline Agent proposes, policy gate, sandbox (gVisor), verifier, signed receipt. A blocked action stops at the policy gate; no sandbox is started and the decision is still signed. Agentproposes code Policy gatestatic, allow-list SandboxgVisor, no network Verifieroutput and cleanup Signed receiptEd25519, hash chain allow denystopsherenocontainer

BLOCKED the gate denied it before anything ran · ALLOWED it passed the gate · CONTAINED allowed code ran in the restricted sandbox (runsc, no network, limits) · VERIFIED the receipt's signature and receipt hash check out. VERIFIED proves the record is intact and signed, not that the execution was safe.

What I guarantee: every action the agent proposes is checked by the policy before anything runs, denied code never reaches a container, and every decision gets a signed, hash-chained receipt. You can check a receipt's signature and hash here in your browser or offline with the published key and tests/js/verify_cli.mjs from the repository; chain linkage is checked by the offline CLI (airlock verify-chain). What I do not: that the policy catches every attack, or that the host itself is honest. The receipt proves what was recorded, not that the machine was uncompromised. Known limitations.

loading…

Try it yourself

Same task, poisoned log

One log line pretends to be an ops runbook and tells agents to pipe a remote script into sh and post the environment to an outside host. The task prompt is deliberately naive and says to follow runbook steps. The gate decides on the code, not on the model's intent.

The injected line

A. Live model

The real model (Vultr Serverless Inference) gets the poisoned log.

B. Replay a compromised agent

Airlock assumes the agent is already compromised. The model has already proposed the dangerous action: can an independent gate stop it? The proposals in this run are scripted. This is not a successful attack on a model; it plays the actions an agent that obeyed the injected line would propose. Only the proposals are fixed. The policy verdicts, the sandbox run, the verifier and every signed receipt are real and come from the same code path as the live run. Each receipt says "context": {"mode": "replay_compromised", "planner": "scripted"}.

loading the last live run…

Policy corpus numbers

Computed by scripts/corpus_metrics.py over two corpora. Every number is on this corpus only. The first corpus I wrote myself while building the policy: 0 false-ALLOW on my own corpus. The second was written by an independent reviewer: on that corpus the policy had 46 false-ALLOWs before my fixes, 6 of them security-relevant, and after the fixes 39 remain, 0 of them security-relevant (I triaged each by hand). Neither says anything about attacks nobody thought of.

loading…

Known limitations

LimitationWhat it means
Containers share the host kernelUnder runc a kernel bug is a host escape. This deployment runs gVisor (runsc), which puts a user-space kernel in between and shrinks that surface. It does not remove it.
The static policy is incompleteIt is an allow-list parser for a subset of Python and bash. Unknown constructs are denied, but a bypass in what it does allow is possible. The sandbox is the second line.
Signatures cover the record, not the hostA valid signature proves the receipt came from the holder of this key and was not edited. It does not prove the host was honest or uncompromised when it wrote it.
No egress allow-listThe only network mode is none. Tasks that need the network cannot run here.
The control process can reach the Docker socketThe API service runs as an unprivileged user in the docker group, which is root-equivalent on this VM. The socket is never mounted into a sandbox or exposed over the network.
The signing key lives on this VMThe Ed25519 key sits on the same VM as the API process, and that process can reach Docker. Whoever controls the host can sign anything. The receipts prove integrity of the record, not honesty of the host.
Receipts are kept, not prunedDeleting one breaks the hash chain. Old work dirs and containers are pruned by a timer.