README
¶
agent-tool-firewall
Default-deny policy gateway for LLM and agent tool calls.
agent-tool-firewall is a lightweight HTTP service that sits between your AI agent/LLM and the tools it can invoke. Every tool call is evaluated against a YAML policy before execution. If the policy says no, the call is blocked and audit-logged.
Why
LLMs and AI agents increasingly call external tools (file I/O, shell commands, APIs). Without a policy layer, a prompt injection or jailbreak can escalate to arbitrary code execution. agent-tool-firewall enforces default-deny: tools must be explicitly allowlisted before they can run.
Use cases
- Local AI assistants (Claude, GPT, open-source LLMs)
- MCP server gateways
- RAG pipelines with tool access
- Desktop copilots
- CI/CD agent sandboxes
- Any system where an LLM invokes tools on behalf of a user
Features
| Feature | Description |
|---|---|
| Default-deny policy | Tools blocked unless explicitly allowed |
| Path allowlisting | Filesystem access restricted to permitted directories |
| Traversal protection | Catches ../, null bytes, symlink escapes |
| Argument filtering | Block dangerous patterns in tool arguments |
| Rate limiting | Sliding-window rate limiter (configurable RPM) |
| Structured audit log | JSONL audit trail for every decision |
| Hot reload | Reload policy without restart (POST /v1/reload) |
| Bearer token auth | Optional service-to-service authentication |
| Zero dependencies | Single static binary, only needs a policy YAML file |
Quick start
1. Write a policy
# policy.yaml
version: 1
tools:
default: "deny"
rate_limit:
requests_per_minute: 120
allow:
- name: "filesystem.read"
paths_allowlist:
- "/home/user/documents/**"
paths_denylist:
- "/etc/shadow"
- "/etc/passwd"
max_arg_length: 4096
- name: "web.search"
args_blocklist:
- "password"
- "secret"
deny:
- name: "shell.exec"
- name: "process.spawn"
2. Run
# From source
go build -o agent-tool-firewall .
POLICY_PATH=./policy.yaml ./agent-tool-firewall
# With Docker/Podman
podman build -t agent-tool-firewall .
podman run -v ./policy.yaml:/etc/secure-ai/policy/policy.yaml:ro \
-p 8475:8475 agent-tool-firewall
3. Evaluate a tool call
curl -s -X POST http://127.0.0.1:8475/v1/evaluate \
-H "Content-Type: application/json" \
-d '{"tool":"filesystem.read","params":{"path":"/home/user/documents/notes.txt"}}' | jq .
{ "allowed": true }
curl -s -X POST http://127.0.0.1:8475/v1/evaluate \
-H "Content-Type: application/json" \
-d '{"tool":"shell.exec","params":{"cmd":"rm -rf /"}}' | jq .
{ "allowed": false, "reason": "tool is explicitly denied" }
API
| Endpoint | Method | Auth | Description |
|---|---|---|---|
/health |
GET | No | Health check + request counters |
/v1/evaluate |
POST | No | Evaluate a tool call against policy |
/v1/stats |
GET | No | Aggregated security statistics |
/v1/reload |
POST | Bearer | Hot-reload the policy file |
POST /v1/evaluate
Request:
{
"tool": "filesystem.read",
"params": {
"path": "/vault/user_docs/readme.txt"
}
}
Response:
{
"allowed": true
}
Or when denied:
{
"allowed": false,
"reason": "path not in allowlist"
}
Configuration
All configuration is via environment variables:
| Variable | Default | Description |
|---|---|---|
BIND_ADDR |
127.0.0.1:8475 |
Listen address |
POLICY_PATH |
/etc/secure-ai/policy/policy.yaml |
Path to YAML policy file |
AUDIT_LOG_PATH |
/var/lib/secure-ai/logs/tool-firewall-audit.jsonl |
Audit log output |
SERVICE_TOKEN_PATH |
/run/secure-ai/service-token |
Bearer token file for /v1/reload |
Policy reference
See examples/policy.yaml for a fully annotated example.
Evaluation order
- Rate limit -- reject if over budget
- Deny list -- explicit denials always win
- Allow list -- tool must be listed (in default-deny mode)
- Argument validation -- length limits, blocked patterns
- Path security -- clean, resolve, check denylist, check allowlist
Path matching
/vault/user_docs/**-- recursive match (everything under the directory)- Paths are canonicalized (
filepath.Clean+filepath.Abs) before matching ../traversal and null-byte injection are caught and rejected
Hardening
When deploying in production, consider:
- Systemd sandboxing: See deploy/systemd/ for a hardened unit file with
DynamicUser=yes,PrivateNetwork=yes,MemoryDenyWriteExecute=yes, and syscall filtering. - Seccomp profile: See deploy/seccomp/ for a strict seccomp profile that blocks exec syscalls.
- Service token: Set
SERVICE_TOKEN_PATHto require Bearer auth on the reload endpoint.
Integration with SecAI OS
agent-tool-firewall is used as a core component of SecAI OS, a bootable local-first AI appliance. In that context it runs as a systemd service with strict sandboxing, seccomp filtering, and no network access.
License
Apache-2.0. See LICENSE.
Documentation
¶
There is no documentation for this package.