flowchart TB
U[User
Terminal / Discord] --> O[Orchestrator]
O --> RBAC[RBAC + Sessions]
RBAC --> R{Router}
R --> L[Local Agent
in-process, Agent SDK]
R --> S[Sandboxed Agent
Container, Worker]
L --> PE[Permission Engine]
S --> PE
PE -->|allow| X[Execute]
PE -->|deny| B[Block]
PE -->|ask| GK[Gatekeeper
AI risk review]
GK -->|low risk| X
GK -->|high risk| H[Prompt User]
L -->|HTTP_PROXY| CP[Credential Proxy]
S -->|HTTP_PROXY| CP
CP --> NP{Network Policy}
NP -->|allow| I[Internet]
NP -->|deny| BL[Blocked]
| Package | What it does |
|---|---|
orchestrator |
Config, RBAC, sessions, routing, channels (terminal + Discord), dispatch, container lifecycle, permission engine, gatekeeper, scheduler |
worker |
HTTP server (/run + /health) wrapping Agent SDK query(). Runs inside containers. Stateless. |
proxy |
MITM HTTP proxy with TLS interception. Route-based credential injection. SSH tunnel. Gateway API for token management. |
sequenceDiagram
participant U as User
participant Ch as Channel
participant O as Orchestrator
participant RBAC as RBAC
participant PE as Permission Engine
participant A as Agent
participant P as Credential Proxy
participant API as Upstream API
U->>Ch: Message
Ch->>O: Route message
O->>RBAC: Check access
RBAC-->>O: Allowed
O->>A: Dispatch (local or container)
A->>PE: Tool invocation
PE-->>A: allow / deny / ask
A->>P: HTTPS request (via HTTP_PROXY)
P->>P: Strip auth headers
P->>P: Inject credentials
P->>API: Authenticated request
API-->>P: Response
P-->>A: Response
A-->>O: Result
O-->>Ch: Reply
Ch-->>U: Display
POST /runquery() directlyallow → proceeddeny → blockask → gatekeeper reviews risk → auto-approve or prompt userask_agent MCP tool
flowchart LR
U[User] --> M[Main Agent]
M -->|ask_agent| E[Engineer]
E -->|ask_agent| R[Researcher]
M -.->|RBAC check| RBAC[Original user's
permissions]
E -.->|RBAC check| RBAC
R -.->|RBAC check| RBAC
The orchestrator injects an ask_agent MCP tool into each agent’s session. When an agent calls it:
A Discord user’s permissions apply even three levels deep: user → main → engineer → researcher.
stateDiagram-v2
[*] --> Idle
Idle --> Provisioning: First request
Provisioning --> Starting: docker create + start
Starting --> HealthCheck: Container up
HealthCheck --> Ready: GET /health OK
HealthCheck --> Failed: Timeout
Failed --> Provisioning: Retry
Ready --> Ready: Subsequent requests (reuse)
Ready --> Stopping: Shutdown / idle timeout
Stopping --> [*]: docker stop + remove
Shared mode (default): one container per agent type, reused across sessions. The worker is stateless — each request carries model, system prompt, tools, and session ID.
On first request to a sandboxed agent:
docker create with proxy env vars (no secrets)docker start + health checkSession-isolated mode: set container.isolation: session for per-scope containers. Each conversation gets its own container, torn down on idle timeout.
flowchart LR
A[Agent] -->|HTTPS via HTTP_PROXY| P[Credential Proxy]
P --> NP{Network Policy}
NP -->|denied| B[403 Blocked]
NP -->|allowed| S[Strip Auth Headers]
S --> M{Match Route?}
M -->|yes| R[Resolve Credential
file / 1Password / AWS]
M -->|no| F[Forward as-is]
R --> I[Inject Header]
I --> U[Upstream API]
F --> U
Any agent with credentials configured routes through the proxy — sandboxed or local. Sandboxed agents are forced through it (only route out of the container). Local agents route through it automatically via the SDK’s env option when the proxy is running. All HTTPS is intercepted via MITM with a local CA cert:
The credential provider is a CLI command template — works with files, 1Password, AWS Secrets Manager, or anything else:
# File-based (default)
read: "cat config/secrets/{key}"
# 1Password
read: "op read op://{key}"
flowchart LR
T[Tool Call] --> R{Match Rules
first-match-wins}
R -->|allow| E[Execute]
R -->|deny| B[Block + Error]
R -->|ask| GK{Gatekeeper}
R -->|no match| GK
GK -->|risk ≤ threshold| E
GK -->|risk > threshold| H[Prompt User]
H -->|approved| E
H -->|denied| B
Per-agent, first-match-wins. Three actions:
| Action | Behavior |
|---|---|
allow |
Proceeds silently |
deny |
Blocked, agent sees error |
ask |
Human-in-the-loop approval (or gatekeeper auto-approve) |
No match defaults to ask.
Selectors:
"allow:*" # all tools
"deny:Write" # specific tool, all invocations
"allow:Bash(git *)" # tool + command glob
"deny:Write(/config/**)" # tool + path glob
Path prefixes: / (platform root), ~/ (home), ./ (agent cwd), // (absolute).
Optional AI risk review for ask rules. A configurable agent evaluates each tool invocation and assigns a risk level (low / medium / high / critical). Actions at or below the threshold are auto-approved with a notification; higher-risk actions are presented to the user with the review attached.