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. Full language SDKs available for Go, Java, and TypeScript.
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"
}
A thin REST API wrapper published as @autopil/sdk. Zero runtime dependencies — uses native fetch (Node 18+). Full type coverage.
npm install @autopil/sdk
import { AutoPilClient } from "@autopil/sdk" const client = new AutoPilClient({ baseUrl: "http://localhost:8000", apiKey: process.env.AUTOPIL_API_KEY, }) const result = await client.context.evaluate({ agent_role: "loan_underwriter", source_id: "credit_scores", user_id: "user_001", sensitivity_level: "high", session_id: "sess_abc", }) if (result.decision === "DENY") { throw new Error(result.reason) } // Query audit events const events = await client.audit.listEvents({ agent_role: "loan_underwriter", decision: "DENY", limit: 50, })
stdlib-only — no external dependencies. Uses net/http and encoding/json. Go 1.21+.
go get github.com/vibrantcapital/autopil-go
import "github.com/vibrantcapital/autopil-go/autopil" client := autopil.New("http://localhost:8000", "apl_yourkey") result, err := client.Context.Evaluate(ctx, autopil.EvaluateRequest{ AgentRole: "loan_underwriter", UserID: "user_001", SourceID: "credit_scores", SensitivityLevel: "high", SessionID: sessionID, }) if err != nil { return err } if result.Decision == "DENY" { return fmt.Errorf("access denied: %s", result.Reason) } events, _ := client.Audit.ListEvents(ctx, autopil.ListEventsParams{ AgentRole: "loan_underwriter", Decision: "DENY", Limit: 50, })
Jackson-only. Uses java.net.http.HttpClient — no external HTTP library. Java 17+. Builder pattern throughout. 19 JUnit 5 tests.
<dependency> <groupId>ai.vibrantcapital</groupId> <artifactId>autopil-java</artifactId> <version>0.1.0</version> </dependency>
AutoPILClient client = AutoPILClient.builder() .baseUrl("http://localhost:8000") .apiKey("apl_yourkey") .build(); EvaluateResponse resp = client.context().evaluate( EvaluateRequest.builder() .agentRole("loan_underwriter") .userId("user_001") .sourceId("credit_scores") .sensitivityLevel("high") .sessionId(sessionId) .build() ); if ("DENY".equals(resp.getDecision())) { throw new SecurityException(resp.getReason()); } List<AuditEvent> events = client.audit().listEvents( "loan_underwriter", "DENY", 50 );
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.