Show HN: Vigil – Zero-dependency safety guardrails for AI agent tool calls
3 comments
Nice approach. The "don't trust an LLM to guard another LLM" principle is sound for tool-call safety specifically, where the threat model is well-defined (destructive commands, SSRF, path traversal, etc.) and pattern matching gives you deterministic guarantees.
Where this gets interesting is at the boundary between tool-call safety and output quality. Vigil solves the "agent tries to rm -rf /" problem, but there's a whole class of failures where the agent makes safe tool calls that produce wrong results - querying the right database but misinterpreting results, calling an API correctly but hallucinating the summary it returns to the user, following the workflow but giving a factually incorrect final answer.
For that layer, deterministic rules don't scale because you'd need rules for every possible factual claim. That's where LLM-based evaluation actually makes sense - not as the guard for tool execution, but as the quality check on the final output. Think of it as two layers:
1. Vigil-style - deterministic, sub-millisecond checks on tool calls and actions (is this safe to execute?)
2. Semantic evaluation - LLM-based scoring on the output (is this correct, complete, and grounded in the provided context?)
The combination of both is what production agent systems actually need. We've been building the second layer at DeepRails (evaluate + auto-remediate when quality checks fail), and something like Vigil would complement it well as the first layer.
One thought on false positives: have you considered a "soft block" mode where flagged-but-borderline calls get routed through human approval rather than hard-blocked? For long-running agent tasks, a hard block with no fallback can leave workflows in broken states.
Where this gets interesting is at the boundary between tool-call safety and output quality. Vigil solves the "agent tries to rm -rf /" problem, but there's a whole class of failures where the agent makes safe tool calls that produce wrong results - querying the right database but misinterpreting results, calling an API correctly but hallucinating the summary it returns to the user, following the workflow but giving a factually incorrect final answer.
For that layer, deterministic rules don't scale because you'd need rules for every possible factual claim. That's where LLM-based evaluation actually makes sense - not as the guard for tool execution, but as the quality check on the final output. Think of it as two layers:
1. Vigil-style - deterministic, sub-millisecond checks on tool calls and actions (is this safe to execute?)
2. Semantic evaluation - LLM-based scoring on the output (is this correct, complete, and grounded in the provided context?)
The combination of both is what production agent systems actually need. We've been building the second layer at DeepRails (evaluate + auto-remediate when quality checks fail), and something like Vigil would complement it well as the first layer.
One thought on false positives: have you considered a "soft block" mode where flagged-but-borderline calls get routed through human approval rather than hard-blocked? For long-running agent tasks, a hard block with no fallback can leave workflows in broken states.
Author here, happy to answer any questions.
Some context on why we built this: you might have seen the post earlier this week about someone building a file recovery tool after Claude Code rm -rf'd their Obsidian vault through a symlink. We had similar near-misses running our own agent swarm, agents curling cloud metadata endpoints, attempting path traversal, executing destructive commands during "cleanup" steps. We kept adding one-off guards and eventually realized this should be a proper library.
The main design choice was making it deterministic rather than using an LLM to review tool calls. An LLM guarding another LLM felt like asking the fox to guard the henhouse. Pattern matching is boring, but it's fast, predictable, and works offline.
Happy to hear about false positives, missing threat categories, or use cases where the rule set is too aggressive. That's the main thing we want to calibrate for v0.2.
Some context on why we built this: you might have seen the post earlier this week about someone building a file recovery tool after Claude Code rm -rf'd their Obsidian vault through a symlink. We had similar near-misses running our own agent swarm, agents curling cloud metadata endpoints, attempting path traversal, executing destructive commands during "cleanup" steps. We kept adding one-off guards and eventually realized this should be a proper library.
The main design choice was making it deterministic rather than using an LLM to review tool calls. An LLM guarding another LLM felt like asking the fox to guard the henhouse. Pattern matching is boring, but it's fast, predictable, and works offline.
Happy to hear about false positives, missing threat categories, or use cases where the rule set is too aggressive. That's the main thing we want to calibrate for v0.2.
Vigil is a deterministic rule engine that inspects AI agent tool calls before they execute. 22 rules across 8 threat categories: destructive shell commands, SSRF, path traversal, SQL injection, data exfiltration, prompt injection, encoded payloads, and credential exposure. It's not an LLM wrapper — we don't trust an LLM to guard another LLM. Pure pattern matching, zero dependencies, <2ms per check, works completely offline.
npm install vigil-agent-safety
import { checkAction } from 'vigil-agent-safety'; const result = checkAction({ agent: 'my-agent', tool: 'exec', params: { command: 'rm -rf /' }, }); // result.decision → "BLOCK" // result.reason → "Destructive command pattern" // result.latencyMs → 0.3
It plugs into MCP servers, LangChain tool chains, Express middleware, or anything else. MIT licensed, no API keys, no network calls, no telemetry.
This is v0.1 — probably too aggressive for some use cases. Next up is a YAML policy engine (v0.2) and an MCP proxy. We'd love feedback on the rule set, false positive experiences, and threat categories we're missing.
GitHub: https://github.com/hexitlabs/vigil