Repository navigation
feat: read-only web dashboard (/ui) for developers and DevOps engineers #2192
Description
Activity
- addedstate:triage-neededOpened without agent diagnostics and needs triageOpened without agent diagnostics and needs triage
on Jul 9, 2026 📋 triage-agent
Triage Assessment
Classification: needs-investigation
Summary
The observability need is real, and existing server handlers plus
TracingLogBusmake a read-only dashboard feasible. The proposed authorization boundary is not safe as written: an environment flag controls availability, but it does not make routes local-only or protect fleet metadata, policies, and logs.Investigation
Sandbox, policy-history, and log handlers already expose the underlying data in process, and
TracingLogBusprovides both tail and subscription APIs (crates/openshell-server/src/tracing_bus.rs:74-97). However, gRPC requests are protected byAuthGrpcRouter, while the Axum HTTP router is a separate service without equivalent bearer/RBAC enforcement (crates/openshell-server/src/multiplex.rs:155-185;http.rs:180-188).Gateway deployments commonly bind to non-loopback addresses. Therefore
OPENSHELL_WEB_UI=1does not make unauthenticated/ui/api/*routes dev/local-only. Those routes would disclose sandbox inventory, full policy material, and recent/live logs that currently require read scopes. The decision board also needs a structured event contract; parsing shorthand display strings is not a durable OCSF API.No exact duplicate exists. #1055 is the broader enterprise-observability roadmap, while #1922 and #1722 are related durability and tenancy/access-control work.
Recommendation
Run a focused spike before implementation. Define HTTP authentication and RBAC equivalence, listener exposure, browser token/session handling, CSRF/origin behavior, and a structured event stream. A strictly loopback-only listener could be an alternative, but “disabled by default” alone must not be the security boundary.
- addedarea:gatewayGateway server and control-plane workGateway server and control-plane worktopic:observabilityLogging, metrics, and observability workLogging, metrics, and observability workand removedstate:triage-neededOpened without agent diagnostics and needs triageOpened without agent diagnostics and needs triage
on Jul 10, 2026 This issue has had no activity for 14 days and is now marked stale. It may be closed in 7 days if there is no further activity. Comment or remove the state:stale label to keep it open.
- addedstate:staleInactive item at risk of automatic closure.Inactive item at risk of automatic closure.
on Jul 25, 2026 This is being developed out of this repo already by Red Hat.
Problem Statement
OpenShell currently exposes two operator surfaces: the CLI and the ratatui TUI. Both work well for hands-on-keyboard workflows, but several recurring situations are poorly served:
openshell logs --tail,policy get, YAML edits, andpolicy setacross terminals. The "why" of a denial (binary mismatch, resolved symlink, policy rule) is buried in log text.messagefield when a destination endpoint is present, so an operator seesNET:FAIL [LOW] pypi.org:443with no reason. In a real debugging session this cost us a full day chasing an IPv6 hypothesis when the actual cause was an upstream TLS verification failure.Proposed Design
A read-only web dashboard embedded in the gateway binary, as the first slice of a larger web UI direction (full plan drafted separately; this issue covers only the read-only observability slice).
Backend (
openshell-server):web_uimodule serving a single-file SPA at/uiplus a small JSON API under/ui/api/*:GET /ui/api/overview— gateway version, sandbox countsGET /ui/api/sandboxes— fleet list (phase, image, created, active policy version, conditions)GET /ui/api/sandboxes/{name}— detail incl. policy revision history and current policy YAMLGET /ui/api/sandboxes/{name}/logs— initial log tailGET /ui/api/sandboxes/{name}/stream— SSE live stream bridged from the in-memoryTracingLogBusOPENSHELL_WEB_UI=1is set. These routes intentionally bypass gRPC bearer auth, so the gate keeps them dev/local-only until proper authn/z (OIDC session or token) is added in a follow-up.Frontend (embedded
assets/ui.html, no build step, no external dependencies):Non-goals for this slice: any mutating action (policy edit, sandbox lifecycle), multi-gateway views, web terminal, persistent event storage. Those are follow-ups per the broader plan.
Alternatives Considered
Agent Investigation
Feasibility was validated by implementing a working prototype against a live gateway (Docker driver) running a real agent workload (Discord bot in a policy-constrained sandbox):
grpc::sandbox::{handle_get_sandbox, handle_list_sandboxes}andgrpc::policy::{handle_get_sandbox_policy_status, handle_list_sandbox_policies, handle_get_sandbox_logs}(visibility widened topub; thegrpcmodule itself remains crate-private).TracingLogBus::subscribeworks end-to-end: a policy denial triggered inside the sandbox appeared on the board in real time, including the full denial reason (binary-not-allowed with ancestor chain and symlink hint) that the shorthand log format suppresses.cargo clippy --workspace --all-targets -- -D warningsandcargo fmtclean; no new dependencies added to the workspace.