AutoPIL meets you where your agents live — Python microservices, Java Spring Boot, Go services, Node apps, FastAPI middleware, LangChain pipelines, LlamaIndex retrievers, Gemini agents, OpenAI Agents, or AWS Bedrock. Every channel enforces the same policy and writes to the same audit log.
Every channel runs the same policy engine, writes to the same audit log, and stamps a distinct source_type for dashboard visibility.
@guard.protect() decorator — sync, direct embed
@guard.protect_async() — ContextVar safe under asyncio.gather
FastAPI/Starlette HTTP-layer enforcement
Claude Desktop and any MCP-compatible agent
Any language with an HTTP client
Tools, chains, and LCEL pipelines
Query engines and retrievers
Google Gemini function-calling agents
OpenAI Agents SDK function tools
boto3 / aioboto3 invoke_agent wrapper
The primary integration. Embed directly in your agent process — no network hop, no latency overhead. Works with any Python-based agent framework.
pip install autopil
from autopil import ContextGuard, SensitivityLevel guard = ContextGuard( policy_path="policies/", audit_db="autopil.db", ) @guard.protect( agent_role="loan_underwriter", user_id="user_001", source_id="credit_scores", sensitivity_level=SensitivityLevel.HIGH, session_id=session_id, ) def get_credit_score(customer_id: str) -> dict: return credit_db.query(customer_id) # ALLOW — audit event logged, OTEL span emitted score = get_credit_score("cust_abc")
# protect_async — safe under asyncio.gather() @guard.protect_async( agent_role="analyst", user_id="user_002", source_id="reports", sensitivity_level=SensitivityLevel.MEDIUM, session_id=session_id, ) async def fetch_report(query: str) -> list: return await vector_db.asearch(query) results = await asyncio.gather( fetch_report("Q1 revenue"), fetch_report("Q2 margins"), )
Enforce policy at the HTTP layer — before your route handler runs. No changes to your handler code. Shadow mode lets you roll out gradually.
from fastapi import FastAPI from autopil.middleware import AutoPILMiddleware, RouteRule from autopil import ContextGuard, SensitivityLevel guard = ContextGuard(policy_path="policies/") app = FastAPI() app.add_middleware( AutoPILMiddleware, guard=guard, rules=[ RouteRule( path_pattern=r"^/api/credit/.*", agent_role="loan_underwriter", user_id_header="X-User-ID", source_id="credit_scores", sensitivity_level=SensitivityLevel.HIGH, on_deny="reject", # or "log" for shadow mode ), ], )
"reject" — returns HTTP 403 and logs the denial"log" — shadow mode: logs the denial but allows the request throughNative guard subclasses for the five major agent frameworks. Install the matching Python package and wrap with the appropriate guard class.
from autopil.langchain_guard import LangChainGuard from langchain_core.tools import tool guard = LangChainGuard(policy_path="policies/") @tool @guard.protect( agent_role="research_analyst", user_id="u1", source_id="market_data", sensitivity_level=SensitivityLevel.MEDIUM, session_id=session_id, ) def get_market_data(ticker: str) -> dict: return data_api.fetch(ticker) # source_type="langchain" — compatible with LCEL and LangChain agents
Use the REST API from Go, Java, TypeScript, Ruby, PHP, .NET, or any language with an HTTP client.
curl -X POST http://localhost:8000/v1/context/evaluate \ -H "X-API-Key: apl_yourkey" \ -H "Content-Type: application/json" \ -d '{ "agent_role": "loan_underwriter", "user_id": "user_001", "source_id": "credit_scores", "sensitivity_level": "high", "session_id": "sess_abc123" }'
{
"decision": "ALLOW",
"policy_name": "loan_underwriter_policy",
"reason": "all checks passed",
"event_id": "evt_abc123"
}
Use the REST API directly from TypeScript or Node.js via native fetch — no package required. Zero runtime dependencies, Node 18+.
// Native fetch — no package required (Node 18+) const result = await fetch(`${baseUrl}/v1/context/evaluate`, { method: "POST", headers: { "X-API-Key": process.env.AUTOPIL_API_KEY!, "Content-Type": "application/json", }, body: JSON.stringify({ agent_role: "loan_underwriter", source_id: "credit_scores", user_id: "user_001", sensitivity_level: "high", session_id: "sess_abc", }), }).then(r => r.json()) if (result.decision === "DENY") { throw new Error(result.reason) } // Query audit events const events = await fetch( `${baseUrl}/v1/audit/events?agent_role=loan_underwriter&decision=DENY&limit=50`, { headers: { "X-API-Key": process.env.AUTOPIL_API_KEY! } } ).then(r => r.json())
Use the REST API from Go via net/http and encoding/json — no external dependencies. Go 1.21+.
import ( "bytes"; "encoding/json"; "net/http" ) body, _ := json.Marshal(map[string]string{ "agent_role": "loan_underwriter", "user_id": "user_001", "source_id": "credit_scores", "sensitivity_level": "high", "session_id": sessionID, }) req, _ := http.NewRequestWithContext(ctx, "POST", baseURL+"/v1/context/evaluate", bytes.NewReader(body)) req.Header.Set("X-API-Key", apiKey) req.Header.Set("Content-Type", "application/json") resp, _ := http.DefaultClient.Do(req) var result map[string]interface{} json.NewDecoder(resp.Body).Decode(&result) if result["decision"] == "DENY" { return fmt.Errorf("access denied: %v", result["reason"]) }
Use the REST API from Java via java.net.http.HttpClient — no external dependencies. Java 17+.
String payload = String.format(
"""{"agent_role":"%s","user_id":"%s","source_id":"%s","sensitivity_level":"high","session_id":"%s"}""",
agentRole, userId, sourceId, sessionId
);
HttpClient httpClient = HttpClient.newHttpClient();
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create(baseUrl + "/v1/context/evaluate"))
.header("X-API-Key", apiKey)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(payload))
.build();
HttpResponse<String> resp = httpClient.send(req,
HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(resp.body());
if ("DENY".equals(result.get("decision").asText())) {
throw new SecurityException(result.get("reason").asText());
}
Expose AutoPIL governance as native MCP tools for Claude Desktop, GPT-4, Gemini, or any MCP-compatible agent. No code changes in the agent required.
pip install autopil[mcp]
autopil-mcp --policy policies/ --db autopil.db
{
"mcpServers": {
"autopil": {
"command": "autopil-mcp",
"args": ["--policy", "/path/to/policies/", "--db", "/path/to/autopil.db"]
}
}
}
Before accessing any data source, call evaluate_context with: - agent_role, user_id, source_id, sensitivity_level, session_id Only proceed if decision is ALLOW. After retrieval, call record_action with the event_id.
Self-hosted. Every channel runs the same policy engine.