Platform Settings
The Admin → Settings page provides platform-wide configuration that affects all users. Changes take effect immediately unless noted otherwise.
This page requires the symphony-admin role.
Session Idle Timeout
Controls how long a user can be inactive before their session is allowed to expire. When idle, token renewal is paused and the session will end when the current access token expires.
| Setting | Range | Default |
|---|---|---|
| Idle timeout | 5 minutes – 8 hours | 30 minutes |
Users pick up the new timeout on their next page load.
Extension Dependency Resolution
Controls how extension UIs obtain the JavaScript libraries they import (React, MUI, charting libraries, 3D libraries, etc.). Three modes are available; each has different implications for outbound network requirements and the bundle workflow extension authors use.
| Mode | Outbound to cdn.jsdelivr.net | Bundle resolution | Use case |
|---|---|---|---|
| Proxy (default) | Required | Disabled even if a bundle exists | Standard production with internet access. Backward-compatible. |
| Mixed | Required for unbundled imports | Enabled; bare specifiers not in any extension's bundle fall through to /npm | Phased migration — fleet adopts bundles extension-by-extension. |
| Bundle-only | Not required | Required for every non-platform import | Air-gapped, compliance-restricted, or supply-chain-hardened deployments. |
Switching mode takes effect immediately on save; no Symphony restart is required. The /npm proxy returns 404 the moment Bundle-only is selected, and resumes serving the moment Proxy or Mixed is selected.
The platform's own UI assets (Babel, htmx, Mermaid, oidc-client-ts, the React/MUI/etc. shims that extensions consume as platform externals) are vendored into the Symphony binary and served from /vendor/* regardless of mode. They never depend on outbound HTTPS.
Bundle-only mode prerequisites
Before switching to Bundle-only, every extension whose UI imports a non-platform library must have shipped a bundle for that library. If you switch with unbundled extensions registered, the affected extension's pages will fail to load with an explicit error message naming the missing dependency. The first-party globe extension is an example of an extension that ships a bundle (for globe.gl and three).
See Bundling UI Dependencies for the developer workflow.
CDN Cache
The CDN cache stores the responses of jsDelivr proxy fetches in NATS JetStream memory storage. It only operates in Proxy and Mixed dependency resolution modes; in Bundle-only mode the proxy is disabled and the cache is unused.
Status
The settings page shows the current cache usage as a progress bar. If the cache is not active, an alert displays the reason (for example, insufficient JetStream storage). When Bundle-only mode is selected, this section is hidden.
Configuration
| Setting | Range | Default | Description |
|---|---|---|---|
| Maximum size | 64 – 2048 MB | 256 MB | Upper bound on total cached content. Uses the jetstream.max_mem quota in nats.config. |
| TTL | 1 – 168 hours | 24 hours | How long cached entries are retained before automatic eviction. |
Changes are applied at runtime without restarting Symphony.
The CDN cache uses memory storage, which draws from the jetstream.max_mem budget configured in nats.config (default: 1 GB). If the JetStream memory quota is exhausted by other workloads, the cache will fail to initialise. Increase jetstream.max_mem or reduce the cache maximum size to resolve this.
Extension Bundles (Admin)
In Mixed and Bundle-only modes, the bundles uploaded by registered extensions can be inspected and managed via:
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/admin/bundles | List every uploaded bundle with version, active status, publish time, chunk count, and total bytes. |
| PUT | /api/v1/admin/bundles/{prefix}/active | Promote a specific version to active for a prefix (rollback or staged promotion). |
| DELETE | /api/v1/admin/bundles/{prefix}/{version} | Force-delete a non-active version. Returns 409 if the targeted version is currently active. |
Non-active bundle versions are garbage-collected automatically after a 7-day grace period. The active version is never automatically deleted.
API
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/admin/settings | Returns current settings including idle_timeout_minutes, cdn_mode, cdn_cache_max_bytes_mb, and cdn_cache_ttl_hours. |
| PUT | /api/v1/admin/settings | Updates settings. Only provided fields are modified. cdn_mode accepts "proxy", "mixed", or "bundle-only". |
| GET | /api/v1/admin/cdn/status | Returns cache runtime status: enabled, size_bytes, max_bytes, ttl_seconds, and error (if any). |
| GET | /api/v1/extensions/bundles/active | Per-user discovery: returns the active bundle index for every extension the requesting user can see. Entries are keyed by registration identifier and include both identifier and prefix. The UI loader populates window.__symphonyExtensionBundles from this endpoint. |