SDKs & IntegrationsChoosing an integration pattern

Choosing an integration pattern

Choose between the embedded decorator and the REST API for your deployment and identity model.

Two integration paths

AutoPIL has two primary integration paths for Python — the embedded decorator and the REST API. They enforce the same policies and write to the same audit log, but the right choice depends on how your stack is deployed and how user identity flows through your system.

Decision guide

Decision guide:

ScenarioUseWhy
Local development or single-process self-hosted deploymentEmbedded decorator (@guard.protect)No network hop; policy files load directly from disk in the same process
AutoPIL deployed on Render or any remote hostREST API (POST /v1/context/evaluate)The embedded ContextGuard would open its own SQLite/Postgres — separate from the server's. All agents must call the shared server
Service-account style access — one known identity per retrieval functionEmbedded decoratoragent_role and user_id are fixed at decoration time; all calls to that function share the same audit identity
Multi-user app — different end users hit the same retrieval pathREST APIuser_id comes in the request payload per call, so each request gets a distinct identity in the audit log
Polyglot stack (Go, Java, TypeScript, Ruby)REST APIThe embedded SDK is Python-only; any language can call /v1/context/evaluate
Already using LangChain, LlamaIndex, Bedrock, or OpenAI Agents SDKFramework guard for that libraryWraps at the tool or query-engine level without changing your retrieval code
Enforcing governance without touching agent codeAutoPILMiddleware (ASGI)Intercepts every request at the HTTP layer; agents need no changes

How user_id flows

The user_id distinction: user_id identifies who triggered a retrieval in the audit log — it does not affect allow/deny decisions. How it flows differs between the two patterns:

Embedded decoratorREST API
Set atDecoration time — fixed per functionRequest time — varies per call
Good forService accounts, internal agents with a single identityMulti-user apps where attribution matters per request
TradeoffAll calls to the function share one user_id in the audit trailEach call carries its own user_id — more granular audit trail

agent_role works the same way. In both patterns, agent_role is developer-supplied — it declares the identity of the access path, not a runtime claim by the agent. The agent cannot change it. In the decorator, it is fixed at decoration time. In the REST API, it is a declared field in the request payload trusted because the API key is already authenticated.

Side-by-side example

Side-by-side example — the same governance check (analyst accessing financial reports at high sensitivity) written both ways:

from autopil import ContextGuard

guard = ContextGuard(policy_path="policies/", audit_db="autopil.db")

# agent_role and user_id are fixed here — the agent cannot change them
@guard.protect(
    agent_role="analyst",
    user_id="svc-reporting-agent",   # same for every call
    source_id="financial_reports",
    sensitivity_level="high",
)
def retrieve_report(query: str):
    return vectorstore.search(query)
import httpx

def retrieve_report(query: str, user_id: str, session_id: str):
    r = httpx.post(
        "https://your-app.onrender.com/v1/context/evaluate",
        headers={"X-API-Key": AUTOPIL_API_KEY},
        json={
            "agent_role": "analyst",
            "user_id": user_id,           # varies per caller
            "source_id": "financial_reports",
            "sensitivity_level": "high",
            "query": query,
            "session_id": session_id,
        },
        timeout=10,
    )
    r.raise_for_status()
    result = r.json()
    if result["decision"] == "DENY":
        raise PermissionError(result["reason"])
    return vectorstore.search(query)

Never use the embedded decorator against a remote AutoPIL instance. If your AutoPIL server is on Render, calling ContextGuard(audit_db="...") locally opens a separate database — your events will not appear in the shared audit log and policies will not be in sync. Use the REST pattern for any hosted deployment.