CC CloudControl Operator docs · no login required

Agent command surface

The bound device runs a small lifeline core plus a signed plugin. The most basic agent must always accept and execute confirmed shell commands natively — shell is not break-glass and not plugin-optional. Other ops still come from the signed plugin. This page maps that surface against the control plane.

Modular agent · 0.3.2-lifeline+ Lab: GL-E5800 Shell = core native (confirmed) Upgrade required for shell on current lab unit
Rule of thumb: trust GET /api/admin/devices/:iddevice.status.agent.commands. After the shell-capable core is installed, that list includes shell. Until upgrade, live lab may still report without shell.

Why this page exists

Earlier modular builds treated shell as local break-glass only. That was the wrong product direction: the most basic device agent must run shell (with server confirmation). MQTT and collect_status already worked; shell was missing from the advertised core surface.

Compare these stories when something fails:

  • What the live device advertises (source of truth for enqueue)
  • What the modular core implements natively (status, upgrade, reboot, shell)
  • What the signed plugin manifest allows
  • What the server accepts as a type name (COMMAND_TYPES)

What runs on the device

Think of three replaceable pieces on A/B devices. Only core + plugin advertise remote commands.

Core

cloudcontrold

Reach the assigned edge at all costs, durable ledger/outbox, recovery, signed updates, minimal status, and shell.
Native: collect_status, agent_upgrade, reboot, shell (confirmed)

Guardian

cloudcontrol-guard

Independent rollback deadlines for connectivity and updates. Not a command agent — no remote command types.

Plugin

cloudcontrol-legacy

Out-of-process ops (set_*, network tests, WG/IPsec, scans). Signed manifest is the allowlist. Shell stays on the core so the basic agent works even with zero plugins.

Optional lock-down

Disable shell

Deployments may set CLOUDCONTROL_DISABLE_SHELL=1 on the device to turn shell off. Default is on.

Lab snapshot · GL-E5800

Captured 2026-07-19 against the live lab unit via admin API only.

Onlinelive · MQTT via edge-nyc3-01
Agentcloudcontrold · 0.3.2-lifeline · profile full · protocol 3
Core SHA-256d211e2646e5fef36f32667d31c75aad074c40023899e3dd1e6bc2ed8b1f6ce87
Core size2,000,748 bytes (UPX)
Plugincloudcontrol-legacy · same version
Shell (pre-upgrade lab)Was not advertised on 0.3.2-lifeline without native shell; code now treats shell as core native — rebuild/upgrade to pick up
Proven pathcollect_status succeeded (delivered → acked → completed ≈ 553 ms)

Advertised commands on that device

agent_upgrade, block_client, bt_scan, cell_scan, collect_clients, collect_status, firmware_check, ipsec_join, ipsec_leave, network_iperf, network_path_test, network_port_test, network_speedtest, reboot, set_firewall, set_lan, set_system, set_wifi, wireguard_onboard, wireguard_remove

Full command grid

Compare each command type across the modular core, the legacy plugin, the server type allowlist, and the live lab advertisement. Rows highlighted in warm tint are mismatches (server still names the type; modular device does not advertise it).

Y present / allowed N absent / refused when advertised set exists BG break-glass only E edge-control, not device agent
Command type Core Plugin Server Live Notes

Control-plane mismatches

These sources still describe an older or broader surface than modular lifeline ships.

src/routes/admin.js · COMMAND_TYPES
Claims: historical full set including shell, wifi_*, reset, firmware_upgrade, cell_at…
Reality: type name accepted, then capability gate filters per device advertisement.
src/routes/info.js · commandTypes
Claims: short outdated list with shell; missing WG/IPsec/agent_upgrade.
Reality: not a reliable live catalog.
src/agent-command-policy.js
Claims: comment says modular bundle does not export WG/IPsec/agent_upgrade/shell.
Reality: wrong for WG/IPsec/agent_upgrade (plugin/core export them). Shell correctly absent.
docs/autonomous-operations.md (pre-fix)
Claims: “Full profile on GL-E5800 advertises shell.”
Reality: false for 0.3.2-lifeline. Ops doc corrected; use this page.
agent/cmd/cloudcontrold/capabilities.go
Claims: monolithic defaultFullAgentCapabilities (wifi, firmware_upgrade, …).
Reality: shipped lifeline follows coreagent + plugin, not that list alone.

How enqueue is gated

  1. POST /api/admin/devices/:id/commands with type in server COMMAND_TYPES.
  2. If the device has reported agent.commands or agent.capabilities, the type must appear in their union (case-insensitive).
  3. Otherwise: 409 device_capability_not_advertised.
  4. Confirmation / risk bits (agent-command-policy.js) are separate from advertise/deny.
Do not use SQL to invent command capability. Inspect and control via admin API only. Device traffic is edge-only; the UI host is not on the device contact path.

Example: uname -a

PathResult
Lab unit on pre-shell core device_capability_not_advertised — expected until upgrade
After shell-capable core upgrade Admin enqueue shell with payload.command: "uname -a" (confirmed) → stdout
collect_status inventory (always) Kernel / hostname / arch without full uname string

How to refresh this page’s data

  1. Admin login → GET /api/admin/devices/:id
  2. Read status.agent.commands, .capabilities, .plugins[]
  3. Compare to public/downloads/cloudcontrol-plugin-legacy-*.plugin.json
  4. Compare to COMMAND_TYPES in src/routes/admin.js
  5. Update the COMMANDS array in this HTML (and the snapshot pills) when the surface changes

Machine-oriented twin (markdown): docs/agent-command-surface.md in the repo. Prefer this HTML page for operators.