Skip to content

Terminal Plugin

The terminal plugin is the reference SDK plugin implementation. It provides a WebSocket-based interactive shell relay so operators can open a live terminal session to any connected device directly from the Umoo platform — no separate SSH access or VPN required.


Overview

PropertyValue
Plugin IDterminal
TierSDK (pluginsdk.BackendPlugin)
Version1.0.0
HTTP routesYes — WebSocket + REST
Prometheus metricsYes
Bus subscriptionsevt.terminal.v1.*, cmd.terminal.v1.*
DB schemaYes — session table

HTTP Routes

All routes are mounted under /api/v1/plugins/terminal/ and go through the standard middleware stack:

Rate limit → JWT auth → Tenant auth → per-route RBAC check

MethodPathPermissionDescription
GET/api/v1/plugins/terminal/ws/{device_id}terminal/session:openUpgrade to WebSocket; open interactive shell
GET/api/v1/plugins/terminal/sessionsterminal/session:readList all currently active terminal sessions

WebSocket Terminal (GET /ws/{device_id})

Opens a bidirectional WebSocket connection that relays raw terminal I/O between the browser and the target device agent.

Connection lifecycle:

  1. Client sends GET /api/v1/plugins/terminal/ws/{device_id} with Upgrade: websocket.
  2. Server validates RBAC (terminal/session:open), looks up the device, and opens a relay channel via the message bus.
  3. The device agent receives a cmd.terminal.v1.open command and spawns a shell process.
  4. Raw bytes flow bidirectionally: client → server → device, device → server → client.
  5. When either end closes, the server sends a cmd.terminal.v1.close command and tears down the session.

Shell defaults:

Config keyDefaultDescription
shell/bin/bashShell executable on the device
persistencetrueKeep session alive if the WebSocket drops temporarily
enable_colorfalseAdvertise TERM=xterm-256color to the shell

⚠️ Docs correction: Earlier versions of the guide listed /bin/sh, persistence=false, and enable_color=true as defaults. The source-of-truth defaults are shown above.

List Sessions (GET /sessions)

Returns all sessions that are currently tracked by the server (connected or reconnecting).

Response (JSON array):

json
[
  {
    "session_id": "sess_abc123",
    "device_id":  "550e8400-e29b-41d4-a716-446655440000",
    "tenant_id":  "660f9511-...",
    "user_id":    "770a0622-...",
    "opened_at":  "2025-03-25T10:00:00Z",
    "state":      "connected"
  }
]

RBAC Permissions

Permissions are seeded automatically at startup (SDKPluginManager.Init()). They are stored in the platform permissions table and enforced by the same PermissionCache that guards ConnectRPC handlers.

PermissionDefault rolesDescription
terminal/session:readviewer, operator, tenant_adminList active sessions
terminal/session:openoperator, tenant_adminOpen a WebSocket shell to a device

To check programmatically from the Web UI:

typescript
can(perms, 'terminal/session', 'read')   // show sessions list
can(perms, 'terminal/session', 'open')   // show "Open Terminal" button

Message Bus

The terminal plugin publishes and subscribes on the following bus topics:

DirectionTopicPayloadDescription
Subscribeevt.terminal.v1.*Incoming terminal state events from devices
Subscribecmd.terminal.v1.*Internal command routing
Publishcmd.terminal.v1.open{session_id, device_id, shell, tenant_id}Tell device agent to spawn a shell
Publishcmd.terminal.v1.close{session_id}Tell device agent to terminate the shell

Prometheus Metrics

All metrics are registered under the terminal_ namespace:

MetricTypeLabelsDescription
terminal_active_sessionsGaugeNumber of currently open WebSocket sessions
terminal_sessions_opened_totalCounterLifetime count of sessions opened
terminal_sessions_closed_totalCounterLifetime count of sessions closed
terminal_bytes_relayed_totalCounterdirection (ingress|egress)Total bytes relayed through the terminal proxy

Plugin Configuration

Configuration is stored per-tenant using SetPluginConfig / GetPluginConfig RPCs (resource: plugin, action: write/read).

KeyTypeDefaultDescription
shellstring/bin/bashShell to spawn on the device
persistencebooltrueWhether to maintain session on transient WebSocket disconnects
enable_colorboolfalseSet TERM=xterm-256color in the shell environment
max_sessionsint10Maximum concurrent sessions per tenant
idle_timeout_secint300Seconds of inactivity before auto-closing a session

Agent-Side Plugin

The device agent runs a corresponding terminal agent plugin that:

  1. Subscribes to cmd.terminal.v1.open commands addressed to its device ID.
  2. Spawns the configured shell and attaches stdin/stdout/stderr.
  3. Relays I/O back to the server over the existing agent connection.
  4. Handles cmd.terminal.v1.close by sending SIGHUP to the shell process.

The agent plugin is hot-reconfigurable: if SetPluginConfig changes shell or enable_color, the change takes effect for new sessions without agent restart.


See Also

Umoo — IoT Device Management Platform