Skip to content

Web Dashboard Configuration

This document describes the configuration for the Scion Web Dashboard. The web UI is served by the Go scion binary with the --enable-web flag.

The Web Dashboard is a client-side SPA served by the Go server, which also handles OAuth, session management, SSE real-time events, and API routing. Configuration is managed through CLI flags and environment variables.

Flag Default Description
--enable-web false Enable the web dashboard.
--web-port 8080 The HTTP port the web UI listens on.
--session-secret (Deprecated — use the SCION_SERVER_SESSION_SECRET environment variable instead.) Secret key for signing session cookies. Must be set in production. Passing secrets via CLI flags exposes them in /proc/pid/cmdline and ps(1) output; use the environment variable or a systemd EnvironmentFile for secure delivery.
Variable Default Description
SCION_SERVER_SESSION_SECRET Secret key for signing session cookies and hub tokens. Preferred over --session-secret — environment variables are not visible in process listings. Deliver via systemd EnvironmentFile or a secrets manager.
SESSION_SECRET Deprecated. Read only when SCION_SERVER_SESSION_SECRET is unset, with a startup warning. Use SCION_SERVER_SESSION_SECRET instead.

These variables are required for standard user login in production.

Variable Description
SCION_SERVER_OAUTH_WEB_GOOGLE_CLIENTID Google OAuth 2.0 Client ID.
SCION_SERVER_OAUTH_WEB_GOOGLE_CLIENTSECRET Google OAuth 2.0 Client Secret.
SCION_SERVER_OAUTH_WEB_GITHUB_CLIENTID GitHub OAuth App Client ID.
SCION_SERVER_OAUTH_WEB_GITHUB_CLIENTSECRET GitHub OAuth App Client Secret.
SCION_SERVER_AUTH_AUTHORIZEDDOMAINS Comma-separated list of email domains allowed to sign in.

Configure user login via an external OIDC provider (e.g. Okta, Keycloak) in the server.oidc_login section of settings.yaml (enabled, display_name, issuer_url, client_id, client_secret, scopes). See Authentication for an example.

Underscored names such as SCION_SERVER_OIDC_LOGIN_ENABLED are ignored, and the Hub logs a warning at startup for each one. The collapsed names (SCION_SERVER_OIDCLOGIN_ENABLED, SCION_SERVER_OIDCLOGIN_ISSUERURL, and so on) take effect only when settings.yaml has a server: section. They are ignored on the legacy server.yaml path.

Used for local testing without setting up full OAuth. The CLI sends development credentials only to loopback Hub endpoints (localhost, 127.0.0.1, ::1).

Variable Default Description
SCION_DEV_TOKEN Explicit development token for loopback Hub API access.
SCION_DEV_TOKEN_FILE ~/.scion/dev-token Path to the token file generated by the Hub (used by the CLI only for loopback Hub endpoints).

Feature flags control the availability of Web Dashboard features. Registered experiments (see Experiments) are resolved in this order:

  1. Server value — the client fetches GET /api/v1/experiments at boot (signed-in users only). This is the hub-wide value an admin sets from Admin → Server Config → Experiments.
  2. localStorage override — set scion:feature:<name> in localStorage for development. Applies only to names the server did not send, or when the experiments fetch fails.
  3. Compiled default — flags listed below default to ON; all others default to OFF. Used when the experiments fetch fails.
Flag Default Description
web.native_chat ON Enable the Native Web Chat workspace.
web.gcs_links OFF Linkify a gs://bucket/object URI an agent posts in chat, and let the viewer fetch and preview that object through the hub. Also gates the hub’s GET /api/v1/gcs/object endpoint, which additionally requires a configured GCP token generator.
web.agent_badges OFF Show a harness vendor mark and the agent’s configured model size (S, M, L, XL) on agent cards and rows on the Agents and project pages and on graph cards. Web only; the hub is unaffected.
web.sse_hidden_tab_close OFF Close a tab’s live-update streams (page, agent list and terminal metadata) after it has been hidden for 60 seconds, and reopen them, refreshing the page’s data, when it is shown again. Terminal connections stay open. Web only; the hub is unaffected.
hub.artifacts OFF Artifacts: files and bundles agents and users publish with stable, versioned references. Also gates the hub’s /api/v1/artifacts routes, which answer 404 while it is off, and the artifact page. See Artifacts.

web.gcs_links, web.agent_badges, web.sse_hidden_tab_close and hub.artifacts are registered experiments; web.native_chat is not (see Experiments for what that distinction means). web.native_chat is instead driven by the hub’s nativeChatEnabled setting (from /api/v1/settings/public): when it is false, boot writes the flag to false directly into the flag bag isFeatureEnabled checks first, ahead of any localStorage override.

To disable a registered experiment hub-wide, use the Experiments tab. A localStorage override has no effect on a registered experiment for a signed-in user on a working hub — it only applies to an unregistered flag (such as web.native_chat), or on a page load where the experiments fetch fails:

// localStorage override (development only; no effect on a registered
// experiment unless the experiments fetch fails)
localStorage.setItem('scion:feature:web.native_chat', 'false');

The Go server includes a pre-configured Content Security Policy (CSP) that allows the Hub itself and Google Fonts. Shoelace and its icons are served from the web bundle, not a CDN. Images may also load from blob: URLs, which chat uses for image previews. HSTS is automatically enabled in production with a 1-year max-age.

  • API responses. JSON responses on the web server’s /api/v1/ mount are gzip-compressed when the client sends Accept-Encoding: gzip and the body is at least 1 KiB (status 200, 201 or 203, type application/json or application/problem+json). A compressed response carries Content-Encoding: gzip and Vary: Accept-Encoding, has no Content-Length, and any ETag becomes weak. Streams are never compressed: WebSocket upgrades, text/event-stream requests, terminal and port routes, and paths ending in /stream or /events. Nor are responses that can carry credentials, signed object-store URLs or artifact capabilities, for example the authentication, agent-facing, Runtime Broker registration, secrets and env routes, agent records and agent creates, workspace, template, harness-config and skill transfers, and artifact links and views.
  • Static assets. Files of the embedded web build that compress well have brotli and/or gzip variants. The server sends the coding the client prefers by Accept-Encoding q-value, brotli then gzip on a tie, else uncompressed. Each variant has its own strong ETag, and a matching If-None-Match gets 304 Not Modified. Assets served from --web-assets-dir (including any up-to-date .br/.gz siblings) use weak validators based on file size and modification time. Content-hashed bundle files listed in .vite/manifest.json are served with Cache-Control: public, max-age=31536000, immutable; hex-hashed filenames not in the manifest get public, max-age=86400; and unhashed entrypoints such as /assets/main.js get no-cache. Directory requests under /assets/ and dot-path files such as /.vite/manifest.json return 404 (/.well-known/ routes remain reachable), and the web build ships no source maps: .map files and sourceMappingURL comments are neither embedded nor served (CI keeps the maps as a build artifact).

The Web Dashboard is served by the same Go binary as the Hub API. In production, enable it with --enable-web and ensure the SCION_SERVER_SESSION_SECRET environment variable and the OAuth provider variables are configured. Avoid passing the session secret via the --session-secret CLI flag, as CLI arguments are visible to other local users via /proc/pid/cmdline.