Observed since 20 Oct, 22:02 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Action-level firewall for AI agents — intercepts tool calls before execution.
Guardrails AI protects what LLMs say. AgentGate protects what agents do.
AgentGate is an action-level firewall for AI agents. It intercepts every tool call at the Python execution layer — before any side effect occurs. When an agent calls execute_sql("DROP TABLE users"), text-level guardrails don't catch it. AgentGate does.
| Feature | Guardrails AI | NeMo Guardrails | AgentGate |
|---|---|---|---|
| Protects | LLM outputs (text) | Conversational flow | Tool calls (actions) |
| Intercepts at | Text generation | Dialog management | Execution layer |
| SQL injection detection | No | No | Yes — AST analysis |
| SSRF prevention | No | No | Yes — IP/metadata checks |
| Path traversal detection | No | No | Yes — multi-pattern |
| Scope-based policies | No | Partial | Yes — allow-first model |
| Two-tier evaluation | No | No | Static + LLM-as-judge |
| Audit trail | No | Logs | Full Supabase audit log |
| Setup complexity | Moderate | High | One line |
uv add agentgate
# or
pip install agentgate
import agentgate
agentgate.protect_all() # auto-patches LangChain, OpenAI SDK
# Your existing agent code — zero modifications needed
agent.run("Generate the monthly sales report")
That's it. Every tool call your agent makes is now intercepted, evaluated, and logged.
For stronger guarantees, declare what the agent is allowed to do:
with agentgate.scope(
task="Generate the monthly sales report",
allowed_resources=["sales_data", "reports"],
allowed_operations=["read", "aggregate", "write"],
):
agent.run(task)
Define scopes once in agentgate.yaml:
agents:
reporting_agent:
allowed_operations: [read, aggregate, write_report]
allowed_resources: [sales_data, reports_output]
agentgate.protect_all(config="agentgate.yaml")
For functions outside a framework:
@agentgate.guard
def execute_sql(query: str) -> str:
return db.execute(query)
execute_sql("SELECT * FROM users") # ✅ Allowed
execute_sql("DROP TABLE users") # 🛑 FirewallBlockedError
Agent Tool Call
│
▼
┌──────────────────────────────────────────────┐
│ AgentGate Firewall │
│ │
│ ┌─────────────────────────────────────────┐ │
│ │ TIER 1 — Fast Path │ │
│ │ (sync, < 2ms, no API) │ │
│ │ │ │
│ │ 1. Scope check (allowed ops/resources) │ │
│ │ 2. Static analysis: │ │
│ │ • SQL: sqlparse AST → destructive? │ │
│ │ • FS: path traversal patterns │ │
│ │ • HTTP: SSRF / metadata endpoints │ │
│ │ • Rate: sliding window per agent │ │
│ │ │ │
│ │ Clear verdict? ──────► ALLOW or BLOCK │ │
│ │ Ambiguous? ──────────► escalate ↓ │ │
│ └─────────────────────────┬───────────────┘ │
│ │ │
│ ┌─────────────────────────▼───────────────┐ │
│ │ TIER 2 — Semantic Judge │ │
│ │ (async, 100-400ms, gpt-4o-mini) │ │
│ │ │ │
│ │ Separate LLM client (reviewer, not │ │
│ │ participant). Evaluates: │ │
│ │ • Task consistency │ │
│ │ • Blast radius proportionality │ │
│ │ • Action reversibility │ │
│ │ │ │
│ │ → { consistent, confidence, reasoning} │ │
│ └─────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────┐ │
│ │ Audit Logger (async) │ │
│ │ Fire-and-forget → Supabase │ │
│ │ actions + violations tables │ │
│ └─────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────┐ │
│ │ Context Propagation │ │
│ │ agent_id, task_id, user_id, │ │
│ │ action_history (contextvars) │ │
│ └─────────────────────────────────────────┘ │
└──────────────────────────────────────────────┘
│
▼
ALLOW → execute tool BLOCK → FirewallBlockedError
AgentGate uses Python contextvars for thread-safe, async-safe identity tracking:
from agentgate import agent_context
with agent_context(agent_id="report-bot", task_id="run-42", user_id="alice"):
agent.run(task) # all tool calls automatically carry this context
Every intercepted action is logged to Supabase (when configured):
export SUPABASE_URL="https://your-project.supabase.co"
export SUPABASE_KEY="your-service-role-key"
Schema:
actions — every tool call: id, agent_id, task_id, tool_name, payload, verdict, tier_used, reasoningviolations — blocked calls: id, action_id (FK), severity, detailsLogging is async and fire-and-forget — verified to add < 5ms overhead.
CREATE TABLE actions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
created_at TIMESTAMPTZ DEFAULT now(),
agent_id TEXT,
task_id TEXT,
user_id TEXT,
tool_name TEXT NOT NULL,
payload JSONB DEFAULT '{}',
verdict TEXT NOT NULL,
policy_name TEXT,
severity TEXT DEFAULT 'low',
tier_used INTEGER DEFAULT 1,
reasoning TEXT
);
CREATE TABLE violations (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
action_id UUID REFERENCES actions(id),
created_at TIMESTAMPTZ DEFAULT now(),
severity TEXT DEFAULT 'low',
details JSONB DEFAULT '{}'
);
CREATE INDEX idx_actions_agent ON actions(agent_id);
CREATE INDEX idx_actions_task ON actions(task_id);
CREATE INDEX idx_actions_created ON actions(created_at DESC);
CREATE INDEX idx_violations_action ON violations(action_id);
CREATE INDEX idx_violations_severity ON violations(severity);
BaseTool._run/_arun) and OpenAI SDK (chat.completions.create). CrewAI, AutoGen, and other frameworks are not yet supported.stream=True).postgres_changes). The schema is already designed for this — no migration needed.# Install with dev dependencies
make dev
# Run tests
make test
# Run timing tests specifically
make test-timing
# Lint
make lint
# Format
make format
MIT
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.1.0 | 6 Apr 2026 | 16 |
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 22:02 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:1cd96920e25ba088f984e524b163617762a9fc54b827ac1a47629b572c8eb31f