← Blog
RFC · sigil-os#21

Remote Desktop RFC: Projected Lumen Desktops in sigilOS 0.6.0

June 22, 2026 · sigil-os#21 · Sigil-Docs
rfc remote-desktop rfb capabilities 0.6.0

sigilOS 0.6.0 gains remote desktop: a Lumen desktop projected over the network, with full capability isolation per session. Each remote client receives a framebuffer region and can inject pointer and keyboard events — all through Cap<Display>, Cap<Input>, and Cap<NetConn>, none of which can be forged or escalated. This RFC gates the 0.6.0 sprint assignments for the whole fleet. (sigil-os#21)

Remote desktop session on Raspberry Pi
Remote desktop session on raspi3b — Lumen projected over Cap<NetConn>

Three capabilities, one session

Every remote desktop session in sigilOS is defined by exactly three capabilities held by the session process:

Cap<Display>
Read access to exactly one DSO overlay slot (framebuffer region). The session reads its slot; it cannot peek at any other session's region or the full system framebuffer.
Cap<Input>
Write access to the session's own WM input queue entry. Pointer and keyboard events from the remote client go here. Cannot inject events into another session's context.
Cap<NetConn>
Bidirectional byte-stream connection to the remote client (TCP or QUIC). Carries RFB-format framebuffer updates outbound and client events inbound.

The session process holds all three and nothing else — it cannot elevate, cannot access another session's framebuffer, cannot forge events for another WM context. The broker mints the caps and hands them over; the broker's elevation token never enters the session process.


Session lifecycle

1
Incoming client connection → broker mints Cap<NetConn> via cap_net_accept (Kernel syscall 110).
2
Broker requests a DSO overlay slot (fb_overlay_request, syscall 103) → receives Cap<Display> scoped to that slot's region. Max 8 concurrent sessions.
3
Broker mints Cap<Input> scoped to the session's WM input queue entry.
4
All three caps are handed to the session process (rdp_session.sg). Session loop runs: read Display → RFB-encode → write NetConn; read NetConn → RFB-decode → write Input.
5
Session process crash or disconnect → kernel ref-count drop releases all three caps. No WM or kernel state is corrupted; overlay slot freed for the next session.

Wire protocol: RFB (VNC-compatible)

The wire format is RFB — the same protocol used by VNC clients, which means any VNC-compatible viewer (RealVNC, TigerVNC, Screens, Jump Desktop) can connect to a sigilOS remote desktop session without a custom client.

SRDX frame encoder on x86
SRDX encode path — frame-diff encoder on x86 (RFB-compatible output)

Per-session isolation invariants

These invariants hold for every session, and are enforced by the capability system — not by runtime checks in the session code:


Fleet implementation order

This RFC gates the 0.6.0 sprint. The implementation proceeds in dependency order:

StepOwnerDeliverable
1 Kernel cap_net_listen(port) → Cap<NetConn> (syscall 109) + cap_net_accept(listener) → Cap<NetConn> (syscall 110)
2 OS rdp_session.sg — session loop with loopback-stubbed caps: Display read → RFB encode → NetConn write; NetConn read → RFB decode → Input write
3 Video vid_rfb_encode(prev_fb, curr_fb, out_buf) → bytes — frame-diff encoder (ZRLE or raw)
4 All Integration test: local loopback client → PASS screendump showing projected Lumen desktop

Open questions