-
Notifications
You must be signed in to change notification settings - Fork 2
web ui
Pre-Alpha. This page describes behavior that may change.
The web UI is the same engine as the CLI with a different surface. It reads and writes the same config tree, runs the same YANG validators, and uses the same user database. This is the long version of the Web UI tour.

The web server is part of the Ze daemon. You enable it from the command line or in the config.
ze start --web 3443environment {
web {
enabled true;
server main {
ip 0.0.0.0;
port 3443;
}
}
}
When no certificate is configured, Ze generates an ECDSA P-256 self-signed certificate on first start, with SANs for localhost, 127.0.0.1, ::1, and the listen address. Put a real certificate in front of the port before you expose it.
The --insecure-web flag turns off authentication and forces the listener back to 127.0.0.1. It exists for development. Do not use it on a public interface.
The web server uses the same user database as the SSH CLI. You can log in two ways.
Browser sessions go through /login. On success, Ze sets a ze-session cookie that is Secure, HttpOnly, and SameSite=Strict. Each user has at most one active session: logging in from a second browser invalidates the first.
API clients use HTTP Basic. Send Accept: application/json (or append ?format=json to the URL) and Ze authenticates the request without creating a session.
Both login paths run through the same AAA chain as the SSH CLI, so RADIUS and TACACS+ administrators can sign in to the web UI. Local users remain the fallback, used when the remote servers are unreachable or do not recognise the account.
curl -k -u admin:password https://localhost:3443/show/bgp/?format=jsonEvery authenticated response carries the security headers you would expect: HSTS (max-age=63072000), Content-Security-Policy: default-src 'self', X-Frame-Options: DENY, X-Content-Type-Options: nosniff, and Cache-Control: no-store.
A session's authorization profile decides what it can reach. A read-only session (a profile that denies the edit section) is blocked from every configuration-editing surface: the config edit form and the /admin/ console return 403 Forbidden, and the edit controls are hidden from the navigation so they are never offered in the first place.
The same authorizer enforces both layers. The route gate that returns the 403 and the handler that would apply a mutation consult one authorizer, so page visibility and mutation enforcement never diverge. Read paths are unaffected: a read-only user still browses the config tree, runs show and monitor, and downloads the running config.
Deployments with a single admin and no authorization assignments are unaffected: with nothing to enforce, the gate allows edits.
The URL pattern is verb-first and three-tier.
| Tier | Pattern | Method | Description |
|---|---|---|---|
| View | /show/<yang-path> |
GET | Read-only config tree view. |
| View | /monitor/<yang-path> |
GET | Same as /show with auto-polling. |
| Config | /config/edit/<path> |
GET | Editable config tree. |
| Config | /config/set/<path> |
POST | Set a leaf value. |
| Config | /config/add/<path> |
POST | Create a list entry. |
| Config | /config/delete/<path> |
POST | Delete a leaf value. |
| Config | /config/add-form/ |
GET | Add new entry overlay form. |
| Config | /config/changes |
GET | Commit bar HTML with pending change count. |
| Config | /config/commit/ |
GET/POST | Diff and commit. |
| Config | /config/discard/ |
POST | Discard pending changes. |
| Config | /config/compare/ |
GET | Compare pending against committed. |
| Config | /config/diff |
GET | Diff modal with content. |
| Config | /config/diff-close |
GET | Closed diff modal (empty state). |
| Config | /config/download |
GET | Download the committed config as a text attachment. |
| Config | /config/upload |
POST | Replace the whole config from an uploaded file. |
| Fragment | /fragment/detail |
GET | HTMX fragment for detail panel. |
| SSE | /events |
GET | SSE endpoint for real-time config change notifications. |
| Admin | /admin/<yang-path> |
GET/POST | Administrative commands. |
| Auth | /login |
POST | Login (no auth). |
| Static | /assets/ |
GET | CSS, JS, images (no auth). |
/ redirects to /show/.
The left panel is a Finder-style column browser, the kind macOS users will recognise. You click into a container, a new column slides in to the right, and you keep going until you hit a leaf or a list. Three columns are visible at a time, scrolling horizontally as you go deeper.
Named containers (lists with YANG keys, like peer and group) appear above unnamed ones (local, timer), separated by a horizontal rule. Lists with unique constraints render as a table in the detail panel, with the key and unique fields as columns. You rename, edit, and delete entries inline. The + new button under every list opens a server-rendered form, with YANG types validated before the entry is created.
When you are inside a list entry, the detail panel shows a context heading at the top (PEER upstream) so you do not need the breadcrumb to know where you are.
Each authenticated user gets an independent draft session. Your edits are tracked per user and never affect other users until you commit.
Text and number fields auto-save one second after you stop typing, in addition to saving on blur and Enter. The commit bar at the bottom of the page tracks the count of pending changes. Click "Review and Commit" to see a diff and either commit or discard.
Conflicts with another user are detected at commit time. The conflict report names the paths and shows both your value and the other user's value. You resolve them and try again.
If a colleague commits while you have the page open, a Server-Sent Events stream pushes a notification banner with their username and a Refresh button. The SSE broker supports up to 100 concurrent clients.
The editor manager allows up to 50 concurrent draft sessions. Idle sessions (no activity for one hour) are evicted when capacity is reached.
You can move the whole configuration through the browser. GET /config/download streams the committed config as a ze.conf text attachment. Any authenticated session may download it, and the download is audit-logged.
POST /config/upload replaces the entire configuration from an uploaded file. The upload is validated exactly like a commit: an invalid config is rejected with the validation error (HTTP 400) and nothing is applied. A valid config is applied, the reload fires, and the action is audit-logged. Upload is an edit action, so read-only sessions are refused. The body is capped to reject oversized uploads.
Every page has a CLI bar at the bottom that takes the same grammar as the SSH shell. The bar carries the current URL path as context, so a set or delete runs against whatever you are looking at. Tab completion is context-aware: at /show/bgp/peer/upstream/, typing set and Tab offers the children of that peer entry, not root-level items.
| Command | Effect |
|---|---|
edit <path> |
Navigate to a config path. |
set <leaf> <value> |
Set a value at the current context. |
delete <leaf> |
Delete a value at the current context. |
show [path] |
Display config text at the current or given path. |
top / up
|
Navigate to root or up one level. |
commit / discard
|
Apply or abandon pending changes. |
who |
List active web editing sessions. |
help |
List available commands. |
There is also a terminal mode for when you want a scrollback shell in the browser.
The /admin/ tree exposes administrative RPCs through the same finder-style column navigation as the config tree. GET renders the navigation and command forms; POST executes the command. The tree is derived from the ze-bgp-api YANG RPCs.
| Group | Subcommands |
|---|---|
peer |
list, show, summary, capabilities, statistics, add, remove, teardown, clear-soft, flush
|
route |
update, borr, eorr, raw
|
cache |
list, retain, release, expire, forward
|
system |
commit, subscribe, unsubscribe, events
|
Leaf commands (those with no sub-commands) render a parameter form in the detail panel. POST to /admin/<group>/<command> executes the command and returns the result.
The Workbench is now the default web UI. It provides:
- Two-level navigation: top bar for domains (Dashboard, BGP, Config, System, Specs), sidebar for sub-pages.
- Dashboard: hostname, uptime, version, memory usage at a glance. Live BGP summary data and SSE log stream.
- Domain pages: per-peer detail with capabilities, statistics, flush, and teardown controls. Configured interfaces with canonical kernel types.
- Integrated CLI page: full terminal-mode CLI in the browser.
- Structured log viewer: parses and displays JSON log output with filtering.
- Theme: unified CSS custom properties, switchable at runtime.
The previous Finder-style UI is still accessible by setting ZE_WEB_UI=finder. The --web-only flag on ze cli launches the daemon with only the web UI (no interactive CLI session).
The UI ships an English base catalog and a French locale. The locale is chosen from the browser's Accept-Language header, and any key missing from a non-English catalog falls back to English, so a partial translation never renders a blank label.
The stylesheet carries a small-screen layout down to 390px (iPhone-class portrait), with a horizontal-scroll guard so the page body never scrolls sideways. Wide content scrolls inside its own container instead.
Some leaves are annotated at render time with a friendlier form beside the raw value:
| Value | Annotation |
|---|---|
| An IP address | Its reverse-DNS (PTR) hostname. |
A standard community in ASN:value form |
Its well-known RFC name (for example 65535:65281 shows as no-export). |
Decoration is best-effort: a failed DNS lookup, or a community with no well-known name, simply shows the raw value with no annotation. These join the existing ASN-name decorator, which annotates an AS number with its organization name.
The Looking Glass route-list API accepts limit and offset query parameters to page through large tables (for example ?limit=50&offset=100). Without them a request returns the full list unchanged. limit=0 means unlimited, an offset past the end returns an empty list, and a non-numeric or negative value is rejected with HTTP 400.
- Web UI tour for the five-minute version.
- CLI for the same operations through SSH.
- Configuration overview for the model both surfaces share.
Adapted from main/docs/features/web-interface.md and main/docs/guide/web-interface.md.
Unreviewed draft. This wiki was authored in bulk and has not been reviewed. File corrections on the issue tracker.
- Overview
- YANG Model
- Editor Workflow
- Archive and Rollback
- System
- Interfaces
- VRRP
- BFD
- FIB
- OSPF
- IS-IS
- MPLS / LDP / RSVP-TE
- RSVP-TE
- SRv6
- Static Routes
- Policy Routing
- Firewall
- Traffic Control
- Class of Service
- L2TP/PPP
- PPPoE
- VPP Data Plane
- RPKI
- IPsec VPN
- TACACS+ AAA
- RADIUS AAA
- AS112 DNS
- Authorization
- Fleet
- BGP
- Starting and Stopping
- Show Commands
- Monitoring
- Flow Export
- DDoS Mitigation
- Anomaly Detection
- Health Checks
- Audit Trail
- Production Diagnostics
- Logging
- Operational Reports
- Healthcheck
- Self-Update
- Zero-Touch Provisioning
- MRT Analysis
- Upgrade and Restart
- Storage
- Policy
- Core
- Resilience
- Validation
- Capabilities
- Address Families
- Protocol
- Subsystems
- Infrastructure
- Route Server at an IXP
- Transit Edge with RPKI
- Public Looking Glass
- ExaBGP Migration Walkthrough
- FlowSpec Injection
- Chaos-Tested Peering
- AS Path Topology