Skip to content

Remote Shell (Secure Console)

The portal can open an interactive root shell on a gateway. It needs no SSH and no inbound reachability, because the session rides the agent's outbound WebSocket. For the operator procedure see Remote root console.

Authorization

The console action is separate from write, because a shell bypasses every guard the config path has. IssueShellTicket calls requireDeviceAccess(…, ActionConsole).

Holder Console
ORG_OWNER (org wildcard) yes
SUPPORT, SUPPORT_ADMIN (on the org or the device) yes
PLATFORM_ADMIN yes
ORG_MEMBER, DEVICE_OWNER, PARTNER no

Flow

sequenceDiagram
    actor Op as Operator
    participant P as Portal (xterm.js)
    participant N as Nexus
    participant DO as realtime DO
    participant A as Agent

    Op->>P: Open console
    P->>N: PortalGatewayService.IssueShellTicket(device)
    N->>N: check console
    N-->>P: single-use ticket
    P->>DO: WSS /gateway/{id}?role=operator&ticket=…
    DO->>N: GatewayInternalService.ValidateShellTicket
    N->>N: open a shell_sessions row
    N-->>DO: valid (user, device, expiry)
    P->>DO: shell_input / shell_resize
    DO->>A: forwarded
    A->>A: first frame starts /bin/ksh on a PTY
    A->>DO: shell_output
    DO->>P: forwarded
    Note over DO,N: operator socket closes
    DO->>N: ReportShellSessionEnd
  • Frames are JSON, with the PTY bytes base64-encoded inside: shell_input, shell_resize, shell_output, shell_close.
  • The DO relays operator frames to the gateway and gateway shell frames to operators only. Viewers never receive them, and viewer sockets are read-only.
  • The ticket is single-use and bound to user, device and organization. It expires, and the session lasts at most one hour (shellticket.SessionTTL).

Limits on the agent

The agent enforces its own limits (internal/shell) and does not trust the client:

  • a 60-minute maximum session
  • a 10-minute idle timeout
  • one session per device

When any limit is reached, or the socket closes, the PTY's process group is killed.

Audit

Each session is a shell_sessions row: device, user, organization, start, end, end reason. PortalGatewayService.ListShellSessions lists them, for platform admins only. Keystrokes and output are not recorded.