- Introduced AGENTS.md, README.md, TASKS.md, and implementation_plan.md for Vexer, detailing mission, responsibilities, key components, and operational notes. - Established similar documentation structure for Vulnerability Explorer and Zastava modules, including their respective workflows, integrations, and observability notes. - Created risk scoring profiles documentation outlining the core workflow, factor model, governance, and deliverables. - Ensured all modules adhere to the Aggregation-Only Contract and maintain determinism and provenance in outputs.
		
			
				
	
	
	
		
			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 insessionStorage, 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,offlineBannerevents | Concelier WebService, Excititor WebService, Attestor metrics | 5 s heartbeat; gateway disables proxy buffering ( X-Accel-Buffering: no) and setsCache-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 usingLast-Event-ID. | 
| /console/telemetry/stream | metricSample,alert,collectorStatus | Observability aggregator | Gated by ui.telemetryscope; disabled whenCONSOLE_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_secondsP95 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.jsonbudgets; CI fails build on overflow. | 
| Component stylesheet | Warn ≥ 2 KB, fail ≥ 4 KB | angular.jsonbudgets; 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-uiwith 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).