Architecture overview
- Web Dashboard: Next.js app. Create agents, chat with them, edit their memory and skills, manage connections, secrets, and grants.
- API Server: the control plane. Owns the database, the conversation plane, and the work queue the runner polls.
- Rust Gateway: intercepts outbound requests (HTTPS included, via MITM) and injects credentials. Agents authenticate with access tokens via
Proxy-Authorizationheaders. - Runner: starts, parks, and reaps agent sandboxes. Outbound-only, and never touches the database.
- Sandbox Supervisor: runs inside each sandbox, speaking a vendor-neutral harness interface so the agent runtime is swappable.
- Channel Adapter: the Slack daemon, posting answers, mirrors, and approval cards.
- Secret Store: AES-256-GCM at rest, decrypted only at request time, matched by host and path pattern, injected as headers or query parameters.
The agent lifecycle
- You create an agent and grant it a model key plus the connections it needs.
- A message (from the dashboard, Slack, or a schedule) queues a turn on the API server’s work queue.
- The runner, polling outbound-only, picks up the turn and boots or wakes the agent’s sandbox. The sandbox has a durable workspace volume that survives park and wake.
- The agent works: shell, filesystem, and HTTP, with every outbound request forced through the gateway.
- Actions matching an approval rule pause and render an Approve/Deny card in the chat (dashboard or Slack). The decision is deterministic: nothing executes until a human decides, and expiry denies.
- The answer lands back in the conversation. What the agent learned persists in its platform-kept memory, and idle sandboxes are parked to free resources.
The gateway
Every outbound request from a sandbox (and from any connected external agent) passes through the Rust gateway:- The agent makes a normal HTTP request (e.g.,
GET https://www.googleapis.com/calendar/v3/events) - The gateway evaluates policy: organization rules plus the agent’s own grants. Blocked or rate-limited requests get a 403 or 429 immediately
- Approval-gated requests pause for a human decision
- If allowed, the gateway matches the target host and path against the credentials granted to that agent, decrypts the match, and injects it as a header (e.g.
Authorization: Bearer ...) or query parameter. A credential the agent has no grant for is never considered - The request is forwarded with credentials attached, and the response passes back unchanged
Policy engine
Rules are evaluated top-down, first match wins. Each rule pairs identities (which agents or people) with targets (an app and its tools, a connection, a secret, or a network pattern) and applies an action:- Block: deny the request entirely (403)
- Allow: permit it, optionally requiring human approval, or rate-limited to N requests per window (429 beyond the cap)