Guardian
Deterministic security sidecar for AI agent frameworks
drop-in protection against prompt injection, tool poisoning, capability abuse
What it is
Guardian is a deterministic security sidecar for AI agent frameworks. It runs as a separate FastAPI service in a Docker container. Every tool invocation in your agent stack POSTs to Guardian's /check endpoint before executing. Guardian runs 7 checks in sub-5ms and returns allow or deny.
The checks are deterministic — no LLM in the hot path — so latency is predictable, cost is zero, and adversarial robustness is high.
The 7 checks
1. Tool revocation list
Known-bad tool IDs. Instant deny.
2. Hash validation
Live tool code hashed and compared to registered hash. Catches supply-chain tool tampering.
3. Capability boundary
Tool's required capability must be in the task's authorized scope. Stops capability creep.
4. Destructive pattern detection
rm -rf /, DROP TABLE, fork bombs, pipe-to-shell, cloud metadata endpoints. Extensible.
5. Sequence contracts
Some tool sequences have implicit ordering. delete_file must follow read_file. Enforced.
6. Ed25519 signature verification
Every registered tool has a cryptographic signature. Verification catches unauthorized tool registration.
7. Adaptive threat rules
Operator-defined rules hot-reloaded every 10 seconds. Novel patterns go live without redeploying.
Why a separate sidecar
Three reasons Guardian is a separate process rather than a Python library imported into the framework:
- Crash isolation. A bug in Guardian shouldn't take down the agent.
- Framework independence. Designed to drop into any agent framework via HTTP — LangChain, LangGraph, AutoGen, CrewAI, custom. Guardian doesn't care which.
- Hot-reloadable rules. New rules in
threat_rulestable go live within 10 seconds without restarting any agent process.
Drop-in usage
import httpx
GUARDIAN_URL = "http://localhost:9766"
async def guarded_tool_call(tool_name, args, task_context):
response = await httpx.AsyncClient().post(
f"{GUARDIAN_URL}/check",
json={
"tool_name": tool_name,
"task_id": task_context.task_id,
"user_id": task_context.user_id,
"capability_scope": task_context.scope,
"args": args,
"code_hash": get_tool_hash(tool_name),
},
)
decision = response.json()
if not decision["allow"]:
raise PermissionError(decision["reason"])
return await actually_call_tool(tool_name, args)
That's the entire integration. Plug Guardian into any framework the same way.
Status
Install
pip install legionforge-guardian
Or pull the Docker image:
docker pull legionforge-guardian:latest
Full deployment walkthrough in the Guardian docs.
Read more
- Architecture — sidecar layout, request lifecycle, rule storage
- Checks — detail on each of the 7 checks
- Deployment — docker-compose, env vars, health probes, metrics