Prerequisites
- Python 3.10 or higher
- AgentGate server running (self-hosted — MIT licensed)
- An API key (or run in development mode without one)
1. Installation
pip install agentgate-pdp
To run the AgentGate server locally:
git clone https://github.com/ElamOlame31/agentgate-public cd agentgate-public pip install -r requirements.txt python run.py
2. Register your agent
Registration declares the agent's identity, purpose, and authorized scope. AgentGate uses this declaration to verify every subsequent action. The declared_purpose string is embedded at registration and compared against every action via cosine similarity.
from agentgate import AgentGate
gate = AgentGate("http://localhost:8000", api_key="your-key")
# Register the agent with its declared scope
gate.register(
agent_id="report_bot_001",
name="ReportBot",
declared_purpose="Read and summarize quarterly business reports for the executive team",
authorized_resources=["/reports/*", "/documents/public/*"],
authorized_actions=["read", "search"],
delegation_depth=0, # 0 = not a sub-agent
processes_external_content=False,# True = enable prompt injection scanning
requires_human_approval=False, # True = always ESCALATE to human
)4. LangChain integration
AgentGateToolkit wraps your LangChain tools transparently. The agent framework sees normal LangChain tools — but every call is intercepted.
from integrations.langchain_agentgate import AgentGateToolkit
from langchain_core.tools import tool
from langchain_anthropic import ChatAnthropic
from langgraph.prebuilt import create_react_agent
# Define your tools as normal
@tool
def read_document(path: str) -> str:
"""Read a document from the company file system."""
return open(path).read()
@tool
def list_documents(directory: str) -> str:
"""List all documents in a directory."""
import os
return str(os.listdir(directory))
# AgentGateToolkit registers the agent AND wraps tools in one call
toolkit = AgentGateToolkit(
agentgate_url="http://localhost:8000",
agent_id="langchain_report_bot",
name="LangChainReportBot",
declared_purpose="Read and summarize quarterly business reports for the executive team",
authorized_resources=["/documents/*"],
authorized_actions=["read", "search"],
api_key="your-key",
)
# wrap() returns drop-in replacements — every call goes through AgentGate
safe_tools = toolkit.wrap([read_document, list_documents])
llm = ChatAnthropic(model="claude-haiku-4-5-20251001", max_tokens=512)
agent = create_react_agent(llm, safe_tools)
# Run the agent — tool calls are intercepted transparently
result = agent.invoke({
"messages": [{"role": "user", "content": "Summarize Q3 and Q4 reports"}]
})5. AutoGen integration
# AutoGen integration — similar pattern
from integrations.autogen_agentgate import AgentGateToolkit as AutoGenToolkit
toolkit = AutoGenToolkit(
agentgate_url="http://localhost:8000",
agent_id="autogen_bot_001",
name="AutoGenResearchBot",
declared_purpose="Research and summarize public financial reports",
authorized_resources=["/public/*"],
authorized_actions=["read", "search"],
api_key="your-key",
)
# Wrap your AutoGen tools the same way6. Output sanitization
AgentGate scans content your agents receive — from users, tools, or external APIs — before the agent processes it. Credentials, PII, and exfiltration URLs are redacted in-place. Prompt injection patterns in tool responses trigger a hard block.
# Scan any string — user input, tool response, email body, etc.
scan = gate.scan(content)
print(scan["level"]) # "clean" | "injection" | "suspicious"
print(scan["evidence"]) # list of matched patterns
print(scan["redacted"]) # sanitized version of content (PII/credentials replaced)
if scan["level"] == "injection":
raise ValueError(f"Injection attempt blocked: {scan['evidence']}")
# For MCP (Model Context Protocol) tool-calling agents, route tool traffic
# through the AgentGate MCP proxy — it intercepts tool responses before
# the agent processes them. Configure your MCP client to use:
# http://localhost:8000/mcp (instead of the upstream MCP server URL)
# AgentGate forwards permitted requests and blocks INSTRUCTION_TAG / IMPERATIVE_INJECT patterns.What gets caught
API keys, passwords, tokens embedded in tool responses
Emails, SSNs, credit card numbers matched via regex
URLs that look like exfiltration endpoints
Prompt injection patterns hidden inside tool output
7. Quarantine management
When an agent is quarantined (automatically by kill chain detection, or manually via the dashboard), all its requests are denied until released. Quarantine also propagates contagion penalties to delegation neighbors. These REST endpoints let you query and manage quarantine state programmatically.
import requests
BASE = "http://localhost:8000"
HEADERS = {"X-API-Key": "your-key"}
# Check agent status
status = requests.get(f"{BASE}/agents/report_bot_001/status", headers=HEADERS).json()
print(status["quarantined"]) # True | False
print(status["attack_flags"]) # ["KILL_CHAIN_DETECTED", ...]
print(status["trust_score"]) # current composite score
# Manually quarantine an agent (admin action)
requests.post(f"{BASE}/agents/report_bot_001/quarantine", headers=HEADERS)
# Release from quarantine
requests.delete(f"{BASE}/agents/report_bot_001/quarantine", headers=HEADERS)
# View active contagion records (penalties propagated from neighbors)
contagion = requests.get(f"{BASE}/contagion", headers=HEADERS).json()
# [{"agent_id": "report_bot_001", "direction": "from_parent", "penalty": 30.0, "expires_in": 2847}, ...]
# Clear contagion penalties from a specific source agent
requests.post(f"{BASE}/agents/compromised_parent/contagion/clear", headers=HEADERS)
# Merkle audit trail — verify a specific decision record
proof = requests.get(f"{BASE}/audit/inclusion-proof/{{record_id}}", headers=HEADERS).json()
print(proof["merkle_root"]) # SHA-256 root hash
print(proof["proof_path"]) # O(log n) hashes for verificationException reference
AgentGateDeniedRaised when decision is DENY (if raise_on_deny=True). Contains action, resource, explanation.
AgentGateEscalatedRaised when decision is ESCALATE (if raise_on_escalate=True).
AgentGateNotRegisteredRaised if .authorize() is called before .register().
AgentGatePendingRaised when decision is PENDING and auto_resolve_pending=False.
AgentGateUnavailableRaised if the AgentGate server is unreachable.
Full documentation, changelog, and source code on GitHub.
ElamOlame31/agentgate-public