14 KiB
		
	
	
	
	
	
	
	
			
		
		
	
	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.WebAngular 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 
stellacommands 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.
| Path | Purpose | Highlights | 
|---|---|---|
src/app/core/auth | 
DPoP + PKCE authentication, Authority session store, HTTP interceptors. | WebCrypto keygen (crypto.subtle), session metadata persisted in sessionStorage, DPoP nonce replay guard. | 
src/app/core/api | 
Typed API clients for Console gateway (/console/*) and downstream services. | 
DTOs for Scanner, Notify, Concelier exporters; fetch-based clients with abort signals. | 
src/app/core/config | 
Runtime 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/testing | 
Fixtures 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:installprimes dependencies without network audits;scripts/verify-chromium.jsensures headless Chromium availability for Karma. - Build budgets: 
angular.jsonenforces 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.jsonmerged 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<br/>(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<br/>(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-authwhen required, then refreshes UI caches (ui.tenant.switchlog). Gateway injectsX-Stella-Tenantheaders 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/downloadsmerges DevOps signed manifest and Offline Kit metadata; UI renders digest, signature, and CLI parity command. - Offline resilience: Gateway exposes 
/console/statusheartbeat. 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.
| Endpoint | Payload | Source | Behaviour | 
|---|---|---|---|
/console/status/stream | 
statusChanged, ingestionDelta, attestorQueue, offlineBanner events | 
Concelier WebService, Excititor WebService, Attestor metrics | 5 s heartbeat; gateway disables proxy buffering (X-Accel-Buffering: no) and sets Cache-Control: no-store. | 
/console/runs/{id}/stream | 
stateChanged, segmentProgress, deltaSummary, log | 
Scheduler WebService SSE fan-out | Event payloads carry traceId, runId, tenant; UI reconnects with exponential backoff and resumes using Last-Event-ID. | 
/console/telemetry/stream | 
metricSample, alert, collectorStatus | 
Observability aggregator | Gated 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: <seq>)
    GW->>SCHED: GET /runs/42/stream?since=<seq>
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 return204immediately; UI suppresses auto-reconnect to preserve resources. 
5 · Performance & Budgets
| Surface | Target | Enforcement | 
|---|---|---|
| First meaningful paint (dashboard) | ≤ 2.5 s on 4 vCPU offline runner | Lighthouse CI gate (DEVOPS-CONSOLE-23-001), ui_route_render_seconds P95 alert. | 
| Route hydration (feature shells) | ≤ 1.5 s after token acquisition | Angular Signals + lazy loading; route-level budgets tracked via custom telemetry. | 
| Initial bundle size | Warn ≥ 500 KB, fail ≥ 1 MB | angular.json budgets; CI fails build on overflow. | 
| Component stylesheet | Warn ≥ 2 KB, fail ≥ 4 KB | angular.json budgets; ensures Tailwind utilities stay tree-shaken. | 
| SSE heartbeat | Every 15 s max | Gateway emits comment heartbeats; UI resets timers on each frame. | 
Optimisation levers:
- Standalone components with 
ChangeDetectionStrategy.OnPushand 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.jsonincludes Authority issuer/client ID, gateway base URL, feature flags, telemetry endpoints, and offline hints. Operators can swap config by copyingsrc/config/config.sample.jsonand editing before build, or by rewriting the response at gateway runtime. - Deterministic install: Documented in 
src/Web/StellaOps.Web/docs/DeterministicInstall.md—npm run ci:installplus 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_FLAGStoggles 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+DPoPheader 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 asProblem+JSONwithERR_*codes. - Tenant propagation: 
X-Stella-Tenantheader derived from token; downstream services reject mismatches. Tenant switches logui.tenant.switchand require fresh-auth for privileged actions. - CSP & headers: Default CSP forbids third-party scripts, only allows same-origin 
connect-src. HSTS, Referrer-Policyno-referrer, andPermissions-Policyconfigured 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 whenCONSOLE_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 includeui.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 
traceIdso operators can jump from UI to backend logs using shared correlation IDs. 
9 · Integration Points & Dependencies
| Service | Console dependency | Notes | 
|---|---|---|
| Authority | OIDC, DPoP tokens, tenant catalog, fresh-auth | Requires client console-ui with scopes listed in security guide. | 
| Concelier WebService | /console/advisories, feed health, export triggers | 
Gateway must enforce Aggregation-Only guardrails and surface merge hashes. | 
| Excititor WebService | /console/vex, consensus overlays | 
SSE ticker shows provider deltas. | 
| Policy Engine | Findings views, policy previews, simulation diffs | Console never writes overlays; uses effective_finding_* data via API. | 
| Scheduler WebService | Runs dashboard, SSE streams, queue metrics | Heartbeat drives status ticker; cancellation actions require runs.manage. | 
| SBOM Service | SBOM explorer tree, component lookup | Responses cached per tenant; offline bundles preload snapshots. | 
| Attestor | Attestation verification, evidence links | Console displays verification status and CLI parity commands. | 
| DevOps downloads pipeline | Signed manifest for /console/downloads | 
Manifest 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).