Python runtime for Ari Kernel. Delegates all security decisions and tool execution to the TypeScript sidecar process, providing process-boundary isolation for mediated tool calls.
Python support is sidecar-first by design. This ensures Python agents use the same enforcement authority as the primary Ari Kernel runtime — a single enforcement authority with multi-language clients, not multiple runtimes with drift risk.
The Python runtime uses a sidecar-authoritative enforcement model:
- Python calls
create_kernel()which connects to the TypeScript sidecar over HTTP - Every
execute_tool()/request_capability()call is sent to the sidecar - The sidecar evaluates policy, checks capabilities, tracks taint, runs behavioral rules, executes the tool via its own executors, and logs the audit event
- The sidecar returns the result (or a denial) — the decorated Python function body is not called
This provides:
- Mediation of routed calls — every tool call sent through the kernel is checked by the TypeScript runtime
- Process isolation — Python cannot modify enforcement logic (it lives in a separate process)
- Audit integrity — the sidecar owns the hash-chained audit log
- Full parity — same policy engine, same behavioral rules, same taint tracking as TypeScript
Important: Python code that calls OS APIs directly (e.g., open(), subprocess.run(), httpx.get()) without going through protect_tool or execute_tool is not mediated. Sidecar mode isolates the enforcement state, not the Python process itself.
pip install arikernelStep 1: Start the TypeScript sidecar
pnpm build
node -e "import('@arikernel/sidecar').then(m => m.createSidecarServer({}).listen().then(() => console.log('Sidecar listening on http://localhost:8787')))"
# → listening on http://localhost:8787Step 2: Use from Python
from arikernel import create_kernel, protect_tool
kernel = create_kernel(preset="safe-research")
@protect_tool("file.read", kernel=kernel)
def read_file(path: str) -> str:
# In sidecar mode, this body is NOT called.
# The sidecar's FileExecutor handles the read.
return open(path).read()
@protect_tool("http.read", kernel=kernel)
def fetch_url(url: str) -> str:
# In sidecar mode, this body is NOT called.
# The sidecar's HttpExecutor handles the fetch.
return httpx.get(url).text
read_file(path="./data/report.csv") # ALLOWED — sidecar reads the file
read_file(path="/etc/shadow") # DENIED by sidecar (path constraint)
fetch_url(url="https://example.com") # ALLOWED — sidecar fetches the URLdef my_approval_handler(tool_call: dict, decision: dict) -> bool:
"""Return True to approve, False to deny."""
print(f"Approval requested for {tool_call['toolClass']}.{tool_call['action']}")
return input("Approve? [y/N] ").lower() == "y"
kernel = create_kernel(
preset="safe-research",
on_approval=my_approval_handler,
)create_kernel(preset, principal, on_approval, ...)— connect to the TypeScript sidecar (default)create_kernel(..., mode="local")— local enforcement for dev/testing only (emits warning)@protect_tool("capability.class", kernel=kernel)— decorator to protect a tool functionkernel.execute_tool(tool_class, action, parameters, ...)— direct execution with enforcementkernel.request_capability(capability_class)— request a capability tokenkernel.close()— end session, release sidecar resources- Context manager support (
with create_kernel(...) as kernel:)
ToolCallDenied— raised on policy denialApprovalRequiredError(ToolCallDenied)— raised whenrequire-approvalverdict is denied (no handler or handler returnsFalse)ConnectionError— raised when the TypeScript sidecar is not reachable
| Mode | Usage | Isolation |
|---|---|---|
| Sidecar (default) | create_kernel(preset="safe-research") |
Process boundary for mediated calls — Python code that bypasses the kernel (direct OS API calls) is not mediated |
| Local (dev/testing) | create_kernel(preset="safe-research", mode="local") |
In-process — cooperative enforcement, can be bypassed by Python code |
| High assurance | Sidecar + container egress controls + network policies | Process + OS-level isolation |
There is no silent fallback. If the sidecar is unreachable, create_kernel() raises ConnectionError immediately. It does not fall back to local enforcement.
For development and testing without running the sidecar:
kernel = create_kernel(preset="safe-research", mode="local")
# ⚠️ Emits warning: local enforcement can be bypassed by Python codeLocal mode runs the same policy engine in-process but does not provide process-boundary isolation. It should never be used in production.
The sidecar writes audit logs using the same SQLite schema and SHA-256 hash chain as the TypeScript runtime. Trace and replay with the CLI:
pnpm ari trace --latest --db ./audit.db
pnpm ari replay --latest --verbose --db ./audit.dbSee the main README for full documentation.