Test whether your AI agent respects permission boundaries — before it touches real data.
If you're building an agent that eventually calls real APIs (read emails, delete records, touch a calendar), you don't want to find out it ignores a permission boundary in production. agent-guardrail is a lightweight local mock server: point your agent at it instead of your real backend, define who's allowed to do what in a JSON file, and get a clean 200 or 403 back — with every decision logged to an immutable audit trail.
Every resource, action, and synthetic user permission is defined in policy.json — no code changes needed to model a new API:
{
"synthetic_users": {
"alice": {
"emails": { "read": true, "delete": false },
"records": { "read": true, "delete": false },
"calendar": { "read": true, "write": true }
},
"bob": {
"emails": { "read": false, "delete": false },
"records": { "read": false, "delete": false },
"calendar": { "read": true, "write": false }
}
}
}Point your agent at /api/{resource}/{user_id}/{action} instead of your real API. The server checks the policy and responds accordingly:
- Fail-closed guarantees: Anything not explicitly permitted is denied. Unknown resources, unknown actions, and unknown users all fail closed.
- Strict boolean validation: Policy leaves must be native JSON booleans (
true/false). Coerced strings (e.g."false") or malformed configs fail closed with a503. - Method-to-action binding: Actions bind to standard HTTP verbs (
read->GET,write->POST/PUT,delete->DELETE, or verbs directly). Mismatched methods return403 METHOD_MISMATCH.
git clone https://github.com/shiks2/agent-guardrail.git
cd agent-guardrail
pip install -r requirements.txt
cd src && uvicorn policy_engine:app --reload --port 8080Try it — verified responses from a running instance:
$ curl "http://127.0.0.1:8080/api/emails/alice/read?agent_id=test-bot"
{"user":"alice","resource":"emails","action":"read","status":"simulated success"}
$ curl "http://127.0.0.1:8080/api/emails/bob/read?agent_id=test-bot"
{"detail":"Access denied by sandbox policy"}
$ curl -X DELETE "http://127.0.0.1:8080/api/records/alice/delete?agent_id=test-bot"
{"detail":"Access denied by sandbox policy"}
$ curl "http://127.0.0.1:8080/api/calendar/bob/read?agent_id=test-bot"
{"user":"bob","resource":"calendar","action":"read","status":"simulated success"}Every call above is logged to audit.jsonl with an explicit reason code:
{"timestamp": "2026-09-10T14:30:00Z", "agent": "test-bot", "user": "alice", "resource": "emails", "action": "read", "method": "GET", "decision": "ALLOW", "reason": "POLICY_ALLOW"}
{"timestamp": "2026-09-10T14:30:00Z", "agent": "test-bot", "user": "bob", "resource": "emails", "action": "read", "method": "GET", "decision": "DENY", "reason": "POLICY_DENY"}Inspect and summarize all recorded decisions using the built-in CLI:
# Print a human-readable audit report
python src/cli.py report --audit src/audit.jsonl
# Output structured JSON for automation
python src/cli.py report --json
# Fail CI build if any unauthorized (DENY) attempts occurred
python src/cli.py report --fail-on-denyRun with zero setup via Docker (hardened non-root user with health check and persistent volume):
docker build -t agent-guardrail .
docker run -p 8080:8080 -v guardrail-data:/app/src agent-guardrailAgent Guardrail includes a zero-dependency Python client (GuardrailClient) in src/client.py:
from client import GuardrailClient
client = GuardrailClient(base_url="http://127.0.0.1:8080", agent_id="my-agent-v1")
# Check permissions
response = client.check(user_id="alice", resource="emails", action="read")
if response.allowed:
print("Action authorized:", response.detail)
else:
print("Action blocked:", response.detail)
# CI Assertion Helpers
client.assert_allowed("alice", "emails", "read")
client.assert_denied("bob", "emails", "read")- LangChain Custom Tool Wrapper
- CrewAI / Multi-Agent Role Attribution
- Automated Agent Boundary Conformance CI Test
- Generic, policy-driven ALLOW/DENY engine
- Audit logging with machine-readable reasons (
audit.jsonl) - Fail-closed on unknown resource/action/user
- Strict boolean type validation & fail-closed error handling
- HTTP Method ↔ Action binding with zero-config fallback
- Hardened Docker container
- Audit report CLI with
--fail-on-denyCI gate - Automated GitHub Actions CI workflow
- Example integration with LangChain / CrewAI & Python Client SDK
Issues and PRs welcome! Please ensure all tests pass before submitting (pytest -v).
MIT