Agent Guardrail — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Agent Guardrail (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
<!-- mcp-name: io.github.JarvisOnM4/agent-guardrail -->
Action-level governance for AI agents — control what they DO, not what they SAY.
AI agents are getting tool access. They can run shell commands, make API calls, read files, spend money. But most "guardrails" only filter what agents say — not what they do.
Real incidents:
You need action-level control. Not output filtering.
Agent Framework --> Agent Guardrail --> {allow, deny, require_approval}
--> Flight Recorder logs everythingZero dependencies. Python stdlib only. SQLite for storage.
pip install agent-guardrail
# Register an agent
agent-guardrail register "my-research-agent" --framework langchain
# Apply the moderate policy template
agent-guardrail apply-template moderate <agent-id>
# Test it
agent-guardrail eval <agent-id> bash --target /workspace/test.sh # -> allow
agent-guardrail eval <agent-id> bash --target /etc/shadow # -> deny
agent-guardrail eval <agent-id> sudo # -> denyfrom agent_guardrail import GuardrailStore, PolicyEngine, DEFAULT_POLICIES
# Initialize
store = GuardrailStore() # ~/.agent-guardrail/guardrail.db
engine = PolicyEngine(store)
# Register agent
agent = store.register_agent("my-agent", framework="langchain")
# Apply policy template
store.save_policy({
"name": "moderate",
"agent_id": agent["id"],
"rules": DEFAULT_POLICIES["moderate"]["rules"],
})
# Evaluate actions
decision = engine.evaluate(agent["id"], "bash", target="/workspace/run.sh")
# -> PolicyDecision(decision="allow", risk_score=0.7)
decision = engine.evaluate(agent["id"], "bash", target="/etc/shadow")
# -> PolicyDecision(decision="deny", reason="Target '/etc/shadow' is denied...")
# Evaluate + record to flight recorder
decision = engine.evaluate_and_record(
agent_id=agent["id"],
action_type="api_call",
tool_name="openai_chat",
cost_usd=0.05,
session_id="session-123",
)from agent_guardrail import GuardrailStore, PolicyEngine
class GuardrailCallback:
"""Drop into any LangChain agent as a callback handler."""
def __init__(self, agent_id, db_path=None):
self._engine = PolicyEngine(GuardrailStore(db_path=db_path))
self.agent_id = agent_id
def on_tool_start(self, serialized, input_str, **kwargs):
decision = self._engine.evaluate_and_record(
agent_id=self.agent_id,
action_type="tool_call",
tool_name=serialized.get("name"),
target=input_str[:200],
)
if decision.decision == "deny":
raise PermissionError(f"Guardrail: {decision.reason}")from agent_guardrail import GuardrailStore, PolicyEngine
def make_guardrail(agent_id, db_path=None):
engine = PolicyEngine(GuardrailStore(db_path=db_path))
def check(task_output):
decision = engine.evaluate_and_record(
agent_id=agent_id, action_type="task_output",
target=str(task_output)[:200],
)
if decision.decision == "deny":
return (False, f"Blocked: {decision.reason}")
return (True, task_output)
return check
# task = Task(description="...", guardrail=make_guardrail("agent-id"))from agent_guardrail import GuardrailStore, PolicyEngine
import functools
def guardrail(agent_id, action_type="function_call", db_path=None):
engine = PolicyEngine(GuardrailStore(db_path=db_path))
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
target = str(args[0])[:200] if args else None
decision = engine.evaluate_and_record(
agent_id=agent_id, action_type=action_type,
tool_name=func.__name__, target=target,
)
if decision.decision == "deny":
raise PermissionError(f"Guardrail: {decision.reason}")
return func(*args, **kwargs)
return wrapper
return decorator
@guardrail("my-agent", action_type="bash")
def run_command(cmd):
...The library is for humans. The API is for agents.
An orchestrator running 5 sub-agents doesn't pip install — it calls an endpoint.
# Start the proxy server
pip install agent-guardrail[proxy]
guardrail-proxy --port 8300 --admin-key YOUR_ADMIN_KEY# Register an agent (admin)
curl -X POST http://localhost:8300/v1/agents \
-H "X-Admin-Key: YOUR_ADMIN_KEY" \
-d '{"name": "research-agent", "framework": "crewai"}'
# Evaluate an action (agent)
curl -X POST http://localhost:8300/v1/evaluate \
-H "X-API-Key: gw_agent_key_here" \
-d '{
"agent_id": "...",
"action_type": "bash",
"tool_name": "shell",
"target": "/etc/shadow",
"cost_usd": 0.0
}'
# -> {"decision": "deny", "reason": "Target denied...", "risk_score": 0.7}Full API docs at http://localhost:8300/docs (Swagger UI).
Free tier included. Pay with Bitcoin when you need more.
| Tier | Evaluations | Price | Per Eval |
|---|---|---|---|
| Free | 100/day per agent | $0 | $0 |
| Starter | 1,000 | $10 | $0.010 |
| Growth | 5,000 | $40 | $0.008 |
| Scale | 25,000 | $150 | $0.006 |
Credits are prepaid and never expire. Admin-authenticated requests bypass billing entirely.
How it works:
# Check your balance
curl http://localhost:8300/v1/billing/balance \
-H "X-API-Key: gw_your_agent_key"
# Buy credits (returns a BTC address + amount)
curl -X POST http://localhost:8300/v1/billing/checkout \
-H "X-API-Key: gw_your_agent_key" \
-d '{"pack_id": "pack_1000"}'
# -> {"btc_address": "bc1q...", "amount_btc": 0.00015, "amount_satoshi": 15000, ...}
# Pay the BTC address -> webhook confirms -> credits granted automaticallyWhen free tier is exhausted and no credits remain, /v1/evaluate returns 402 Payment Required with a link to available packs.
Self-hosted billing: Set BLOCKONOMICS_API_KEY and BLOCKONOMICS_WEBHOOK_SECRET environment variables. Without these, billing is disabled and all evaluations proceed without metering (backward compatible).
{
"tool_allowlist": ["read_file", "write_file"], # Only these tools allowed
"tool_denylist": ["sudo", "rm", "delete*"], # These tools always denied
"target_allowlist": ["/workspace/*"], # Only these targets allowed
"target_denylist": ["/etc/*", "*.env", "*.key"], # These targets always denied
"network_allowlist": ["api.openai.com"], # Allowed network targets
"network_denylist": ["*"], # Denied network targets
"spend_cap_daily_usd": 25.0, # Daily spend limit
"spend_cap_total_usd": 500.0, # Lifetime spend limit
"require_approval": ["bash", "install"], # Human approval required
"risk_threshold": 0.8, # Auto-approval gate
}Patterns support glob matching (*, ?, [abc]).
Kill switch? ──deny──> DENY
|
Agent enabled? ──no──> DENY
|
Spend cap? ──exceeded──> DENY
|
Tool denylist? ──match──> DENY
|
Target denylist? ──match──> DENY
|
Approval required? ──match──> REQUIRE_APPROVAL
|
Risk threshold? ──exceeded──> REQUIRE_APPROVAL
|
Tool allowlist? ──not in list──> DENY
|
Target allowlist? ──not in list──> DENY
|
DEFAULT ──> ALLOW+-------------------+ +------------------+ +-----------------+
| Agent Framework |---->| Billing Check |---->| Policy Engine |
| (LangChain, | | (free tier / | | (evaluate) |
| CrewAI, custom) | | credits) | +-----------------+
+-------------------+ +------------------+ |
| v
| +------------------------+
402 if empty | Decision: |
| allow / deny / |
| require_approval |
+------------------------+
|
v
+-----------------+
| Flight Recorder|
| (SQLite) |
+-----------------+
+-------------------+ +------------------+
| BTC Payment |---->| Blockonomics |
| (checkout) | | (xpub-derived |
+-------------------+ | addresses) |
+------------------+
|
webhook (status=2)
|
v
+------------------+
| Credit Grant |
| (billing_ledger)|
+------------------+| Feature | Agent Guardrail | Guardrails AI | NeMo Guardrails | DIY |
|---|---|---|---|---|
| Action-level control | Yes | No (output only) | No (dialogue only) | Manual |
| Spend caps | Yes | No | No | Manual |
| Kill switch | Yes | No | No | Manual |
| Flight recorder | Yes | No | No | Manual |
| Pay-per-eval billing | Yes (BTC) | No | No | Manual |
| Zero dependencies | Yes | No (many) | No (many) | Varies |
| Framework agnostic | Yes | LangChain-focused | LangChain-focused | Yes |
| Hosted API | Yes | Cloud only | No | Manual |
agent-guardrail agents # List registered agents
agent-guardrail register "name" # Register a new agent
agent-guardrail kill <agent_id> # Emergency kill switch
agent-guardrail unkill <agent_id> # Revoke kill switch
agent-guardrail policies # List policies
agent-guardrail apply-template <template> <agent_id>
agent-guardrail actions [--agent X] [--decision deny]
agent-guardrail replay <session_id> # Session replay
agent-guardrail approvals # Pending approvals
agent-guardrail approve <id> # Approve action
agent-guardrail deny <id> # Deny action
agent-guardrail eval <agent_id> <type> [--target X] [--cost 0.5]
agent-guardrail stats # Statistics| Variable | Default | Purpose |
|---|---|---|
GUARDRAIL_DB | ~/.agent-guardrail/guardrail.db | SQLite database path |
GUARDRAIL_LOG_DIR | ~/.agent-guardrail/logs | CLI log directory |
GUARDRAIL_ADMIN_KEY | (none) | Admin API key for proxy |
BLOCKONOMICS_API_KEY | (none) | Blockonomics Store API key (enables billing) |
BLOCKONOMICS_WEBHOOK_SECRET | (none) | Secret for webhook verification |
GUARDRAIL_BILLING_ENABLED | true | Set false to disable billing even with API key |
MIT
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.