返回资讯中心
外部精选
软件工程
#开发者实时流

OpenShell WebUI – a secure local web UI for OpenShell

A web UI for OpenShell. Everything you do with the openshell CLI (sandboxes, policies, proposals, providers, workspaces) from your browser, without giving up its security model.

Hacker News 最新shahariaa2026/10/24 · 13 天前29 分钟阅读

以下正文同步自 Hacker News 最新,版权归原站所有,已转换为易读排版。

A web UI for OpenShell. Everything you do with the openshell CLI (sandboxes, policies, proposals, providers, workspaces) from your browser, without giving up its security model.

One small binary (Rust backend, React UI embedded). It reuses the gateways and credentials your openshell CLI already has, runs on 127.0.0.1, and can do only what your gateway identity is allowed to do. No extra accounts, no database.

Quickstart · Features · Docs · Security · Configuration · Development · Contributing

It takes two seconds, and it is how the next OpenShell user finds it.

Unofficial project. OpenShell WebUI is an independent community tool. It is not affiliated with, endorsed by, or supported by NVIDIA. For OpenShell itself, see the official repository and documentation.

openshell-webui-demo-small.mp4

📸 Screenshots

⚡ Quickstart

You need the OpenShell CLI with a registered gateway: the WebUI uses its gateway registry and credentials. Check that openshell status says Connected. Docker is optional and adds live container stats for local sandboxes.

Each release publishes an image for linux/amd64 and linux/arm64 to ghcr.io/shaharia-lab/openshell-webui (tagged latest, X.Y and X.Y.Z).

docker run --rm --name openshell-webui
--network host
--user "$(id -u):$(id -g)"
-v ~/.config/openshell:/home/app/.config/openshell:ro
-v openshell-webui-state:/home/app/.local/state
ghcr.io/shaharia-lab/openshell-webui:latest

Then open http://127.0.0.1:8787. Add flags after the image name, e.g. --read-only or --addr 127.0.0.1:9000.

Each release ships one self-contained binary, with the UI embedded, for Linux and macOS on amd64 and arm64. The Linux builds are static, so they run on any distribution.

os=$(uname -s | tr '[:upper:]' '[:lower:]') # linux or darwin arch=$(uname -m | sed 's/x86_64/amd64/; s/aarch64/arm64/') # amd64 or arm64 curl -fsSL -o openshell-webui "https://github.com/shaharia-lab/openshell-webui/releases/latest/download/openshell-webui-$os-$arch" chmod +x openshell-webui ./openshell-webui --open

The WebUI opens http://127.0.0.1:8787. To keep it on your PATH, move the binary to /usr/local/bin or ~/.local/bin. Each release also ships a checksums.txt (SHA-256).

[!NOTE] The macOS binary is not notarized. curl downloads are not quarantined, but if you downloaded the binary with a browser, clear the flag first: xattr -d com.apple.quarantine openshell-webui.

Needs Rust (stable) and Bun (cargo --version, bun --version).

git clone https://github.com/shaharia-lab/openshell-webui.git cd openshell-webui make run

make run checks the tools, starts the local gateway if it is not reachable (systemd user unit or Homebrew service), builds one release binary with the UI embedded, and opens http://127.0.0.1:8787. make build only builds it, to bin/openshell-webui.

openshell-webui # read-write openshell-webui --read-only # look, but never change anything openshell-webui --addr 127.0.0.1:9000 # another port

From a source checkout, the same with make run, make run ARGS=--read-only and make run ADDR=127.0.0.1:9000. Every flag is in Configuration.

Start with --read-only on a shared or production gateway. Every write is refused before it reaches the gateway, so you can explore safely.

Area You can…

Overview See every registered gateway and its health, sandbox counts, and live CPU / memory of local OpenShell containers

Sandboxes Create (image or template, network rules, providers, resources, GPUs, labels, environment, services), start, stop, delete

Policy Read the effective policy including provider rules, add or remove rules, endpoints and binaries, edit the whole policy as YAML, change settings

Proposals Review rules drafted from denied traffic as a diff, edit them, then approve, reject, undo, approve all or clear

History Browse every policy version and diff any two

Logs Stream gateway and sandbox logs live, filter by source, level, time and text, and spot denied connections

Terminal Open a shell or run a one-off command in a sandbox (xterm.js over WebSocket); Ctrl+C copies a selection, Ctrl+Shift+C/V copy and paste

Files 🆕 Browse a sandbox's file system: upload files or whole folders (drag and drop; .git, node_modules, target, dist, .venv and .gitignore matches are skipped), download, preview, edit, create folders, delete

Services Expose sandbox HTTP ports through the gateway and remove them

Providers Manage credentials (never shown again after saving), rotation, expiry and automatic refresh; check readiness per sandbox

Provider profiles Import, lint, edit and delete profiles in CLI YAML or proto JSON

Templates Create and delete reusable sandbox templates (image, resources, environment, labels, driver config) and create sandboxes from them

Workspaces Create and delete workspaces, manage members and roles

Gateway See your identity and roles, compute drivers, extensions, gateway-wide settings, the gateway's own log, and the WebUI's audit log

The user guide walks through each area step by step.

Everything is scoped by gateway and workspace (or all workspaces), refreshes automatically, works in light and dark mode, and adapts to small screens. The gateway enforces roles: the WebUI can do only what the signed-in identity may do.

flowchart LR B["Browser<br/>React + shadcn/ui"] -->|"JSON + CSRF<br/>SSE · WebSocket"| S["openshell-webui<br/>(Rust, single binary)"] S -->|"reads"| R[("~/.config/openshell/<br/>gateways/<name>/")] S -->|"gRPC<br/>mTLS · OIDC · plaintext"| G1["Gateway A"] S -->|"gRPC"| G2["Gateway B"] S -.->|"optional"| D["Docker<br/>container stats"] S -.->|"append"| A[("audit.jsonl")]

Loading

The backend calls the gateway through reflection over the upstream protos: one dynamic gRPC codec serves every method, and secret fields are found from the proto annotations rather than a hand-kept list. See Architecture in the developer guide for the details.

The server reads each gateway from ~/.config/openshell/gateways/<name>/:

Cloudflare edge gateways are not supported yet.

Editors accept the CLI YAML format, proto-shaped YAML, or proto JSON. Only known spelling differences are converted; unknown fields are errors, and the gateway validates the result again.

The WebUI holds the keys to your gateways, so it is built to be boring and strict.

There is no login. Anyone who can reach the port acts as your gateway identity. Do not expose it to other people without an authenticating reverse proxy in front (see --addr and --allowed-host).

Guide What's inside

User guide Install, concepts, every page of the UI, configuration, security, troubleshooting

Developer guide Local development, architecture, backend and frontend, tracking upstream OpenShell, testing, recipes, releasing

⚙️ Configuration

Flag Environment Default Meaning

--addr OPENSHELL_UI_ADDR 127.0.0.1:8787 listen address; keep it on loopback

--open

off open the UI in the default browser

--read-only OPENSHELL_UI_READ_ONLY off refuse every action that changes state

--audit-log OPENSHELL_UI_AUDIT_LOG $XDG_STATE_HOME/openshell-ui/audit.jsonl JSON-lines record of every write

--gateway-log-dir OPENSHELL_UI_GATEWAY_LOG_DIR Homebrew log dir, else the systemd journal where the local gateway logs

--allowed-host OPENSHELL_UI_ALLOWED_HOSTS none extra Host values to accept, for a reverse proxy

--timeout-secs OPENSHELL_UI_TIMEOUT 20 timeout for one gateway call

--no-update-check OPENSHELL_UI_NO_UPDATE_CHECK off never ask GitHub for the latest release

The sidebar shows the WebUI version, the version of the openshell CLI on your PATH, and a link to this repository. To tell you when a newer release is out, the backend asks GitHub's API for the latest release at most once every six hours. That request carries no gateway data; --no-update-check turns it off.

More detail, including reverse proxies and running in the background, is in Configuration. With make, set ADDR for the address and ARGS for anything else. If DOCKER_HOST is unset, the WebUI uses the one from the gateway's gateway.env, so it talks to the same Docker engine as the gateway.

examples/claude-sandbox/ runs Claude Code inside an OpenShell sandbox: an Ubuntu image, a policy that lets only the claude binary reach Anthropic's API, and a provider profile that injects the OAuth token so the sandbox never sees it. Create it from the CLI or the WebUI, then watch its egress and proposals live.

The image is published as ghcr.io/shaharia-lab/claude-sandbox:latest and rebuilt whenever examples/claude-sandbox/ changes on main.

make dev # backend (cargo watch) + frontend (Vite HMR) with hot reload make backend-dev # backend only, on 127.0.0.1:8787 make frontend-dev # Vite dev server, proxies /api to the backend make test # cargo test + vitest make lint # rustfmt, clippy -D warnings, eslint, prettier, tsc make build # bin/openshell-webui with the frontend embedded make proto # refresh protos from $OPENSHELL_SRC and regenerate TS types

The developer guide covers local setup, architecture, tracking upstream OpenShell, testing and step-by-step recipes.

In development, open the Vite URL it prints (http://localhost:5173). make proto expects an OpenShell checkout at OPENSHELL_SRC (default ~/Projects/OpenShell) and records the upstream commit in backend/proto/SOURCE_COMMIT.

To release, set version in backend/Cargo.toml (and run cargo check so Cargo.lock follows), merge it, then push a matching tag: git tag v0.2.0 && git push origin v0.2.0. The tag builds the four binaries into a GitHub release with checksums.txt, and the multi-platform Docker image. A tag that disagrees with Cargo.toml fails before anything is built; a tag with a - (v0.2.0-rc.1) is a pre-release and does not move latest.

Makefile dev, build, run, test, lint, proto backend/ Rust: axum + tonic + prost-reflect proto/ protos copied from OpenShell (SOURCE_COMMIT) src/gateway/ CLI registry, connection pool, mTLS/OIDC, dynamic gRPC codec src/http/ routes, guards, SSE watch, WebSocket terminal, file browser, assets src/rpcs.rs allowlist of gateway methods the browser may call src/redact.rs secret redaction driven by proto annotations tests/api.rs HTTP tests against an in-process fake gateway frontend/ React 19 + TypeScript + Vite + Tailwind v4 + shadcn/ui src/api/ typed client, TanStack Query hooks, mutations src/features/ one folder per area (sandboxes, policy, logs, files, …) src/components/ shadcn/ui, shared building blocks, app shell src/gen/ types generated from the protos examples/ runnable examples claude-sandbox/ Claude Code in an OpenShell sandbox

Exposing another gateway method

Add it to ALLOWED in backend/src/rpcs.rs as Read or Write (writes are audited and refused in read-only mode).

Add it to the typed map in frontend/src/api/rpc.ts and call it with useRpc(gw, "Method").

Run make lint test.

Never allowlist sandbox-token, supervisor, peer or credential-export RPCs. More rules for contributors and AI agents are in CLAUDE.md.

Found a security problem? Please report it privately through GitHub security advisories, not a public issue.

⭐ Spread the word

⭐ Star the repo · 🐛 Report something broken

Know someone running AI agents in OpenShell? Share it with them.

📄 License

MIT: do what you like, no warranty.

Third-party code keeps its own license: backend/proto/ comes from NVIDIA/OpenShell (Apache License 2.0), and the Rust crates and npm packages (including xterm.js and shadcn/ui) carry their own licenses.

Built with Rust · axum · tonic · React · shadcn/ui · xterm.js · for OpenShell

⭐ Star OpenShell WebUI if it saved you a trip to the terminal.

正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。

打开原文
去社区讨论 →