Files
govoplan-core/docs/REMOTE_WEBUI_BUNDLES.md
Albrecht Degering 635d25c74c
Some checks failed
Dependency Audit / dependency-audit (push) Has been cancelled
Module Matrix / module-matrix (push) Has been cancelled
chore: consolidate platform split checks
2026-07-10 12:51:19 +02:00

6.1 KiB

Remote WebUI Bundle Loading

GovOPlaN WebUI modules normally ship through the core WebUI package graph: install a tagged npm/git dependency, run npm install, rebuild the shell, and restart or reload the served assets. Remote WebUI bundles are an experimental future path for controlled deployments where a backend-enabled module is not in the local WebUI package graph and the operator wants the shell to load its frontend without rebuilding core.

This design defines the target guardrails. The current rebuild/reload path remains the default production path.

Current Rebuild Path

The supported release path is:

  1. Install or remove backend and WebUI package dependencies through the trusted installer CLI/daemon.
  2. Snapshot package state before mutation.
  3. Run npm install and optionally npm run build.
  4. Restart or reload the served WebUI assets.
  5. Use installer rollback if package apply, restart, or health checks fail.

Strengths:

  • package manager and lockfile semantics stay conventional
  • CSP can stay strict because all code is served as built assets
  • rollback restores package files and lockfiles
  • local development uses sibling workspace dependencies naturally

Costs:

  • frontend changes require a rebuild/reload
  • hot enabling a module with frontend code is not possible in the running shell
  • failed rebuilds happen at install time, not at lazy module-load time

Remote Bundle Path

Remote loading is only for modules that are enabled by the backend and absent from virtual:govoplan-installed-modules. The backend manifest exposes:

  • FrontendModule.asset_manifest
  • asset_manifest_integrity
  • asset_manifest_signature
  • asset_manifest_public_key_id
  • asset_manifest_contract_version

The WebUI shell fetches the asset manifest, verifies manifest integrity and/or signature, validates the manifest contract, fetches the entry bundle, verifies the entry integrity, imports the bundle, validates the exported PlatformWebModule, and applies backend metadata before registering routes, navigation, and UI capabilities.

Unsigned and unhashed manifests are skipped. Entries without integrity are skipped. A module id mismatch is skipped.

Asset Manifest Contract

Contract version 1:

{
  "contractVersion": "1",
  "moduleId": "files",
  "entry": "./files-webui.remote.js",
  "entryIntegrity": "SHA-256-<base64-or-hex-digest>",
  "moduleExport": "default"
}

The backend manifest carries the manifest-level trust metadata. The remote asset manifest carries the concrete entry URL and entry digest.

Compatibility Checks

Before a remote bundle is accepted:

  • backend module must be enabled
  • local WebUI module with the same id must be absent
  • manifest contract must be supported by the shell
  • manifest moduleId, exported module id, and backend module id must match
  • backend metadata remains authoritative for label, version, dependencies, nav, and runtime UI capability exposure
  • future contract versions must declare required shell capabilities so old shells fail closed

Remote bundles must not broaden backend permissions. They can only contribute routes/nav/capabilities that the backend metadata and existing permission checks allow.

CSP

The current implementation imports verified entry bytes through a blob URL. A production CSP for this mode must explicitly allow:

  • connect-src for the approved asset-manifest and bundle origins
  • script-src for blob: only when remote loading is enabled
  • no unsafe-inline requirement for remote modules

If an installation cannot allow blob: scripts, the follow-up implementation should use signed same-origin module assets with static URLs instead of blob imports. Remote loading must be disableable by configuration so strict-CSP deployments can keep the rebuild path only.

Cache Invalidation

The shell cache key is:

<module-id>:<asset-manifest-url>:<backend-module-version>

Release catalogs should publish immutable manifest and entry URLs or change at least one cache-key component on every release. Emergency rollback can point the backend manifest at a previous immutable manifest URL or lower the enabled module version after the backend package rollback.

Browsers may still cache remote responses. Approved asset servers should use:

  • long cache lifetimes only for content-addressed immutable assets
  • short cache lifetimes or explicit revalidation for channel/latest manifest aliases
  • Cache-Control: no-store for emergency override manifests

Rollback

Remote WebUI rollback is metadata rollback, not package-manager rollback:

  • if the backend package install rolls back, the previous backend frontend metadata returns
  • if only remote assets are bad, publish a new manifest URL or revert the backend/frontend metadata to the last known good manifest
  • failed remote loading must degrade by omitting the remote module frontend, not by breaking the shell

Installer run records should eventually include remote asset manifest URLs, integrity, signature key ids, and load-test results when a plan enables a remote frontend.

Local And Development Behavior

Local development should keep using workspace/file dependencies and Vite. Remote loading is useful for integration testing release artifacts, not for day-to-day module UI development.

Development deployments may use unsigned catalogs and local asset servers only when signature/integrity enforcement is intentionally disabled. The remote loader itself still requires an integrity hash or a verifiable signature.

Follow-Up Slices

  1. Add a server-side remote-bundle policy flag and surface whether remote loading is enabled in platform metadata.
  2. Add CSP documentation/config generation for strict rebuild-only mode versus controlled remote-bundle mode.
  3. Add an installer/catalog preflight that validates remote WebUI asset manifests and records verified identity in installer run records.
  4. Add Playwright coverage for a signed test remote bundle, failed digest, bad module id, cache-key refresh, and fallback when the module is unavailable.
  5. Add release tooling to emit immutable remote asset manifests with digest, signature, key id, and rollback metadata.