Agents can run shell commands, touch files, and call the internet. ActionWall inspects every action before it executes against a YAML policy you control, and returns ALLOW, ASK HUMAN or BLOCK, with a tamper-evident audit trail.
npm install actionwall· MIT · TypeScript · Node ≥ 20
Prompt-injection classifiers judge words. But the damage an agent can do happens through actions, and an action either violates your policy or it doesn't.
A web page, an issue, or a file the agent reads can carry injected instructions. Some get through any classifier. The resulting action is the reliable place to stop them.
rm -rf with the wrong glob, a credential pasted into a tool call, a request to cloud metadata: agents don't need to be malicious to be destructive.
After an incident you need to know exactly what ran, what was blocked, and why. ActionWall logs every decision, hash-chained and verifiable.
Integrate in any tool-calling loop: OpenAI, Anthropic, LangChain, your own framework. If it can build an action object, ActionWall can gate it.
wants to execute an action
rm -rf /project/*
runs six scanners against your policy
severity → verdict, per your thresholds
only if the firewall allows it
Every decision is appended to a hash-chained audit log.
ActionWall doesn't pattern-match the word rm. It expands the target against the real filesystem (read-only, bounded) and counts what would actually be deleted.
Same intent, different verdicts: deleting 5 build artifacts is normal work; deleting 12 project files breaches file_policy.max_bulk_delete. The policy knob is yours; the measurement is the firewall's.
Beyond the bulk limit: protected paths (.env, ~/.ssh/**, .git/**), workspace containment with traversal-proof normalization, SSRF guards for cloud metadata endpoints, credential signatures + entropy detection with automatic redaction, and per-agent tool policies.
The design decisions are documented and defensible. Every one of them is in docs/ARCHITECTURE.md.
If a scanner crashes, the action is blocked. Opening the firewall is always an explicit, greppable policy flag.
Zero network calls, zero command execution inside the firewall. Filesystem access is read-only and bounded.
Deterministic rules, not model calls. Latency your agent's tool loop won't feel.
YAML policies, zod-validated, with a validate command and CI-friendly exit codes (0 / 1 / 3 / 2).
Every decision is a SHA-256 hash-chained record. actionwall log --verify proves the trail is intact.
Heuristics are bypassable; this is a policy gate, not a sandbox. The threat model says exactly where the walls are.
# inspect any action before it runs $ actionwall check "sudo chmod 777 /etc/hosts" $ actionwall check '{"tool":"http.request", "params":{"url":"http://169.254.169.254/"}}' # watch the scripted demo agent $ actionwall demo
// integrate in any tool-calling loop
import { ShieldEngine, loadPolicy, makeAction } from "actionwall";
const engine = new ShieldEngine(loadPolicy());
const decision = engine.check(
makeAction({ tool: "shell",
params: { command: "rm -rf build/*" } })
);
if (decision.verdict === "BLOCK") throw new Error(decision.summary);