Web Interface
Ze provides an HTTPS web interface for browsing configuration, editing values, and running commands through a browser. The web UI uses the same YANG schemas, user database, and command grammar as the SSH CLI.
Starting the Web Server
Command Line
ze start --web 8443 # Start daemon + web on port 8443
ze start --web 8443 --insecure-web # No authentication (forces 127.0.0.1)
When no certificate is configured, ze generates an ECDSA P-256 self-signed certificate automatically. The certificate includes SANs for localhost, 127.0.0.1, ::1, and the listen address.
| Flag | Description |
|---|---|
--web <port> |
Start web interface on 0.0.0.0:<port> (requires config) |
--web-only |
Start web UI only, no daemon (config editing only, default port 3443) |
--insecure-web |
Disable authentication (forces 127.0.0.1, requires --web or --web-only) |
Workbench UI
Ze defaults to a RouterOS-style operator workbench UI. The workbench keeps the same authentication and commit flow; the CLI is available as a separate /cli tab instead of a bottom bar. BGP peer rows ship with related operator tools (peer detail, capabilities, statistics, flush, teardown) that run the same dispatched commands as the SSH CLI. Confirmation prompts gate destructive tools.
To roll back to the legacy Finder UI:
ZE_WEB_UI=finder ze start --web 8443
Configuration
The web server listen address can also be set in the ze configuration file:
environment {
web {
enabled true;
server main {
ip 0.0.0.0;
port 8443;
}
}
}
Authentication
The web interface uses the same user database as the SSH server. Users log in through a browser login page or authenticate API requests with HTTP Basic Auth.
Browser Sessions
- Navigate to
https://<host>:8443/. Unauthenticated requests receive a login page. - Enter username and password. On success, a
ze-sessioncookie is set. - The cookie is
Secure,HttpOnly, andSameSite=Strict. - Each user can have one active session. Logging in again invalidates the previous session.
JSON API
API clients that send Accept: application/json (or append ?format=json to the URL) can authenticate with HTTP Basic Auth instead of session cookies. No session is created for Basic Auth requests.
curl -k -u admin:password https://localhost:8443/show/bgp/?format=json
Security Headers
All authenticated responses include security headers: HSTS (max-age=63072000), Content-Security-Policy (default-src 'self'), X-Frame-Options DENY, X-Content-Type-Options nosniff, and Cache-Control: no-store.
Navigation
URL Scheme
URLs follow a verb-first three-tier pattern:
| Tier | URL Pattern | Method | Description |
|---|---|---|---|
| View | /show/<yang-path> |
GET | Read-only config tree view |
| View | /monitor/<yang-path> |
GET | View with auto-polling |
| Config | /config/edit/<path> |
GET | Editable config tree view |
| Config | /config/set/<path> |
POST | Set a leaf value |
| Config | /config/add/<path> |
POST | Create a list entry (with optional field values) |
| Config | /config/add-form/<path> |
GET | Fetch add-entry overlay form |
| Config | /config/rename/<path> |
POST | Rename a keyed list entry |
| Config | /config/delete/<path> |
POST | Delete a leaf value |
| Config | /config/commit/ |
GET/POST | View diff and commit changes |
| Config | /config/discard/ |
POST | Discard pending changes |
| Config | /config/changes |
GET | Commit bar state (pending change count) |
| Config | /config/compare/ |
GET | Compare pending vs committed |
| Admin | /admin/<yang-path> |
GET/POST | Administrative commands |
| Auth | /login |
POST | Login (no auth required) |
| Static | /assets/ |
GET | CSS, JS, images (no auth required) |
The root URL / redirects to /show/.
Finder Navigation
The left panel uses a Finder-style column browser (similar to macOS Finder). It shows up to 3 columns, scrolling horizontally as you navigate deeper.
Named vs unnamed containers: Named containers (lists with YANG keys, like peer, group) appear above unnamed containers (global settings like local, timer), separated by a horizontal rule. This makes keyed sections easy to find.
Simple lists: Lists without unique constraints show as a flat column of clickable entries with a + new button.
Context Heading
When inside a list entry, the detail panel shows a context heading at the top with the list name and entry key (e.g., PEER london). This provides immediate context without checking the breadcrumb.
List Table View
Lists that have YANG unique constraints (e.g., peer with unique "remote/ip") display as an interactive table in the detail panel. The table shows the list key and all unique fields as columns.
| Column | Behavior |
|---|---|
| Rename button | Opens a modal, normalizes the new key, and renames the entry without losing its subtree |
| Key column (e.g., name) | Clickable link, navigates into the entry's config subtree |
| Unique field columns (e.g., remote/ip) | Editable inline, saves on blur/Enter/auto-save (1s debounce) |
| Delete button | Removes the entry after confirmation |
The + new button below the table opens a server-rendered form (via HTMX) with inputs for the entry name and all unique fields. Field values are validated against YANG types before the entry is created.
Breadcrumb Navigation
Every page displays a breadcrumb trail from root to the current YANG path. Clicking any breadcrumb segment navigates to that level.
Content Negotiation
The response format is determined by:
?format=jsonquery parameter (takes precedence)Accept: application/jsonheader (whentext/htmlis not also present)- Default: HTML
Config Editing
Each authenticated user gets an independent editor session with its own working tree. Changes are tracked per-user and do not affect other users until committed.
Workflow
- Browse: Navigate to a list (e.g.,
/show/bgp/peer/) to see entries in a table. - Add: Click
+ newto create an entry. Fill in the name and unique fields. Values are validated against YANG types (e.g., IP addresses must be valid). - Rename: In table views, click the rename button to change an entry key. The new key is trimmed and lowercased, and the existing subtree stays attached to the renamed entry.
- Edit: Click an entry name to see its full config. Edit leaf values through inline fields.
- Review: The commit bar at the bottom shows pending change count. Click "Review & Commit" to see a diff.
- Commit: Apply changes. Conflicts with other users are detected and reported.
- Discard: Click "Discard" to abandon all pending changes.
Validation
Field values are validated server-side against YANG types before being accepted:
| Type | Validation |
|---|---|
| IP address | Must be a valid IPv4 or IPv6 address |
| IPv4 | Must be a valid IPv4 address |
| IPv6 | Must be a valid IPv6 address |
| Prefix | Must be a valid CIDR prefix |
| Uint16/Uint32 | Must be a valid unsigned integer in range |
| Boolean | Normalized to true/false |
YANG unique constraints are enforced: duplicate values are rejected with an error naming the conflicting entry.
Entry key names are automatically lowercased and trimmed for both add and rename operations.
Duplicate entry keys are rejected. Validation runs before the entry is created, so invalid input never produces a partial entry.
Navigating to a non-existent list entry (e.g., /show/bgp/peer/london/ when london has not been created) redirects to the root view with an error notification.
Notifications
Error notifications appear as toasts in the top-right corner with a 30-second countdown. Click the countdown to pause (for screenshots). Click the close button to dismiss immediately.
Input Auto-Save
Text and number fields auto-save 1 second after the user stops typing, in addition to saving on blur and Enter. This prevents data loss when navigating away before a field loses focus.
Conflict Detection
When two users edit the same leaf concurrently, the commit reports which paths conflict, showing both the local and other user's values. The user must resolve conflicts before committing.
Session Limits
The editor manager allows up to 50 concurrent user sessions. Idle sessions (no activity for 1 hour) are evicted when capacity is reached.
CLI Bar
The web interface includes a CLI bar at the bottom of the page that accepts the same command grammar as the SSH CLI. The CLI bar sends the current URL path as context, so set and delete commands operate relative to the current view.
Integrated Mode
In integrated mode, CLI commands update the page content directly:
| Command | Effect |
|---|---|
edit <path> |
Navigate to a config path |
set <leaf> <value> |
Set a value at the current context path |
delete <leaf> |
Delete a value at the current context path |
show [path] |
Display config text at the current or specified path |
top |
Navigate to root |
up |
Navigate one level up |
commit |
Commit pending changes |
discard |
Discard pending changes |
help |
List available commands |
The prompt shows the current context path: ze[bgp peer]#.
Terminal Mode
Terminal mode provides a scrollback terminal in the browser. Commands produce plain text output identical to the SSH CLI, displayed in a scrollback area with prompt echo.
Tab Completion
The CLI bar provides tab completion via a JSON endpoint at /cli/complete. Completions are context-aware: when at /show/bgp/peer/london/, typing set + Tab suggests remote, local, timer (children of the peer entry), not root-level items. For YANG union types that include an enum (e.g., local/ip accepting an IP address or auto), the enum values are offered as completions.
Live Updates
The web interface uses Server-Sent Events (SSE) to notify connected browsers when configuration changes are committed by any user. A notification banner appears with the username and a "Refresh" button.
Connect to the SSE stream at /events (requires authentication). The broker supports up to 100 concurrent SSE clients. Slow clients that fall behind have events dropped rather than blocking other clients.
Event Format
Events use the standard SSE wire format:
event: config-change
data: <html-fragment>
The HTML fragment contains a notification banner with the change description and action buttons.
Admin Commands
The /admin/ tier provides a browsable tree of administrative commands. Container nodes display navigable links to sub-commands. Leaf commands display a parameter form with an "Execute" button.
Admin command results are displayed as titled cards showing the command name, output text, and success/error styling.
Resilience
Corrupt change files: If a per-user change file in the blob store is unparseable (e.g., from a previous bug), it is automatically discarded with a warning log. The user can continue editing without manual intervention.
Asset caching: Static assets (/assets/) are served with Cache-Control: no-cache, must-revalidate so browsers always pick up changes after binary updates without requiring a hard refresh.