Local backend (serve) & the Desktop App
Belay splits its "SOC" surface into two pieces: a small local API backend you run
with belay serve, and the Desktop App that renders the actual UI on top of it.
serve is not a web dashboardbelay serve exposes a JSON + Server-Sent-Events (SSE) API only. It does not
serve HTML and it is not a web dashboard. The user-facing interface is the Desktop
App. Do not point a browser at it expecting a page.
When to use
- Run
servewhenever you want a local API for live activity, posture, findings, and human approvals — for the Desktop App to consume, or for your own tooling/automation. - Use the Desktop App as the everyday interface: tray status, live feed, scan, agent
management, AI explanations, messaging, host protection, and inline Allow / Deny for
askverdicts.
The serve backend
belay serve # binds 127.0.0.1:8787 by default
belay serve --addr 127.0.0.1:9000 # custom bind address
belay serve --audit <path> # read a specific audit log
serve is built with axum (Rust) and streams live audit rows over SSE via a tokio
broadcast channel. By default it binds to 127.0.0.1:8787 — loopback only.
The default bind is loopback (127.0.0.1). Treat the API as a local-only backend for the
Desktop App and local tooling; it is not intended to be exposed to a network.
Open API endpoints
| Endpoint | Method | Purpose |
|---|---|---|
/api/health | GET | Liveness / readiness probe. |
/api/posture | GET | Host / VPS security-posture summary. |
/api/findings | GET | Scanner and monitoring findings. |
/api/sessions | GET | Agent sessions (including correlation state). |
/api/egress | GET | Observed outbound / egress activity. |
/api/stream | GET (SSE) | Live feed of audit rows as they are written. |
/api/decisions/pending | GET | Pending ask verdicts awaiting a human decision. |
/api/decisions/{id} | POST | Submit an Allow / Deny answer for a pending decision. |
The two /api/decisions/* routes bridge to the daemon's approval queue, which is how the
Desktop App (or any local client) answers an ambiguous ask verdict inline.
The Desktop App
The Desktop App is built with Tauri 2 + React 19 and ships as an AppImage and a
.deb. It is the UI layer over the serve backend, sporting Belay's refreshed brand —
a faceted low-poly blue "B" icon.
It is more than a monitor: from the app you can run a scan, see detected agents and protect / unprotect them, work the approval queue, read AI explanations, configure messaging channels, and manage host protection.
Sidebar
A left sidebar organizes the app into tabs:
- Overview — posture score plus allow / ask / deny counts.
- Activity — the triage table of recent decisions.
- Live Feed — the SSE stream of audit rows in real time.
- Scan — run and review static scans.
- Agents — detected agents and protect / unprotect controls.
- Host Protection — ssh-guard, hardening checks, host scan, and quarantine.
- AI Explanations — the curated (and optional AI) "why is this risky" write-ups.
- Messaging — configure notification / approval channels and approvers.
- My Machines — this host and, under a commercial license, the fleet console.
Tray + notifications
- System-tray icon with a click-away popover for at-a-glance status.
- Privacy-safe notifications — a native system notification tells you a
denyorasklanded, by category only. It never includes the path or the command. - Autostart so the tray app is present after login.
- Signed auto-updater (minisign) for verified updates.
The webview reads your local ~/.belay data directly and connects to the local serve
backend for live activity and approvals.
Steps
1. Start the backend
belay serve
2. Launch the Desktop App
Install the AppImage or .deb and start it. It connects to the local serve backend and
begins tailing activity. On Linux the app requires webkit2gtk.
3. Respond to approvals
When an ambiguous action triggers an ask, it appears in the app (and at
/api/decisions/pending). Choose Allow or Deny. If nobody answers before the
timeout, the decision fails closed to deny. Approvals can also be routed to a chat
channel — see Notifications & channels.