Operator console
Inspect backend-owned facts, review authorized intents and follow command evidence through the packaged panel.
Packaged in every self-hosted laneThe operator console is the browser dashboard. Every self-hosted lane image includes the same reviewed static bundle, served by nginx from /usr/share/nginz-iot-panel/browser. Lane configuration decides which facts appear and whether governed mutations can run.
It is not ngz-iot. That name is the operator CLI—the shell client on the same node. Both read the same redacted admin snapshot; only the console is a web UI.
The console never reads shared-memory rings, WAL files, checkpoints, private Zig structs, or daemon internals. It consumes HTTPS admin APIs and redacted snapshots. No separate Node runtime is part of the product topology.
What it is for
Operators use the console to answer:
- Can this node safely accept assigned traffic now?
- Which clients, sessions, rules, bridges, and gateways are healthy?
- Who changed configuration, policy, or a governed command?
- Can I create a redacted support bundle without leaking payloads or secrets?
It does not own MQTT sessions, routing, retained data, authorization policy, bridge delivery, HA ownership, or command completion. Those remain with nginx, nginz-iotd, nginz-iot-bridge, and the external HA layer.
Lane behavior
| Lane | Console posture |
|---|---|
| Free, Pro, Max | Same-origin read routes. Controlled writes are requested off. Drain, preflight, and support-bundle mutations fail closed. |
| Enterprise | SSO/CSRF edge plus loopback-only trusted mutation locations. Capability-gated drain, bridge drain, config preflight, and support-bundle creation with PostgreSQL audit. |
A route existing in the navigation does not enable a higher-lane feature. Max can show bridge facts because Max has bridges. Free can show the Bridges page with empty or unavailable surfaces.
Safety model
The console must not display MQTT payloads, passwords, bearer tokens, private keys, DSNs, secret paths, or raw ring contents. Fields such as body_included=false exist to prove a summary stayed redacted.
The browser does not calculate whether traffic may be routed to a node. It displays the backend decision:
route_to_node =
node_ready &&
shard_ready &&
owns_current_writer_term &&
replay_frontier_valid &&
ring_generation_valid &&
required_gates_valid &&
!controlled_drain &&
!stale_active_rejected
live is not ready. A process can answer a health check while route assignment is blocked.
An HTTP 2xx on a command means accepted only. Treat reconciled backend evidence as completion. See governed commands.
Header fields
Confirm these before interpreting data or attempting a mutation:
| Field | Meaning |
|---|---|
env |
fixtures for local console rehearsal, live for a real admin gateway. |
node |
Backend node name. |
contract |
Contract version and compatibility. Incompatible contracts disable mutations. |
quality |
ok, partial, stale, incompatible, or invalid. Only ok permits mutation evaluation. |
freshness |
Age of the dashboard snapshot. The stale threshold is 30 seconds. |
mutations |
Effective browser gate after contract and quality checks. |
Live dashboards refresh every 15 seconds. Collection pages load separately when opened.
Deployment boundary
Serve the panel and admin API through an authenticated same-origin gateway. The trusted edge must:
- strip untrusted identity headers and inject a verified principal
- require the panel CSRF header on mutations
- deny admin CORS
- apply the reviewed CSP
- keep HTML/API responses
no-store - cache only hashed static assets as immutable
Do not expose trusted mutation locations to device clients. Do not use the local Angular proxy as a production SSO boundary.
Local fixture mode is for learning navigation and rehearsing triage:
npm install
npm run contract:refresh
npm run start
That workflow belongs to the panel repository. Customer nodes use the packaged static bundle already inside the lane image.
This page is a customer-oriented guide. The source contract remains authoritative for exact behavior and release evidence.
../nginz-iot-panel/OPERATION_GUIDE.md