Add bind-host assessment that refuses 0.0.0.0/:: without override, warns on non-loopback binds, and documents internal-only MVP serving. Health endpoint exposes deployment metadata; docs cover Access/VPN/WARP and runtime env assumptions without embedding secrets in the client. Closes #435
59 lines
2.5 KiB
Markdown
59 lines
2.5 KiB
Markdown
# Web UI deployment boundary (#435)
|
|
|
|
The MCP Control Plane web UI is an **internal operator console**, not a
|
|
customer-facing application. The MVP assumes local or trusted-network access
|
|
only.
|
|
|
|
## MVP deployment model
|
|
|
|
- **Default bind:** `127.0.0.1:8765` (`WEBUI_HOST` / `WEBUI_PORT`)
|
|
- **Authentication:** none in MVP — protection comes from network placement
|
|
- **Mutations:** read-only routes; gated write actions remain disabled (#434)
|
|
- **Secrets:** resolved server-side via `gitea_auth` / `GITEA_MCP_CONFIG`; never
|
|
embedded in HTML, JavaScript, or browser storage
|
|
|
|
Do **not** expose the UI on the public internet without an access layer.
|
|
|
|
## Beyond localhost
|
|
|
|
If the UI must be reachable outside the operator laptop:
|
|
|
|
1. Prefer **Cloudflare Access**, **Cloudflare WARP**, or an org **VPN** so only
|
|
authenticated staff reach the service.
|
|
2. Bind to a specific interface only when necessary — never `0.0.0.0` / `::`
|
|
without understanding the exposure.
|
|
3. Set explicit override env vars only after access controls are in place:
|
|
- `WEBUI_ALLOW_PUBLIC_BIND=1` — acknowledges all-interface bind (`0.0.0.0`, `::`)
|
|
- `WEBUI_ALLOW_REMOTE_BIND=1` — acknowledges a non-loopback host
|
|
|
|
Startup **refuses** all-interface binds unless `WEBUI_ALLOW_PUBLIC_BIND=1`.
|
|
Non-loopback binds log a warning unless `WEBUI_ALLOW_REMOTE_BIND=1`.
|
|
|
|
## Environment variables
|
|
|
|
| Variable | Default | Purpose |
|
|
|----------|---------|---------|
|
|
| `WEBUI_HOST` | `127.0.0.1` | Bind address |
|
|
| `WEBUI_PORT` | `8765` | Listen port |
|
|
| `WEBUI_REPO_ROOT` | repository root | Workflow/schema hash root for prompt library |
|
|
| `WEBUI_PROJECT_REGISTRY` | packaged JSON | Project registry file path |
|
|
| `GITEA_MCP_CONFIG` | unset | Server-side MCP profile config path (optional) |
|
|
| `GITEA_MCP_PROFILE` | unset | Active MCP profile name (optional) |
|
|
| `WEBUI_ALLOW_PUBLIC_BIND` | unset | Acknowledge `0.0.0.0` / `::` bind |
|
|
| `WEBUI_ALLOW_REMOTE_BIND` | unset | Acknowledge non-loopback bind |
|
|
|
|
Gitea credentials (`GITEA_TOKEN_*`, `.env.*`, keychain refs) are read only on
|
|
the server when a page needs live Gitea data (e.g. `/queue`). They are not
|
|
shipped to the browser.
|
|
|
|
## Health / deployment metadata
|
|
|
|
`GET /health` includes a `deployment` object with bind disposition, runtime
|
|
assumption paths, and the client-secret policy. Use it to verify an instance is
|
|
configured for internal-only operation.
|
|
|
|
## Non-goals (MVP)
|
|
|
|
- Full SSO or session login in the UI
|
|
- Hosting on the public internet without Access/VPN/WARP
|
|
- Embedding Gitea tokens in the frontend bundle |