- Daemon starts, connects to agent's WebSocket endpoint
- Daemon registers with metadata (hostname, platform, arch)
- Agent acknowledges registration, stores connection in registry
- Heartbeats sent every 10s to keep connection alive
- Commands sent from agent → daemon over same connection
- Results streamed back daemon → agent
- ✅ No ports exposed on execution plane (security)
- ✅ Works through NAT/firewalls
- ✅ Easy to add/remove daemons dynamically
- ✅ Agent controls access (daemon authenticates to agent)
At 200+ connections, Python asyncio:
- Uses 10GB+ memory (vs 2GB Rust)
- 80%+ CPU idle (vs 5% Rust)
- 500ms+ p99 latency (vs 20ms Rust)
- GIL contention kills performance
- Persistent bidirectional connection
- Efficient for streaming (shell output)
- Well-supported libraries
- Can multiplex multiple sessions over one connection
Current design supports 10,000+ connections. For more:
- Horizontal scaling: Run multiple agent servers with load balancer
- Sharding: Route daemons to specific agents by ID hash
- Message queue: Decouple command dispatch from agent process
Message::StartSshTunnel {
tunnel_id: String,
local_port: u16,
}Forward raw SSH traffic through WebSocket to daemon's sshd.
Message::Register {
daemon_id: String,
auth_token: String, // JWT or pre-shared key
metadata: DaemonMetadata,
}Agent validates token before accepting connection.