Framework guide · CrewAI
CrewAI under Aarmos in 60 seconds.
Keep your existing CrewAI crew exactly as-is. No aarmos import, no framework wrapper, no monkey-patch. Environment variables route every outbound HTTP call through the local aarmos daemon, where the policy gate decides and a signed AVAR receipt is written.
examples/crewai/ in the repo. Mirrored below.0 · Sanity-check your environment
aarmos doctorVerifies daemon reachability, proxy env, LLM keys, and that the workspace has a valid policy bundle.
1 · Start the daemon
aarmos daemon
▸ listening on 127.0.0.1:7681
▸ policy: ./aarmos.json2 · Your existing CrewAI crew — unchanged
# src/agent.py — stock CrewAI. No aarmos imports.
from crewai import Agent, Task, Crew
researcher = Agent(role="Researcher", goal="Answer briefly.",
backstory="You explain in one sentence.",
allow_delegation=False)
task = Task(description="What is a receipt?",
expected_output="One sentence.", agent=researcher)
print(Crew(agents=[researcher], tasks=[task]).kickoff())3 · Run it under Aarmos
aarmos proxy & # start the local runtime (mints a session)
eval "$(aarmos env)" # authenticated HTTPS_PROXY + HTTP_PROXY
python src/agent.py
▸ gate: api.openai.com (verb: communicate) ✓ allowed
▸ AVAR receipt: .aarmos/avar/2026-…json4 · Inspect the receipt
aarmos verify .aarmos/avar/latest.json
✓ signature valid
✓ chain intact
✓ policy match: aarmos.json@sha256:…Or open /audit in the PWA for the same call with hashes, verb, latency, and the policy that allowed it.
5 · Who spawned whom (optional)
A crew is not one agent. The proxy sees the calls a worker makes; it cannot see that the manager spawned that worker — CrewAI keeps that in process memory. The adapter declares each spawn as it happens, so evidence can answer which step of which crew made the call.
# optional — attribution only, never enforcement
from aarmos_crewai import govern
crew = Crew(agents=[researcher], tasks=[task])
govern(crew, invocation_id="nightly-close-2026-08-10")
crew.kickoff()aarmos lineage show nightly-close-2026-08-10
✓ crewai-manager [agent] — declared by the crewai adapter at spawn time
✓ Researcher [subagent] — declared by the crewai adapter at spawn timeWithout the adapter, actors seen in the same run and process may be correlated for readability — shown as a guess, and excluded from the --attributed view an export or receipt uses. Declared edges are attribution; correlation never quietly becomes one.
Why no CA certificate?
The proxy tunnels HTTPS by hostname and never decrypts it, so your existing certificate chain is untouched — no root CA to install, noREQUESTS_CA_BUNDLE or SSL_CERT_FILE to set. The trade-off: receipts from proxied calls are hostname-level. Install an adapter when you want prompt- and argument-level detail.
Honest limits
- CrewAI tools that shell out to native binaries bypass the proxy — declare them as connectors instead of trusting env vars.
- Local function-tools (pure Python callables) do not touch the network and are not gated by this path.
- Streaming responses hash on close; a truncated stream is recorded as truncated.
Interception runs on your device. Tamper-evident, not tamper-resistant against a modified build — see the threat model.