Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Self-hosting the open-source stack

Agent Assembly is open source. You can self-host it yourself — stand the infrastructure up, run it, and maintain it — using the sample Docker Compose stack in examples/docker-compose/. This page is the quick path for developers: it shows the infrastructure architecture (which containers exist, who each is for, and what each does), the exact configuration, and how to bring it up.

“Open source” here means scope, not a crippled build. Self-hosting runs the components that live in this open-source repository. The hosted SaaS edition additionally runs everything for you as a managed, multi-tenant service and adds the cloud/enterprise control-plane features that live outside this repo (managed persistence, SSO, compliance reporting). Nothing here is deliberately feature-limited — the example simply starts with the components that already ship a container image today.

Infrastructure architecture

The full self-host topology is a short, end-to-end chain. Operators work in the dashboard; the dashboard reads everything through the REST API (aa-api); the API fronts the gateway (the brain), which evaluates policy and saves governance records to persistence; and your agents run co-located with an aa-runtime enforcement sidecar, which checks the actions it receives with the gateway. So the very actions your agents take are recorded in persistence and surface back in the dashboard:

you ⇄ dashboard ⇄ aa-api ⇄ aa-gateway ⇄ persistence ⇆ aa-runtime ⇄ your agents

flowchart TB
    user(["Operator — you, in a browser"])

    subgraph present["Observe and manage"]
        dash["dashboard<br/>single container · React / Vite"]
        api["aa-api<br/>REST / OpenAPI :7700"]
    end

    gw["aa-gateway<br/>registry · policy · budgets · audit<br/>gRPC :50051"]
    db[("persistence — you run and manage<br/>Postgres / TimescaleDB + cache")]

    subgraph workload["Your workload — agent + program, co-located"]
        agent["your agent(s)"]
        rt["aa-runtime<br/>enforcement sidecar · :8080"]
    end

    user -->|HTTPS| dash
    dash <-->|HTTP / WS :7700| api
    api <-->|read model| gw
    gw <-->|audit and state| db
    agent <-->|IPC over UDS socket| rt
    rt -->|CheckAction gRPC :50051| gw
    gw -->|Allow / Deny| rt
    gw -->|save governance records| db

Two things to read from it:

  • The observability loop. Your agents + aa-runtime produce the governance data (decisions, audit, budget usage); the gateway persists it; the dashboard reads it back through the API. That is how what your agents do shows up on screen.
  • What runs where. The dashboard is a single container; persistence is a standard datastore you run and manage (e.g. Postgres / TimescaleDB); the gateway + API are the control plane; and each agent runs next to its own aa-runtime sidecar, sharing a Unix-domain socket.

Containers — for whom, for what

ContainerImage / build todayFor whomFor what
dashboardbuild from source (pnpm --dir dashboard build); image pendingoperatorsSingle-container web UI to observe governance and manage agents, policies and budgets — reads everything via the REST API.
aa-apibuild from source (cargo build -p aa-api); image pendingoperators (via dashboard) + toolsThe REST / OpenAPI surface on :7700 the dashboard reads; fronts the gateway read model.
aa-gatewaybuild from source (cargo build -p aa-gateway); image pendingthe deploymentThe brain — registry, policy evaluation, budgets, audit; decides each action and saves governance records to persistence. gRPC :50051.
persistenceyou run / manage a standard postgres / timescaledb imagethe deploymentDurable audit history + state that the dashboard displays.
aa-runtimeghcr.io/ai-agent-assembly/aa-runtime:latest (pulled)every agentEnforcement sidecar co-located with the agent — the authoritative chokepoint that checks each action with the gateway. Serves health/metrics on :8080.
your agent(s)your imageyouThe workload being governed — runs beside its runtime, sharing the UDS socket.
aa-proxy (optional)build from aa-proxy/Dockerfile (proxy profile)teams wanting code-free egress controlMitM-intercepts outbound HTTPS to apply network-egress policy without touching agent code.

Everything above is open source in this repository. Today aa-runtime ships a published image and aa-proxy builds from a Dockerfile; aa-gateway, aa-api and dashboard you build from source (first-class images are tracked as follow-up); and persistence is any standard Postgres / TimescaleDB you run. The hosted SaaS edition runs this whole stack managed for you and adds the cloud / enterprise control-plane features that live outside this repo.

What the example Compose wires today

The sample docker-compose.yml starts the subset that ships container images out of the box — your agent placeholder, its aa-runtime sidecar, and the optional egress proxy — so you see enforcement working immediately, then grow toward the full topology above by adding persistence, gateway, API and dashboard.

flowchart LR
    subgraph compose["docker compose — your machine or CI"]
        stub["agent-stub<br/>(replace with your agent)"]
        rt["aa-runtime<br/>enforcement sidecar<br/>:8080 health and metrics"]
        proxy["aa-proxy<br/>egress MitM :8899<br/>optional · proxy profile"]
        pol[/"policy.toml<br/>bind mount"/]
        sock(["aa-runtime-socket<br/>shared UDS volume"])
    end
    stub <-->|IPC over shared UDS socket| sock
    rt <--> sock
    pol -->|AA_POLICY_PATH| rt
    stub -.->|outbound HTTPS| proxy
    proxy -.->|decisions| rt

The compose file (examples/docker-compose/docker-compose.yml) defines these services. Values below are taken directly from that file.

ServiceImage / buildCompose profilePublished portRole
aa-runtimeghcr.io/ai-agent-assembly/aa-runtime:latestdefault8080:8080Authoritative enforcement sidecar (health + metrics)
agent-stubalpine:latest (placeholder)defaultStand-in agent sharing the runtime IPC socket
aa-proxybuilt from ../../aa-proxy/Dockerfile (context = repo root)proxy8899:8899Optional egress-interception (MitM HTTPS) proxy

Volumes

VolumeMounted atPurpose
aa-runtime-socket/tmp (in aa-runtime and agent-stub)Shared Unix domain socket — the IPC channel lives at /tmp/aa-runtime-<AA_AGENT_ID>.sock
../policy.toml (bind)/etc/aa/policy.toml (read-only) in aa-runtimeLocal enforcement policy

Environment variables

aa-runtime:

VariableValue in the stackMeaning
AA_AGENT_IDmy-agent-001Agent identity; must match agent-stub. Names the IPC socket.
AA_POLICY_PATH/etc/aa/policy.tomlPath to the mounted local policy file.
AA_METRICS_ADDR0.0.0.0:8080 (default)Bind address for the health/metrics HTTP server.
AA_GATEWAY_ENDPOINT(unset)Left unset for standalone, gateway-less enforcement. Set it to call a gateway (self-hosted from source, or the SaaS endpoint) instead.

agent-stub:

VariableValue in the stackMeaning
AA_AGENT_IDmy-agent-001Must equal the runtime’s AA_AGENT_ID.
AA_GATEWAY_URLhttps://api.agentassembly.ioGateway URL a real agent SDK would use (SaaS endpoint shown; point it at your self-hosted gateway if you run one).
AA_API_KEY${AA_API_KEY}Read from your shell environment.

aa-proxy (only under the proxy profile):

VariableValue in the stackMeaning
AA_PROXY_ADDR0.0.0.0:8899Proxy listen address.
AA_PROXY_LLM_ONLYfalseIntercept all egress, not just LLM calls.
AA_PROXY_MCP_FAIL_OPEN1Demo only — lets the proxy start without a reachable gateway. The proxy normally fails closed when its gateway is unreachable.
AA_PROXY_GATEWAY_ENDPOINT(unset)Set to a gateway endpoint (self-hosted or SaaS) to enforce through it.

Quickstart

From a clone of the repository:

cd examples/docker-compose

# Runtime sidecar path (default profile: aa-runtime + agent-stub)
AA_API_KEY=dev-local-key docker compose up

aa-runtime starts, enforces locally from ../policy.toml, exposes the IPC socket at /tmp/aa-runtime-my-agent-001.sock, and serves health/metrics on :8080:

curl http://localhost:8080/ready
curl http://localhost:8080/health
curl http://localhost:8080/metrics

To additionally build and run the optional egress proxy on :8899:

AA_API_KEY=dev-local-key docker compose --profile proxy up

Tear down when finished:

docker compose down
# or, if you started the proxy profile:
docker compose --profile proxy down

Replacing the agent stub

agent-stub is an alpine placeholder (the Python SDK is not yet published — tracked in AAASM-55). To run a real agent, replace its image: with your agent image, keep AA_AGENT_ID identical to aa-runtime, and keep the aa-runtime-socket volume mounted at /tmp. See the example’s README for details.

Configuring the aa-api service

Once you grow the stack past the runtime-only quickstart and run the aa-api control-plane service (the one the dashboard reads), a few AA_* environment variables on that service shape what operators see and how they sign in. The full reference lives in Configuration → aa-api server environment variables; the self-host essentials:

VariableSet it toEffect
AA_POLICYa directory of scoped policy documentsThe dashboard’s capability-matrix, topology-chain, and team-policy projections show the real policy cascade. A single file shows one policy; leaving it unset makes the projections render Unknown / Unconfigured — never a fabricated allow.
AA_AUTH_OPEN_REGISTRATIONtrue (optional)Opens self-registration for native accounts. Default is closed: the first account bootstraps as owner, then it is invite-only.
AA_SMTP_HOST (+ AA_SMTP_PORT / USER / PASS / FROM)your SMTP relayEnables password-reset email delivery. When unset, resets still return 202 but no email is sent (a logging-mailer fallback).

Native email/password login requires a Postgres-backed deployment. The in-memory / runtime-only quickstart above stays API-key-only. Once aa-api is backed by Postgres, human operators can sign in with accounts — GET /api/v1/auth/methods advertises whether the password path is available, and the login page degrades honestly when it is not. See Authentication for the account, invite, and reset flows.

When you want it fully managed

If you would rather not run and maintain the infrastructure yourself — and want the managed, multi-tenant control plane with durable audit history, the operator dashboard, central registry, team budgets, SSO and compliance reporting — use the hosted SaaS edition, which runs the complete stack for you.


Last updated: 2026-08-06 by Chisanan232