StellaOps Console Architecture (Sprint 23)

Maps the Console implementation to the requirements captured in the Policy, Graph, Vulnerability Explorer, Orchestrator, and Notifications module documentation set.

Ownership: Console Guild • Docs Guild
Delivery scope: StellaOps.Web Angular workspace, Console Web Gateway routes (/console/*), Downloads manifest surfacing, SSE fan-out for Scheduler & telemetry.
Related docs: Console overview, Navigation, Runs workspace, Downloads, Console security posture, Console observability, Deployment guide

This dossier describes the end-to-end architecture of the StellaOps Console as delivered in Sprint 23. It covers the Angular workspace layout, API/gateway integration points, live-update channels, performance budgets, offline workflows, and observability hooks needed to keep the console deterministic and air-gap friendly.


1 · Mission & Boundaries

  • Present an operator-grade UI that surfaces Concelier, Excititor, Policy Engine, Scheduler, Attestor, and SBOM Service data without mutating aggregation or policy state.
  • Enforce Authority-issued scopes and tenant claims on every call through the Console Web Gateway.
  • Deliver deterministic builds (< 1 MB initial bundle) that can be mirrored in Offline Kits, with runtime configuration loaded from /config.json.
  • Stream live status (ingestion deltas, scheduler progress, telemetry) via SSE with graceful degradation to polling when offline or throttled.
  • Maintain CLI parity by embedding stella commands alongside interactive actions.

Non-goals: authoring ingestion logic, mutating Policy overlays, exposing internal Mongo collections, or performing cryptographic signing in-browser.


2 · Workspace & Packages

The console is implemented in src/Web/StellaOps.Web, an Angular 17 workspace built on standalone components and Signals.

PathPurposeHighlights
src/app/core/authDPoP + PKCE authentication, Authority session store, HTTP interceptors.WebCrypto keygen (crypto.subtle), session metadata persisted in sessionStorage, DPoP nonce replay guard.
src/app/core/apiTyped API clients for Console gateway (/console/*) and downstream services.DTOs for Scanner, Notify, Concelier exporters; fetch-based clients with abort signals.
src/app/core/configRuntime configuration loader (/config.json), feature flag gating.Supports air-gap overrides and injects API base URLs, Authority issuer/client.
src/app/features/*Route-level shells (auth bootstrap, scans detail, notifications inbox, Trivy DB settings).Each feature is a standalone module with lazy loading and Angular Signals state.
src/app/testingFixtures and harnesses used in unit tests and storybook-like previews.Deterministic data used for Playwright and Jest scenarios.

Workspace characteristics:

  • Toolchain: Node 20.11+, npm 10.2+, Angular CLI 17.3. npm run ci:install primes dependencies without network audits; scripts/verify-chromium.js ensures headless Chromium availability for Karma.
  • Build budgets: angular.json enforces 500 KB warning / 1 MB error for initial bundle and 2 KB warning / 4 KB error per component stylesheet. Output hashing (outputHashing: all) keeps assets cache-safe.
  • Testing: Karma + Jasmine for unit tests, Playwright for e2e with dev server autotuning. CI (DEVOPS-CONSOLE-23-001) runs Lighthouse against the production bundle.
  • Runtime config: /config.json merged at bootstrap; gateways can rewrite it on the fly to avoid rebuilding for environment changes.

3 · Runtime Topology & Data Flow

The console SPA relies on the Console Web Gateway to proxy tenant-scoped API calls to downstream services. Tenant isolation and Aggregation-Only guardrails are enforced at every hop.

graph TD
    subgraph Browser["Browser (Angular SPA)"]
        UI[Console Shell
(Signals, Feature Modules)] SSE[EventSource / SSE Clients] end subgraph Gateway["Console Web Gateway"] Router[Minimal API / ASP.NET Core Router] StatusCache[Status Cache & Manifest signer] end Authority[Authority
(DPoP + PKCE)] Concelier[Concelier.WebService] Excititor[Excititor.WebService] Scheduler[Scheduler.WebService] Policy[Policy Engine API] SBOM[SBOM Service] Attestor[Attestor API] Downloads[Downloads Manifest Store] UI -->|/config.json| Gateway UI -->|/console/* (Bearer+DPoP)| Router SSE -->|/console/status/stream| Router Router --> Authority Router --> Concelier Router --> Excititor Router --> Scheduler Router --> Policy Router --> SBOM Router --> Attestor Router --> Downloads StatusCache -.-> Gateway Gateway -.-> UI

Key interactions:

  • Auth bootstrap: UI retrieves Authority metadata and exchanges an authorization code + PKCE verifier for a DPoP-bound token (aud=console, tenant=<id>). Tokens expire in 120 s; refresh tokens rotate, triggering new DPoP proofs.
  • Tenant switch: Picker issues Authority /fresh-auth when required, then refreshes UI caches (ui.tenant.switch log). Gateway injects X-Stella-Tenant headers downstream.
  • Aggregation-only reads: Gateway proxies /console/advisories, /console/vex, /console/findings, etc., without mutating Concelier or Policy data. Provenance badges and merge hashes come directly from upstream responses.
  • Downloads parity: /console/downloads merges DevOps signed manifest and Offline Kit metadata; UI renders digest, signature, and CLI parity command.
  • Offline resilience: Gateway exposes /console/status heartbeat. If unavailable, UI enters offline mode, disables SSE, and surfaces CLI fallbacks.

4 · Live Updates & SSE Design

Live surfaces use HTTP/1.1 SSE with heartbeat frames to keep operators informed without polling storms.

EndpointPayloadSourceBehaviour
/console/status/streamstatusChanged, ingestionDelta, attestorQueue, offlineBanner eventsConcelier WebService, Excititor WebService, Attestor metrics5 s heartbeat; gateway disables proxy buffering (X-Accel-Buffering: no) and sets Cache-Control: no-store.
/console/runs/{id}/streamstateChanged, segmentProgress, deltaSummary, logScheduler WebService SSE fan-outEvent payloads carry traceId, runId, tenant; UI reconnects with exponential backoff and resumes using Last-Event-ID.
/console/telemetry/streammetricSample, alert, collectorStatusObservability aggregatorGated by ui.telemetry scope; disabled when CONSOLE_TELEMETRY_SSE_ENABLED=false.

Sequence overview:

sequenceDiagram
    autonumber
    participant UI as Console SPA
    participant GW as Console Gateway
    participant SCHED as Scheduler WebService

    UI->>GW: GET /console/runs/42/stream (Authorization + DPoP)
    GW->>SCHED: GET /runs/42/stream (X-Stella-Tenant)
    SCHED-->>GW: event: stateChanged data: {...}
    GW-->>UI: event: stateChanged data: {..., traceId}
    Note over UI,GW: Gateway injects retry-after + heartbeat every 15s
    UI-->>GW: (disconnect)
    UI->>GW: GET /console/runs/42/stream (Last-Event-ID: )
    GW->>SCHED: GET /runs/42/stream?since=

Offline behaviour:

  • If SSE fails three times within 60 s, UI falls back to polling (/console/status, /console/runs/{id}) every 30 s and shows an amber banner.
  • When console.offlineMode=true, SSE endpoints return 204 immediately; UI suppresses auto-reconnect to preserve resources.

5 · Performance & Budgets

SurfaceTargetEnforcement
First meaningful paint (dashboard)≤ 2.5 s on 4 vCPU offline runnerLighthouse CI gate (DEVOPS-CONSOLE-23-001), ui_route_render_seconds P95 alert.
Route hydration (feature shells)≤ 1.5 s after token acquisitionAngular Signals + lazy loading; route-level budgets tracked via custom telemetry.
Initial bundle sizeWarn ≥ 500 KB, fail ≥ 1 MBangular.json budgets; CI fails build on overflow.
Component stylesheetWarn ≥ 2 KB, fail ≥ 4 KBangular.json budgets; ensures Tailwind utilities stay tree-shaken.
SSE heartbeatEvery 15 s maxGateway emits comment heartbeats; UI resets timers on each frame.

Optimisation levers:

  • Standalone components with ChangeDetectionStrategy.OnPush and Angular Signals avoid zone.js churn.
  • fetch + AbortController guard double fetches.
  • Assets served with immutable caching (cache-control: public, max-age=31536000, immutable) thanks to hashed filenames.
  • Compression (gzip/brotli) enabled at gateway; offline bundles include precompressed assets.
  • Command palette, tenants, and filters rely on IndexedDB caches to avoid refetching static metadata.

6 · Offline & Configuration Workflows

  • Config manifest: /config.json includes Authority issuer/client ID, gateway base URL, feature flags, telemetry endpoints, and offline hints. Operators can swap config by copying src/config/config.sample.json and editing before build, or by rewriting the response at gateway runtime.
  • Deterministic install: Documented in src/Web/StellaOps.Web/docs/DeterministicInstall.mdnpm run ci:install plus Chromium provisioning ensures offline runners reproduce builds.
  • Offline Kit parity: UI validates downloads manifest signatures (cosign) and surfaces snapshot timestamps per tenant. When offline, buttons switch to CLI snippets (stella runs export, stella downloads sync).
  • Feature flags: CONSOLE_FEATURE_FLAGS toggles modules (runs, downloads, telemetry); offline bundles include flag manifest so UI can render only supported panes.
  • Snapshot awareness: Global banner shows snapshot timestamp and disables actions needing Authority fresh-auth when running in sealed mode.

7 · Security & Tenancy

  • DPoP + PKCE: Every request carries Authorization + DPoP header and gateway enforces nonce replay protection. Private keys live in IndexedDB and never leave the browser.
  • Scope enforcement: Gateway checks scope claims before proxying (ui.read, runs.manage, downloads.read, etc.) and propagates denials as Problem+JSON with ERR_* codes.
  • Tenant propagation: X-Stella-Tenant header derived from token; downstream services reject mismatches. Tenant switches log ui.tenant.switch and require fresh-auth for privileged actions.
  • CSP & headers: Default CSP forbids third-party scripts, only allows same-origin connect-src. HSTS, Referrer-Policy no-referrer, and Permissions-Policy configured via gateway (deploy/console.md).
  • Evidence handling: Downloads never cache secrets; UI renders SHA-256 + signature references and steers users to CLI for sensitive exports.
  • See Console security posture for full scope table and threat model alignment.

8 · Observability & Telemetry

  • Metrics: Prometheus scrape at /metrics (enabled when CONSOLE_METRICS_ENABLED=true). Key histograms/counters documented in Console observability (ui_route_render_seconds, ui_tenant_switch_total, ui_download_manifest_refresh_seconds).
  • Logs: Structured JSON with traceId, tenant, action. Categories include ui.action, ui.tenant.switch, ui.security.anomaly. Sampled per feature flag to balance volume.
  • Traces: Browser OTLP exporter ships spans to configured collector; gateway adds server-side spans so traces cross client/server boundary.
  • Alerts: Burn-rate rules for route latency, telemetry batch failures, download manifest refresh, and SSE stalls integrate with Notifier.
  • Correlation: SSE events carry traceId so operators can jump from UI to backend logs using shared correlation IDs.

9 · Integration Points & Dependencies

ServiceConsole dependencyNotes
AuthorityOIDC, DPoP tokens, tenant catalog, fresh-authRequires client console-ui with scopes listed in security guide.
Concelier WebService/console/advisories, feed health, export triggersGateway must enforce Aggregation-Only guardrails and surface merge hashes.
Excititor WebService/console/vex, consensus overlaysSSE ticker shows provider deltas.
Policy EngineFindings views, policy previews, simulation diffsConsole never writes overlays; uses effective_finding_* data via API.
Scheduler WebServiceRuns dashboard, SSE streams, queue metricsHeartbeat drives status ticker; cancellation actions require runs.manage.
SBOM ServiceSBOM explorer tree, component lookupResponses cached per tenant; offline bundles preload snapshots.
AttestorAttestation verification, evidence linksConsole displays verification status and CLI parity commands.
DevOps downloads pipelineSigned manifest for /console/downloadsManifest signatures validated with cosign key shipped in Offline Kit.

10 · Compliance Checklist

  • [ ] Frontend package map (core/auth/api/config + feature shells) documented with ownership and tooling details.
  • [ ] Data flow diagram captures SPA ↔ Gateway ↔ downstream services with tenant & scope enforcement notes.
  • [ ] SSE design documented (endpoints, payloads, heartbeat, retry/backoff, offline fallback).
  • [ ] Performance budgets (< 1 MB initial bundle, route hydration ≤ 1.5 s, SSE heartbeat) stated alongside enforcement mechanisms.
  • [ ] Offline workflows (/config.json, deterministic install, Offline Kit parity) described with operator guidance.
  • [ ] Security section references DPoP, scopes, CSP, evidence handling, and tenancy propagation.
  • [ ] Observability metrics/logs/traces coverage listed with alert hooks.
  • [ ] Integration dependencies table links Console responsibilities to upstream services.
  • [ ] Document cross-references validated (UI guides, security, observability, deployment).
  • [ ] Last updated timestamp refreshed after review.

Last updated: 2025-10-27 (Sprint 23).