Align AOC tasks for Excititor and Concelier
This commit is contained in:
@@ -1,22 +1,22 @@
|
||||
# Console UI agent guide
|
||||
|
||||
## Mission
|
||||
The Console presents operator dashboards for scans, policies, VEX evidence, runtime posture, and admin workflows.
|
||||
|
||||
## Key docs
|
||||
- [Module README](./README.md)
|
||||
- [Architecture](./architecture.md)
|
||||
- [Implementation plan](./implementation_plan.md)
|
||||
- [Task board](./TASKS.md)
|
||||
|
||||
## How to get started
|
||||
1. Open ../../implplan/SPRINTS.md and locate the stories referencing this module.
|
||||
2. Review ./TASKS.md for local follow-ups and confirm status transitions (TODO → DOING → DONE/BLOCKED).
|
||||
3. Read the architecture and README for domain context before editing code or docs.
|
||||
4. Coordinate cross-module changes in the main /AGENTS.md description and through the sprint plan.
|
||||
|
||||
## Guardrails
|
||||
- Honour the Aggregation-Only Contract where applicable (see ../../ingestion/aggregation-only-contract.md).
|
||||
- Preserve determinism: sort outputs, normalise timestamps (UTC ISO-8601), and avoid machine-specific artefacts.
|
||||
- Keep Offline Kit parity in mind—document air-gapped workflows for any new feature.
|
||||
# Console UI agent guide
|
||||
|
||||
## Mission
|
||||
The Console presents operator dashboards for scans, policies, VEX evidence, runtime posture, and admin workflows.
|
||||
|
||||
## Key docs
|
||||
- [Module README](./README.md)
|
||||
- [Architecture](./architecture.md)
|
||||
- [Implementation plan](./implementation_plan.md)
|
||||
- [Task board](./TASKS.md)
|
||||
|
||||
## How to get started
|
||||
1. Open ../../implplan/SPRINTS.md and locate the stories referencing this module.
|
||||
2. Review ./TASKS.md for local follow-ups and confirm status transitions (TODO → DOING → DONE/BLOCKED).
|
||||
3. Read the architecture and README for domain context before editing code or docs.
|
||||
4. Coordinate cross-module changes in the main /AGENTS.md description and through the sprint plan.
|
||||
|
||||
## Guardrails
|
||||
- Honour the Aggregation-Only Contract where applicable (see ../../ingestion/aggregation-only-contract.md).
|
||||
- Preserve determinism: sort outputs, normalise timestamps (UTC ISO-8601), and avoid machine-specific artefacts.
|
||||
- Keep Offline Kit parity in mind—document air-gapped workflows for any new feature.
|
||||
- Update runbooks/observability assets when operational characteristics change.
|
||||
@@ -1,41 +1,41 @@
|
||||
# StellaOps Console UI
|
||||
|
||||
The Console presents operator dashboards for scans, policies, VEX evidence, runtime posture, and admin workflows.
|
||||
|
||||
## Responsibilities
|
||||
- Render real-time status for ingestion, scanning, policy, and exports via SSE.
|
||||
- Provide policy editor, SBOM explorer, and advisory views with accessibility compliance.
|
||||
- Integrate with Authority for fresh-auth and scope enforcement.
|
||||
- Support offline bundles with deterministic build outputs.
|
||||
|
||||
## Key components
|
||||
- Angular 17 workspace under `src/UI/StellaOps.UI`.
|
||||
- Signals-based state management with `@ngrx/signals` store.
|
||||
- API client generator (`core/api`).
|
||||
|
||||
## Integrations & dependencies
|
||||
- Backend APIs (Scanner, Policy, Notify, Export Center, Attestor).
|
||||
- Authority for DPoP-protected calls.
|
||||
- Telemetry streams for observability dashboards.
|
||||
|
||||
## Operational notes
|
||||
- Auth smoke tests in ./operations/auth-smoke.md.
|
||||
- Console architecture doc for layout and SSE fan-out.
|
||||
- Accessibility and security guides in ../../ui/ & ../../security/.
|
||||
|
||||
## Related resources
|
||||
- ./operations/auth-smoke.md
|
||||
- ./console-architecture.md
|
||||
|
||||
## Backlog references
|
||||
- DOCS-CONSOLE-23-001 … DOCS-CONSOLE-23-003 baseline (done).
|
||||
- CONSOLE-OBS-52-001 tasks for observability updates.
|
||||
|
||||
## Epic alignment
|
||||
- **Epic 2 – Policy Engine & Editor:** deliver deterministic policy authoring, simulation, and explain UX.
|
||||
- **Epic 4 – Policy Studio:** implement registry workspace, approvals, and promotion workflows.
|
||||
- **Epic 5 – SBOM Graph Explorer:** surface graph navigation, overlays, and diff tools.
|
||||
- **Epic 6 – Vulnerability Explorer:** provide triage dashboards, findings ledger views, and audit exports.
|
||||
- **Epic 8 – Advisory AI:** embed advisory summaries, explanations, and remediation hints with citations.
|
||||
- **Epic 9 – Orchestrator Dashboard:** expose source/job monitoring with throttling and replay controls.
|
||||
- **Epic 11 – Notifications Studio:** deliver notifications workspace with rule/channel previews and audits.
|
||||
# StellaOps Console UI
|
||||
|
||||
The Console presents operator dashboards for scans, policies, VEX evidence, runtime posture, and admin workflows.
|
||||
|
||||
## Responsibilities
|
||||
- Render real-time status for ingestion, scanning, policy, and exports via SSE.
|
||||
- Provide policy editor, SBOM explorer, and advisory views with accessibility compliance.
|
||||
- Integrate with Authority for fresh-auth and scope enforcement.
|
||||
- Support offline bundles with deterministic build outputs.
|
||||
|
||||
## Key components
|
||||
- Angular 17 workspace under `src/UI/StellaOps.UI`.
|
||||
- Signals-based state management with `@ngrx/signals` store.
|
||||
- API client generator (`core/api`).
|
||||
|
||||
## Integrations & dependencies
|
||||
- Backend APIs (Scanner, Policy, Notify, Export Center, Attestor).
|
||||
- Authority for DPoP-protected calls.
|
||||
- Telemetry streams for observability dashboards.
|
||||
|
||||
## Operational notes
|
||||
- Auth smoke tests in ./operations/auth-smoke.md.
|
||||
- Console architecture doc for layout and SSE fan-out.
|
||||
- Accessibility and security guides in ../../ui/ & ../../security/.
|
||||
|
||||
## Related resources
|
||||
- ./operations/auth-smoke.md
|
||||
- ./console-architecture.md
|
||||
|
||||
## Backlog references
|
||||
- DOCS-CONSOLE-23-001 … DOCS-CONSOLE-23-003 baseline (done).
|
||||
- CONSOLE-OBS-52-001 tasks for observability updates.
|
||||
|
||||
## Epic alignment
|
||||
- **Epic 2 – Policy Engine & Editor:** deliver deterministic policy authoring, simulation, and explain UX.
|
||||
- **Epic 4 – Policy Studio:** implement registry workspace, approvals, and promotion workflows.
|
||||
- **Epic 5 – SBOM Graph Explorer:** surface graph navigation, overlays, and diff tools.
|
||||
- **Epic 6 – Vulnerability Explorer:** provide triage dashboards, findings ledger views, and audit exports.
|
||||
- **Epic 8 – Advisory AI:** embed advisory summaries, explanations, and remediation hints with citations.
|
||||
- **Epic 9 – Orchestrator Dashboard:** expose source/job monitoring with throttling and replay controls.
|
||||
- **Epic 11 – Notifications Studio:** deliver notifications workspace with rule/channel previews and audits.
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# Task board — Console UI
|
||||
|
||||
> Local tasks should link back to ./AGENTS.md and mirror status updates into ../../TASKS.md when applicable.
|
||||
|
||||
| ID | Status | Owner(s) | Description | Notes |
|
||||
|----|--------|----------|-------------|-------|
|
||||
| CONSOLE UI-DOCS-0001 | TODO | Docs Guild | Validate that ./README.md aligns with the latest release notes. | See ./AGENTS.md |
|
||||
| CONSOLE UI-OPS-0001 | TODO | Ops Guild | Review runbooks/observability assets after next sprint demo. | Sync outcomes back to ../../TASKS.md |
|
||||
| CONSOLE UI-ENG-0001 | TODO | Module Team | Cross-check implementation plan milestones against ../../implplan/SPRINTS.md. | Update status via ./AGENTS.md workflow |
|
||||
# Task board — Console UI
|
||||
|
||||
> Local tasks should link back to ./AGENTS.md and mirror status updates into ../../TASKS.md when applicable.
|
||||
|
||||
| ID | Status | Owner(s) | Description | Notes |
|
||||
|----|--------|----------|-------------|-------|
|
||||
| CONSOLE UI-DOCS-0001 | TODO | Docs Guild | Validate that ./README.md aligns with the latest release notes. | See ./AGENTS.md |
|
||||
| CONSOLE UI-OPS-0001 | TODO | Ops Guild | Review runbooks/observability assets after next sprint demo. | Sync outcomes back to ../../TASKS.md |
|
||||
| CONSOLE UI-ENG-0001 | TODO | Module Team | Cross-check implementation plan milestones against ../../implplan/SPRINTS.md. | Update status via ./AGENTS.md workflow |
|
||||
|
||||
@@ -1,366 +1,366 @@
|
||||
# component_architecture_web_ui.md — **Stella Ops Web UI** (2025Q4)
|
||||
|
||||
> Consolidates Console requirements documented across the Policy, Graph, Vulnerability Explorer, Advisory AI, Orchestrator, and Notifications module guides and implementation plans.
|
||||
|
||||
> **Scope.** Implementation‑ready architecture for the **Angular SPA** that operators and developers use to drive Stella Ops. This document defines UX surfaces, module boundaries, data flows, auth, RBAC, real‑time updates, performance targets, i18n/a11y, security headers, testing and deployment. The UI is a *consumer* of backend APIs (Scanner, Policy, Excititor, Concelier, Attestor, Authority) and never performs scanning, merging, or signing on its own.
|
||||
|
||||
---
|
||||
|
||||
## 0) Mission & non‑goals
|
||||
|
||||
**Mission.** Provide a **fast, explainable** console for:
|
||||
|
||||
* Scans (status, SBOMs, diffs, EntryTrace, attestation).
|
||||
* Policy management (rules, exemptions, VEX consumption view).
|
||||
* Vulnerability intel (Concelier status), VEX consensus exploration (Excititor).
|
||||
* Runtime posture (Zastava observer + admission).
|
||||
* Admin operations (tenants, tokens, quotas, licensing posture).
|
||||
|
||||
**Non‑goals.** No client‑side crypto signing; no Docker/CRI access; no direct registry access beyond fetching static assets or OCI referrer summaries exposed by backend.
|
||||
|
||||
---
|
||||
|
||||
## 1) Technology baseline
|
||||
|
||||
* **Framework**: Angular 17+ (Stand‑alone APIs / Signals), TypeScript 5.
|
||||
* **Styling**: Tailwind CSS + headless component patterns; CSS variables for theming.
|
||||
* **Charts**: Lightweight SVG (uPlot or Apache ECharts via on‑demand import).
|
||||
* **State**: Angular **Signals** + `@ngrx/signals` store for cross‑page slices.
|
||||
* **Transport**: `fetch` + RxJS interop; **SSE** (EventSource) for progress streams.
|
||||
* **Build**: Angular CLI + Vite builder.
|
||||
* **Testing**: Jest + Testing Library, Playwright for e2e.
|
||||
* **Packaging**: Containerized NGINX (immutable assets, ETag + content hashing).
|
||||
|
||||
---
|
||||
|
||||
## 2) High‑level module map
|
||||
|
||||
```
|
||||
/app
|
||||
├─ core/ # bootstrap, config, auth, http, error boundary, i18n
|
||||
├─ shared/ # UI kit (tables, code-viewers, badges), pipes
|
||||
├─ dashboard/ # live tiles, fleet KPIs, feed/vex age, queue depth
|
||||
├─ scans/ # scan list, detail, SBOM viewer, diff-by-layer, EntryTrace
|
||||
├─ runtime/ # Zastava posture, drift events, admission decisions
|
||||
├─ policy/ # rules editor (YAML/Rego), exemptions, previews
|
||||
├─ vex/ # VEX explorer (claims, consensus, conflicts)
|
||||
├─ concelier/ # source health, export cursors, rebuild/export triggers
|
||||
├─ attest/ # attestation proofs, verification bundles, Rekor links
|
||||
├─ admin/ # tenants, roles, clients, quotas, licensing posture
|
||||
└─ plugins/ # route plug-ins (lazy remote modules, governed)
|
||||
```
|
||||
|
||||
Each feature folder builds as a **standalone route** (lazy loaded). All HTTP shapes live in `core/api/` clients with shared DTOs.
|
||||
|
||||
---
|
||||
|
||||
## 3) Navigation & key views
|
||||
|
||||
### 3.1 Dashboard
|
||||
|
||||
* **Tiles**: “New criticals (24h)”, “VEX suppressions applied”, “Attested SBOMs (7d)”, “Feed age per provider”, “Scanner queue depth”, “Admission events”.
|
||||
* **Trends**: sparkline for vulns/day, pass/fail rates, attestation throughput.
|
||||
|
||||
### 3.2 Scans
|
||||
|
||||
* **Scan list** with status, image digest, repo, time, artifacts, attestation badge.
|
||||
* **Scan detail**:
|
||||
|
||||
* **SBOM viewer**: Inventory/Usage toggle; component table (virtualized), filters by package type, severity, source.
|
||||
* **Diff by layer**: A→B change grid (added/removed/upgraded), grouped by introducing/removing layer; tooltips show provenance and links to layer SBOM fragment.
|
||||
* **EntryTrace**: shell chain with file:line breadcrumbs; jump‑to source viewer (read‑only, hexdump fallback).
|
||||
* **Attestation**: Rekor UUID, index, inclusion proof; **Verify** button calls Attestor `/verify`.
|
||||
* **Export**: download buttons (CycloneDX JSON, Protobuf, SPDX JSON); size shown; SHA‑256 inline.
|
||||
|
||||
### 3.3 Runtime (Zastava)
|
||||
|
||||
* **Observer timeline**: container start/stop, drift, policy violations; faceted by namespace/owner.
|
||||
* **Live process view**: top N processes, loaded libs summary vs Usage SBOM.
|
||||
* **Admission decisions**: per‑namespace rules, allow/deny events, cache TTL, reasons.
|
||||
|
||||
### 3.4 Policy
|
||||
|
||||
* **Policy bundles**: active vs staged; diff viewer with change summary.
|
||||
* **Editors**:
|
||||
|
||||
* YAML rules (ignore lists, thresholds, vendor precedence overrides).
|
||||
* Rego blocks (advanced gates) with **WASM** preview evaluator (client‑side sandbox) for “preview” against sample SBOMs.
|
||||
* **VEX inclusion controls**: weight sliders (visualization only), provider allow/deny toggles.
|
||||
* **Preview**: select SBOM (or image digest) → show verdict under staged policy.
|
||||
|
||||
### 3.5 Excititor
|
||||
|
||||
* **Claims explorer**: search by vulnId/productKey/provider; show raw claim (status, justification, evidence).
|
||||
* **Consensus view**: rollup per (vuln, product) with accepted/rejected sources, weights, timestamps.
|
||||
* **Conflicts**: grid of top conflicts; filters for justification gates failed.
|
||||
|
||||
### 3.6 Concelier
|
||||
|
||||
* **Sources** table: staleness, last run, errors.
|
||||
* **Advisory search**: by CVE/alias; show normalized affected ranges.
|
||||
* **Exports**: trigger full/delta JSON/Trivy DB; show manifest digests and Rekor link if attested.
|
||||
|
||||
### 3.7 Attest
|
||||
|
||||
* **Proofs list**: last 7 days Rekor entries; filter by kind (sbom/report/vex).
|
||||
* **Verification**: paste UUID or upload bundle → verify; result with explanations (chain, Merkle path).
|
||||
|
||||
### 3.8 Admin
|
||||
|
||||
* **Tenants/Installations**: view/edit, isolation hints.
|
||||
* **Clients & roles**: Authority clients, role→scope mapping, rotation hints.
|
||||
* **Quotas**: per license plan, counters, throttle events.
|
||||
* **Licensing posture**: last PoE introspection snapshot (redacted), release window.
|
||||
|
||||
---
|
||||
|
||||
## 4) Auth, sessions & RBAC
|
||||
|
||||
### 4.1 OIDC flow
|
||||
|
||||
* **Authorization Code + PKCE** to **Authority**.
|
||||
* **ID Token** for UX identity; **Access Token** (OpTok) for APIs (2–5 min TTL).
|
||||
* **DPoP (browser)**: generate ephemeral **WebCrypto** keypair; store public JWK in memory, private key in **IndexedDB** (non‑exportable if platform allows). Access token includes `cnf.jkt`; each API call adds `DPoP` proof; handle nonce challenges automatically.
|
||||
* **Refresh**: optional DPoP‑bound refresh tokens with rotation; otherwise silent renew.
|
||||
|
||||
### 4.2 RBAC
|
||||
|
||||
* Roles (`ui.read`, `ui.admin`, plus service roles) are embedded in ID token or fetched via `/me` endpoint.
|
||||
* **Route guards** enforce access; **feature flags** hide admin pages for non‑admins.
|
||||
|
||||
### 4.3 Session storage
|
||||
|
||||
* Access tokens & refresh metadata in memory; persist **only** minimal session (subject, expiries) in `sessionStorage`. Never persist raw JWTs to `localStorage`. Use **SameSite=Lax** cookies for anti‑CSRF if cookies are required (prefer pure bearer headers + DPoP).
|
||||
|
||||
---
|
||||
|
||||
## 5) HTTP layer & API clients
|
||||
|
||||
* **`core/http/api-client.ts`** centralizes:
|
||||
|
||||
* Base URLs (Scanner, Excititor, Concelier, Attestor).
|
||||
* **Retry** policies on idempotent GETs (backoff + jitter).
|
||||
* **Problem+JSON** parser → uniform error toasts with correlation ID.
|
||||
* **SSE** helper (EventSource) with auto‑reconnect & backpressure.
|
||||
* **DPoP** injector & nonce handling.
|
||||
|
||||
* Typed API clients (DTOs in `core/api/models.ts`):
|
||||
|
||||
* `ScannerApi`, `PolicyApi`, `ExcititorApi`, `ConcelierApi`, `AttestorApi`, `AuthorityApi`.
|
||||
|
||||
**DTO examples (abbrev):**
|
||||
|
||||
```ts
|
||||
export type ImageDigest = `sha256:${string}`;
|
||||
export interface ScanSummary {
|
||||
imageDigest: ImageDigest; createdAt: string;
|
||||
artifacts: { view: 'inventory'|'usage'; format: 'cdx-json'|'cdx-pb'|'spdx-json'; sha256: string; size: number }[];
|
||||
status: 'queued'|'running'|'completed'|'error';
|
||||
rekor?: { uuid: string; index?: number; url?: string };
|
||||
}
|
||||
export interface DiffEntry {
|
||||
key: string; change: 'added'|'removed'|'upgraded'|'downgraded';
|
||||
fromVersion?: string; toVersion?: string; layer: string; usedByEntrypoint?: boolean;
|
||||
}
|
||||
export interface VexConsensus {
|
||||
vulnId: string; productKey: string; rollupStatus: 'affected'|'not_affected'|'fixed'|'under_investigation';
|
||||
sources: { providerId: string; status: string; weight: number; accepted: boolean; reason: string }[];
|
||||
}
|
||||
```
|
||||
|
||||
*Upcoming:* `NotifyApi` consumes delivery history using the new paginated envelope returned by `/api/v1/notify/deliveries`.
|
||||
|
||||
```ts
|
||||
export interface NotifyDeliveryListResponse {
|
||||
items: NotifyDelivery[];
|
||||
count: number;
|
||||
continuationToken?: string;
|
||||
}
|
||||
|
||||
export interface NotifyDelivery {
|
||||
deliveryId: string;
|
||||
ruleId: string;
|
||||
actionId: string;
|
||||
status: 'pending'|'sent'|'failed'|'throttled'|'digested'|'dropped';
|
||||
rendered: NotifyDeliveryRendered;
|
||||
metadata: Record<string, string>; // includes channelType, target, previewProvider, traceId, and provider-specific entries
|
||||
createdAt: string;
|
||||
sentAt?: string;
|
||||
completedAt?: string;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6) State, caching & real‑time
|
||||
|
||||
* **Per‑page stores** (Signals) for list filters, pagination, and selected entities.
|
||||
* **Normalized caches** keyed by `(imageDigest, view, format)`; artifacts are downloaded via pre‑signed URLs from Scanner and streamed; SHA‑256 verified client‑side before exposing “verified” badge.
|
||||
* **SSE channels**:
|
||||
|
||||
* `/scans/{id}/events` → progress log.
|
||||
* `/runtime/events/stream` (optional) → live drift/admission feed (rate‑limited).
|
||||
* **Cache invalidation** on job completion or explicit “refresh”.
|
||||
|
||||
---
|
||||
|
||||
## 7) SBOM viewing & diff UX
|
||||
|
||||
* **Huge tables** rendered with **virtual scrolling** (CDK Virtual Scroll); sort/filter performed client‑side for ≤ 20k rows; beyond that, server‑side queries via BOM‑Index endpoints.
|
||||
* **Component row** shows purl, version, origin (OS pkg / metadata / linker / attested), licenses, and **used** badge (Usage view).
|
||||
* **Diff**: compact heatmap per layer; clicking opens a right‑pane with evidence: introducing paths, file hashes, VEX notes (from Excititor consensus) and links to advisories (Concelier).
|
||||
|
||||
---
|
||||
|
||||
## 8) Policy editor & VEX integration
|
||||
|
||||
* **YAML editor**: Monaco‑based with schema hints; previews show which rules matched.
|
||||
* **Rego editor**: Monaco with WASM‑OPA sandbox for read‑only evaluation on sample SBOMs.
|
||||
* **VEX toggles**: per‑provider enable/disable; “explain” drawer shows why a claim was accepted/rejected (justification gate, signature state, weight).
|
||||
* **Staged → Active** promotion is a two‑step flow with confirmation and automatic policy digest computation.
|
||||
|
||||
---
|
||||
|
||||
## 9) Accessibility, i18n & theming
|
||||
|
||||
* **A11y**: WCAG 2.2 AA; keyboard navigation, focus management, ARIA roles; color‑contrast tokens verified by unit tests.
|
||||
* **I18n**: Angular i18n + runtime translation loader (`/locales/{lang}.json`); dates/numbers localized via `Intl`.
|
||||
* **Languages**: English default; Bulgarian, German, Japanese as initial additions.
|
||||
* **Theming**: dark/light via CSS variables; persisted in `prefers-color-scheme` aware store.
|
||||
|
||||
---
|
||||
|
||||
## 10) Performance budgets
|
||||
|
||||
* **TTI** ≤ 1.5 s on 4G/slow CPU (first visit), ≤ 0.6 s repeat (HTTP/2, cached).
|
||||
* **JS** initial < 300 KB gz (lazy routes).
|
||||
* **SBOM list**: render 10k rows in < 70 ms with virtualization; filter in < 150 ms.
|
||||
* **Diff view**: compute client‑side grouping for 5k changes in < 120 ms.
|
||||
|
||||
Techniques: route‑level code splitting; `ChangeDetectionStrategy.OnPush`; Signals; server compression (zstd/gzip), immutable assets with long max‑age (cache busting via hashes).
|
||||
|
||||
---
|
||||
|
||||
## 11) Security headers & CSP
|
||||
|
||||
* **CSP**: `default-src 'self'; connect-src 'self' https://*.internal; img-src 'self' data:; script-src 'self'; style-src 'self' 'unsafe-inline'; frame-ancestors 'none';`
|
||||
* **HSTS** enabled at gateway.
|
||||
* **Referrer Policy**: `no-referrer`.
|
||||
* **X‑Frame‑Options**: `DENY`.
|
||||
* **COOP/COEP** to enable faster cross‑origin isolation (for WASM OPA).
|
||||
* **Subresource Integrity (SRI)** for third‑party fonts (minimize third‑party).
|
||||
|
||||
---
|
||||
|
||||
## 12) Error handling & UX hygiene
|
||||
|
||||
* **Global error boundary** surfaces Problem+JSON `title/detail/instance` with correlation ID.
|
||||
* **Retry toast** for 429 (quota throttles) with backoff timer.
|
||||
* **Auth expiry**: pre‑emptive refresh; unobtrusive banner when < 60 s TTL; re‑login modal if refresh fails.
|
||||
* **Network down**: offline banner with queued actions (idempotent resubmits).
|
||||
* **File verify**: show SHA‑256 mismatch warnings if artifact altered in transit.
|
||||
|
||||
---
|
||||
|
||||
## 13) Observability
|
||||
|
||||
* **Front‑end telemetry** (OpenTelemetry Web): route timings, API latency by service, error counts; sampled to 1–5% and shipped to backend OTLP endpoint.
|
||||
* **User actions** logged anonymously (no PII): “policy promote”, “scan export”, “attest verify”.
|
||||
* **Metrics dash** in admin shows SLOs and recent front‑end errors.
|
||||
|
||||
---
|
||||
|
||||
## 14) Testing strategy
|
||||
|
||||
* **Unit**: pure component logic via Jest + Testing Library (no TestBed when possible).
|
||||
* **Component harness** for table, code viewer, diff heatmap.
|
||||
* **Contract tests**: OpenAPI schemas pulled at build time; DTOs validated; breaking changes fail CI.
|
||||
* **e2e**: Playwright scenarios (login, scan detail, diff, policy edit, admit deny).
|
||||
* **A11y**: axe-core CI checks; color‑contrast lints.
|
||||
* **i18n**: key coverage tests (no missing translations in supported locales).
|
||||
|
||||
---
|
||||
|
||||
## 15) Deployment & ops
|
||||
|
||||
* **Container**: `stellaops/web-ui:<ver>-<rev>`; NGINX with `gzip_static` + brotli; immutable assets under `/static/<hash>/…`.
|
||||
* **Config**: `/config.json` served by gateway (injected at runtime): API base URLs, authority issuer, telemetry sampling.
|
||||
* **Version banner**: footer shows UI & backend versions; warns on major mismatches.
|
||||
* **CDN** (optional): cache static bundle; APIs stay behind internal gateway.
|
||||
* **Feature flags**: environment gates (staged policies, eBPF runtime) readable from config.
|
||||
|
||||
---
|
||||
|
||||
## 16) Plugin system (route plug‑ins)
|
||||
|
||||
* **Manifest**: Backend provides a signed plug‑in manifest with remote module URLs and **cosign signature** per JS bundle.
|
||||
* **Loader**: dynamic import with **SRI** and signature verification (WebCrypto).
|
||||
* **Sandbox**: plug‑ins are routed modules receiving a limited **UI SDK** (navigation, theme, API gateway). No direct token access; API calls proxied through the UI SDK which enforces RBAC.
|
||||
* **Examples**: custom reports, vendor dashboards, regulated TLS config UIs.
|
||||
|
||||
---
|
||||
|
||||
## 17) Wire sequences (representative)
|
||||
|
||||
**A) View scan progress**
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant UI
|
||||
participant Auth as Authority
|
||||
participant SW as Scanner.WebService
|
||||
|
||||
UI->>Auth: /authorize (PKCE)
|
||||
Auth-->>UI: code → token (DPoP-bound)
|
||||
UI->>SW: GET /scans/{id} (Authorization+DPoP)
|
||||
SW-->>UI: { status: running }
|
||||
UI->>SW: (SSE) GET /scans/{id}/events
|
||||
SW-->>UI: progress events …
|
||||
SW-->>UI: terminal event { status: completed, artifacts[] }
|
||||
```
|
||||
|
||||
**B) Verify attestation**
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant UI
|
||||
participant AT as Attestor
|
||||
UI->>AT: POST /rekor/verify { uuid }
|
||||
AT-->>UI: { ok:true, index, logURL }
|
||||
```
|
||||
|
||||
**C) Promote policy & preview**
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant UI
|
||||
participant BE as Scanner.WebService (Policy endpoint)
|
||||
UI->>BE: POST /policy/stage { yaml, rego }
|
||||
BE-->>UI: { policyRevision, diagnostics }
|
||||
UI->>BE: POST /policy/preview { imageDigest, policyRevision }
|
||||
BE-->>UI: { verdict: pass|fail, reasons[] }
|
||||
UI->>BE: POST /policy/promote { policyRevision }
|
||||
BE-->>UI: { ok:true }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 18) Security hard lines
|
||||
|
||||
* Never store JWTs in `localStorage`.
|
||||
* Enforce DPoP for API calls; if DPoP unsupported for a service, require **SameSite=Lax** cookies with CSRF token header.
|
||||
* Block mixed‑content; only HTTPS origins allowed.
|
||||
* Validate and render only **escaped** user content; code viewer uses safe highlighter.
|
||||
* Downloaded artifacts are treated as **opaque binaries**; no HTML rendering.
|
||||
|
||||
---
|
||||
|
||||
## 19) Roadmap
|
||||
|
||||
* **PWA** offline shell (read‑only) for dashboards and cached scan details.
|
||||
* **SBOM graph** visualization (force‑directed) for small components sets.
|
||||
* **Runtime session replay** (privacy‑safe) to debug operator workflows (opt‑in).
|
||||
* **Assistive wizards** for policy creation with guided templates.
|
||||
# component_architecture_web_ui.md — **Stella Ops Web UI** (2025Q4)
|
||||
|
||||
> Consolidates Console requirements documented across the Policy, Graph, Vulnerability Explorer, Advisory AI, Orchestrator, and Notifications module guides and implementation plans.
|
||||
|
||||
> **Scope.** Implementation‑ready architecture for the **Angular SPA** that operators and developers use to drive Stella Ops. This document defines UX surfaces, module boundaries, data flows, auth, RBAC, real‑time updates, performance targets, i18n/a11y, security headers, testing and deployment. The UI is a *consumer* of backend APIs (Scanner, Policy, Excititor, Concelier, Attestor, Authority) and never performs scanning, merging, or signing on its own.
|
||||
|
||||
---
|
||||
|
||||
## 0) Mission & non‑goals
|
||||
|
||||
**Mission.** Provide a **fast, explainable** console for:
|
||||
|
||||
* Scans (status, SBOMs, diffs, EntryTrace, attestation).
|
||||
* Policy management (rules, exemptions, VEX consumption view).
|
||||
* Vulnerability intel (Concelier status), VEX consensus exploration (Excititor).
|
||||
* Runtime posture (Zastava observer + admission).
|
||||
* Admin operations (tenants, tokens, quotas, licensing posture).
|
||||
|
||||
**Non‑goals.** No client‑side crypto signing; no Docker/CRI access; no direct registry access beyond fetching static assets or OCI referrer summaries exposed by backend.
|
||||
|
||||
---
|
||||
|
||||
## 1) Technology baseline
|
||||
|
||||
* **Framework**: Angular 17+ (Stand‑alone APIs / Signals), TypeScript 5.
|
||||
* **Styling**: Tailwind CSS + headless component patterns; CSS variables for theming.
|
||||
* **Charts**: Lightweight SVG (uPlot or Apache ECharts via on‑demand import).
|
||||
* **State**: Angular **Signals** + `@ngrx/signals` store for cross‑page slices.
|
||||
* **Transport**: `fetch` + RxJS interop; **SSE** (EventSource) for progress streams.
|
||||
* **Build**: Angular CLI + Vite builder.
|
||||
* **Testing**: Jest + Testing Library, Playwright for e2e.
|
||||
* **Packaging**: Containerized NGINX (immutable assets, ETag + content hashing).
|
||||
|
||||
---
|
||||
|
||||
## 2) High‑level module map
|
||||
|
||||
```
|
||||
/app
|
||||
├─ core/ # bootstrap, config, auth, http, error boundary, i18n
|
||||
├─ shared/ # UI kit (tables, code-viewers, badges), pipes
|
||||
├─ dashboard/ # live tiles, fleet KPIs, feed/vex age, queue depth
|
||||
├─ scans/ # scan list, detail, SBOM viewer, diff-by-layer, EntryTrace
|
||||
├─ runtime/ # Zastava posture, drift events, admission decisions
|
||||
├─ policy/ # rules editor (YAML/Rego), exemptions, previews
|
||||
├─ vex/ # VEX explorer (claims, consensus, conflicts)
|
||||
├─ concelier/ # source health, export cursors, rebuild/export triggers
|
||||
├─ attest/ # attestation proofs, verification bundles, Rekor links
|
||||
├─ admin/ # tenants, roles, clients, quotas, licensing posture
|
||||
└─ plugins/ # route plug-ins (lazy remote modules, governed)
|
||||
```
|
||||
|
||||
Each feature folder builds as a **standalone route** (lazy loaded). All HTTP shapes live in `core/api/` clients with shared DTOs.
|
||||
|
||||
---
|
||||
|
||||
## 3) Navigation & key views
|
||||
|
||||
### 3.1 Dashboard
|
||||
|
||||
* **Tiles**: “New criticals (24h)”, “VEX suppressions applied”, “Attested SBOMs (7d)”, “Feed age per provider”, “Scanner queue depth”, “Admission events”.
|
||||
* **Trends**: sparkline for vulns/day, pass/fail rates, attestation throughput.
|
||||
|
||||
### 3.2 Scans
|
||||
|
||||
* **Scan list** with status, image digest, repo, time, artifacts, attestation badge.
|
||||
* **Scan detail**:
|
||||
|
||||
* **SBOM viewer**: Inventory/Usage toggle; component table (virtualized), filters by package type, severity, source.
|
||||
* **Diff by layer**: A→B change grid (added/removed/upgraded), grouped by introducing/removing layer; tooltips show provenance and links to layer SBOM fragment.
|
||||
* **EntryTrace**: shell chain with file:line breadcrumbs; jump‑to source viewer (read‑only, hexdump fallback).
|
||||
* **Attestation**: Rekor UUID, index, inclusion proof; **Verify** button calls Attestor `/verify`.
|
||||
* **Export**: download buttons (CycloneDX JSON, Protobuf, SPDX JSON); size shown; SHA‑256 inline.
|
||||
|
||||
### 3.3 Runtime (Zastava)
|
||||
|
||||
* **Observer timeline**: container start/stop, drift, policy violations; faceted by namespace/owner.
|
||||
* **Live process view**: top N processes, loaded libs summary vs Usage SBOM.
|
||||
* **Admission decisions**: per‑namespace rules, allow/deny events, cache TTL, reasons.
|
||||
|
||||
### 3.4 Policy
|
||||
|
||||
* **Policy bundles**: active vs staged; diff viewer with change summary.
|
||||
* **Editors**:
|
||||
|
||||
* YAML rules (ignore lists, thresholds, vendor precedence overrides).
|
||||
* Rego blocks (advanced gates) with **WASM** preview evaluator (client‑side sandbox) for “preview” against sample SBOMs.
|
||||
* **VEX inclusion controls**: weight sliders (visualization only), provider allow/deny toggles.
|
||||
* **Preview**: select SBOM (or image digest) → show verdict under staged policy.
|
||||
|
||||
### 3.5 Excititor
|
||||
|
||||
* **Claims explorer**: search by vulnId/productKey/provider; show raw claim (status, justification, evidence).
|
||||
* **Consensus view**: rollup per (vuln, product) with accepted/rejected sources, weights, timestamps.
|
||||
* **Conflicts**: grid of top conflicts; filters for justification gates failed.
|
||||
|
||||
### 3.6 Concelier
|
||||
|
||||
* **Sources** table: staleness, last run, errors.
|
||||
* **Advisory search**: by CVE/alias; show normalized affected ranges.
|
||||
* **Exports**: trigger full/delta JSON/Trivy DB; show manifest digests and Rekor link if attested.
|
||||
|
||||
### 3.7 Attest
|
||||
|
||||
* **Proofs list**: last 7 days Rekor entries; filter by kind (sbom/report/vex).
|
||||
* **Verification**: paste UUID or upload bundle → verify; result with explanations (chain, Merkle path).
|
||||
|
||||
### 3.8 Admin
|
||||
|
||||
* **Tenants/Installations**: view/edit, isolation hints.
|
||||
* **Clients & roles**: Authority clients, role→scope mapping, rotation hints.
|
||||
* **Quotas**: per license plan, counters, throttle events.
|
||||
* **Licensing posture**: last PoE introspection snapshot (redacted), release window.
|
||||
|
||||
---
|
||||
|
||||
## 4) Auth, sessions & RBAC
|
||||
|
||||
### 4.1 OIDC flow
|
||||
|
||||
* **Authorization Code + PKCE** to **Authority**.
|
||||
* **ID Token** for UX identity; **Access Token** (OpTok) for APIs (2–5 min TTL).
|
||||
* **DPoP (browser)**: generate ephemeral **WebCrypto** keypair; store public JWK in memory, private key in **IndexedDB** (non‑exportable if platform allows). Access token includes `cnf.jkt`; each API call adds `DPoP` proof; handle nonce challenges automatically.
|
||||
* **Refresh**: optional DPoP‑bound refresh tokens with rotation; otherwise silent renew.
|
||||
|
||||
### 4.2 RBAC
|
||||
|
||||
* Roles (`ui.read`, `ui.admin`, plus service roles) are embedded in ID token or fetched via `/me` endpoint.
|
||||
* **Route guards** enforce access; **feature flags** hide admin pages for non‑admins.
|
||||
|
||||
### 4.3 Session storage
|
||||
|
||||
* Access tokens & refresh metadata in memory; persist **only** minimal session (subject, expiries) in `sessionStorage`. Never persist raw JWTs to `localStorage`. Use **SameSite=Lax** cookies for anti‑CSRF if cookies are required (prefer pure bearer headers + DPoP).
|
||||
|
||||
---
|
||||
|
||||
## 5) HTTP layer & API clients
|
||||
|
||||
* **`core/http/api-client.ts`** centralizes:
|
||||
|
||||
* Base URLs (Scanner, Excititor, Concelier, Attestor).
|
||||
* **Retry** policies on idempotent GETs (backoff + jitter).
|
||||
* **Problem+JSON** parser → uniform error toasts with correlation ID.
|
||||
* **SSE** helper (EventSource) with auto‑reconnect & backpressure.
|
||||
* **DPoP** injector & nonce handling.
|
||||
|
||||
* Typed API clients (DTOs in `core/api/models.ts`):
|
||||
|
||||
* `ScannerApi`, `PolicyApi`, `ExcititorApi`, `ConcelierApi`, `AttestorApi`, `AuthorityApi`.
|
||||
|
||||
**DTO examples (abbrev):**
|
||||
|
||||
```ts
|
||||
export type ImageDigest = `sha256:${string}`;
|
||||
export interface ScanSummary {
|
||||
imageDigest: ImageDigest; createdAt: string;
|
||||
artifacts: { view: 'inventory'|'usage'; format: 'cdx-json'|'cdx-pb'|'spdx-json'; sha256: string; size: number }[];
|
||||
status: 'queued'|'running'|'completed'|'error';
|
||||
rekor?: { uuid: string; index?: number; url?: string };
|
||||
}
|
||||
export interface DiffEntry {
|
||||
key: string; change: 'added'|'removed'|'upgraded'|'downgraded';
|
||||
fromVersion?: string; toVersion?: string; layer: string; usedByEntrypoint?: boolean;
|
||||
}
|
||||
export interface VexConsensus {
|
||||
vulnId: string; productKey: string; rollupStatus: 'affected'|'not_affected'|'fixed'|'under_investigation';
|
||||
sources: { providerId: string; status: string; weight: number; accepted: boolean; reason: string }[];
|
||||
}
|
||||
```
|
||||
|
||||
*Upcoming:* `NotifyApi` consumes delivery history using the new paginated envelope returned by `/api/v1/notify/deliveries`.
|
||||
|
||||
```ts
|
||||
export interface NotifyDeliveryListResponse {
|
||||
items: NotifyDelivery[];
|
||||
count: number;
|
||||
continuationToken?: string;
|
||||
}
|
||||
|
||||
export interface NotifyDelivery {
|
||||
deliveryId: string;
|
||||
ruleId: string;
|
||||
actionId: string;
|
||||
status: 'pending'|'sent'|'failed'|'throttled'|'digested'|'dropped';
|
||||
rendered: NotifyDeliveryRendered;
|
||||
metadata: Record<string, string>; // includes channelType, target, previewProvider, traceId, and provider-specific entries
|
||||
createdAt: string;
|
||||
sentAt?: string;
|
||||
completedAt?: string;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6) State, caching & real‑time
|
||||
|
||||
* **Per‑page stores** (Signals) for list filters, pagination, and selected entities.
|
||||
* **Normalized caches** keyed by `(imageDigest, view, format)`; artifacts are downloaded via pre‑signed URLs from Scanner and streamed; SHA‑256 verified client‑side before exposing “verified” badge.
|
||||
* **SSE channels**:
|
||||
|
||||
* `/scans/{id}/events` → progress log.
|
||||
* `/runtime/events/stream` (optional) → live drift/admission feed (rate‑limited).
|
||||
* **Cache invalidation** on job completion or explicit “refresh”.
|
||||
|
||||
---
|
||||
|
||||
## 7) SBOM viewing & diff UX
|
||||
|
||||
* **Huge tables** rendered with **virtual scrolling** (CDK Virtual Scroll); sort/filter performed client‑side for ≤ 20k rows; beyond that, server‑side queries via BOM‑Index endpoints.
|
||||
* **Component row** shows purl, version, origin (OS pkg / metadata / linker / attested), licenses, and **used** badge (Usage view).
|
||||
* **Diff**: compact heatmap per layer; clicking opens a right‑pane with evidence: introducing paths, file hashes, VEX notes (from Excititor consensus) and links to advisories (Concelier).
|
||||
|
||||
---
|
||||
|
||||
## 8) Policy editor & VEX integration
|
||||
|
||||
* **YAML editor**: Monaco‑based with schema hints; previews show which rules matched.
|
||||
* **Rego editor**: Monaco with WASM‑OPA sandbox for read‑only evaluation on sample SBOMs.
|
||||
* **VEX toggles**: per‑provider enable/disable; “explain” drawer shows why a claim was accepted/rejected (justification gate, signature state, weight).
|
||||
* **Staged → Active** promotion is a two‑step flow with confirmation and automatic policy digest computation.
|
||||
|
||||
---
|
||||
|
||||
## 9) Accessibility, i18n & theming
|
||||
|
||||
* **A11y**: WCAG 2.2 AA; keyboard navigation, focus management, ARIA roles; color‑contrast tokens verified by unit tests.
|
||||
* **I18n**: Angular i18n + runtime translation loader (`/locales/{lang}.json`); dates/numbers localized via `Intl`.
|
||||
* **Languages**: English default; Bulgarian, German, Japanese as initial additions.
|
||||
* **Theming**: dark/light via CSS variables; persisted in `prefers-color-scheme` aware store.
|
||||
|
||||
---
|
||||
|
||||
## 10) Performance budgets
|
||||
|
||||
* **TTI** ≤ 1.5 s on 4G/slow CPU (first visit), ≤ 0.6 s repeat (HTTP/2, cached).
|
||||
* **JS** initial < 300 KB gz (lazy routes).
|
||||
* **SBOM list**: render 10k rows in < 70 ms with virtualization; filter in < 150 ms.
|
||||
* **Diff view**: compute client‑side grouping for 5k changes in < 120 ms.
|
||||
|
||||
Techniques: route‑level code splitting; `ChangeDetectionStrategy.OnPush`; Signals; server compression (zstd/gzip), immutable assets with long max‑age (cache busting via hashes).
|
||||
|
||||
---
|
||||
|
||||
## 11) Security headers & CSP
|
||||
|
||||
* **CSP**: `default-src 'self'; connect-src 'self' https://*.internal; img-src 'self' data:; script-src 'self'; style-src 'self' 'unsafe-inline'; frame-ancestors 'none';`
|
||||
* **HSTS** enabled at gateway.
|
||||
* **Referrer Policy**: `no-referrer`.
|
||||
* **X‑Frame‑Options**: `DENY`.
|
||||
* **COOP/COEP** to enable faster cross‑origin isolation (for WASM OPA).
|
||||
* **Subresource Integrity (SRI)** for third‑party fonts (minimize third‑party).
|
||||
|
||||
---
|
||||
|
||||
## 12) Error handling & UX hygiene
|
||||
|
||||
* **Global error boundary** surfaces Problem+JSON `title/detail/instance` with correlation ID.
|
||||
* **Retry toast** for 429 (quota throttles) with backoff timer.
|
||||
* **Auth expiry**: pre‑emptive refresh; unobtrusive banner when < 60 s TTL; re‑login modal if refresh fails.
|
||||
* **Network down**: offline banner with queued actions (idempotent resubmits).
|
||||
* **File verify**: show SHA‑256 mismatch warnings if artifact altered in transit.
|
||||
|
||||
---
|
||||
|
||||
## 13) Observability
|
||||
|
||||
* **Front‑end telemetry** (OpenTelemetry Web): route timings, API latency by service, error counts; sampled to 1–5% and shipped to backend OTLP endpoint.
|
||||
* **User actions** logged anonymously (no PII): “policy promote”, “scan export”, “attest verify”.
|
||||
* **Metrics dash** in admin shows SLOs and recent front‑end errors.
|
||||
|
||||
---
|
||||
|
||||
## 14) Testing strategy
|
||||
|
||||
* **Unit**: pure component logic via Jest + Testing Library (no TestBed when possible).
|
||||
* **Component harness** for table, code viewer, diff heatmap.
|
||||
* **Contract tests**: OpenAPI schemas pulled at build time; DTOs validated; breaking changes fail CI.
|
||||
* **e2e**: Playwright scenarios (login, scan detail, diff, policy edit, admit deny).
|
||||
* **A11y**: axe-core CI checks; color‑contrast lints.
|
||||
* **i18n**: key coverage tests (no missing translations in supported locales).
|
||||
|
||||
---
|
||||
|
||||
## 15) Deployment & ops
|
||||
|
||||
* **Container**: `stellaops/web-ui:<ver>-<rev>`; NGINX with `gzip_static` + brotli; immutable assets under `/static/<hash>/…`.
|
||||
* **Config**: `/config.json` served by gateway (injected at runtime): API base URLs, authority issuer, telemetry sampling.
|
||||
* **Version banner**: footer shows UI & backend versions; warns on major mismatches.
|
||||
* **CDN** (optional): cache static bundle; APIs stay behind internal gateway.
|
||||
* **Feature flags**: environment gates (staged policies, eBPF runtime) readable from config.
|
||||
|
||||
---
|
||||
|
||||
## 16) Plugin system (route plug‑ins)
|
||||
|
||||
* **Manifest**: Backend provides a signed plug‑in manifest with remote module URLs and **cosign signature** per JS bundle.
|
||||
* **Loader**: dynamic import with **SRI** and signature verification (WebCrypto).
|
||||
* **Sandbox**: plug‑ins are routed modules receiving a limited **UI SDK** (navigation, theme, API gateway). No direct token access; API calls proxied through the UI SDK which enforces RBAC.
|
||||
* **Examples**: custom reports, vendor dashboards, regulated TLS config UIs.
|
||||
|
||||
---
|
||||
|
||||
## 17) Wire sequences (representative)
|
||||
|
||||
**A) View scan progress**
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant UI
|
||||
participant Auth as Authority
|
||||
participant SW as Scanner.WebService
|
||||
|
||||
UI->>Auth: /authorize (PKCE)
|
||||
Auth-->>UI: code → token (DPoP-bound)
|
||||
UI->>SW: GET /scans/{id} (Authorization+DPoP)
|
||||
SW-->>UI: { status: running }
|
||||
UI->>SW: (SSE) GET /scans/{id}/events
|
||||
SW-->>UI: progress events …
|
||||
SW-->>UI: terminal event { status: completed, artifacts[] }
|
||||
```
|
||||
|
||||
**B) Verify attestation**
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant UI
|
||||
participant AT as Attestor
|
||||
UI->>AT: POST /rekor/verify { uuid }
|
||||
AT-->>UI: { ok:true, index, logURL }
|
||||
```
|
||||
|
||||
**C) Promote policy & preview**
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant UI
|
||||
participant BE as Scanner.WebService (Policy endpoint)
|
||||
UI->>BE: POST /policy/stage { yaml, rego }
|
||||
BE-->>UI: { policyRevision, diagnostics }
|
||||
UI->>BE: POST /policy/preview { imageDigest, policyRevision }
|
||||
BE-->>UI: { verdict: pass|fail, reasons[] }
|
||||
UI->>BE: POST /policy/promote { policyRevision }
|
||||
BE-->>UI: { ok:true }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 18) Security hard lines
|
||||
|
||||
* Never store JWTs in `localStorage`.
|
||||
* Enforce DPoP for API calls; if DPoP unsupported for a service, require **SameSite=Lax** cookies with CSRF token header.
|
||||
* Block mixed‑content; only HTTPS origins allowed.
|
||||
* Validate and render only **escaped** user content; code viewer uses safe highlighter.
|
||||
* Downloaded artifacts are treated as **opaque binaries**; no HTML rendering.
|
||||
|
||||
---
|
||||
|
||||
## 19) Roadmap
|
||||
|
||||
* **PWA** offline shell (read‑only) for dashboards and cached scan details.
|
||||
* **SBOM graph** visualization (force‑directed) for small components sets.
|
||||
* **Runtime session replay** (privacy‑safe) to debug operator workflows (opt‑in).
|
||||
* **Assistive wizards** for policy creation with guided templates.
|
||||
|
||||
@@ -1,211 +1,211 @@
|
||||
# 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](../../ui/console-overview.md), [Navigation](../../ui/navigation.md), [Runs workspace](../../ui/runs.md), [Downloads](../../ui/downloads.md), [Console security posture](../../security/console-security.md), [Console observability](../../observability/ui-telemetry.md), [Deployment guide](../../deploy/console.md)
|
||||
|
||||
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.
|
||||
|
||||
| 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: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.
|
||||
|
||||
```mermaid
|
||||
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-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.
|
||||
|
||||
| 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:
|
||||
|
||||
```mermaid
|
||||
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 return `204` immediately; 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.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.md`—`npm 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](../../security/console-security.md) 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](../../observability/ui-telemetry.md) (`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
|
||||
|
||||
| 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).*
|
||||
# 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](../../ui/console-overview.md), [Navigation](../../ui/navigation.md), [Runs workspace](../../ui/runs.md), [Downloads](../../ui/downloads.md), [Console security posture](../../security/console-security.md), [Console observability](../../observability/ui-telemetry.md), [Deployment guide](../../deploy/console.md)
|
||||
|
||||
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.
|
||||
|
||||
| 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: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.
|
||||
|
||||
```mermaid
|
||||
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-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.
|
||||
|
||||
| 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:
|
||||
|
||||
```mermaid
|
||||
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 return `204` immediately; 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.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.md`—`npm 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](../../security/console-security.md) 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](../../observability/ui-telemetry.md) (`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
|
||||
|
||||
| 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).*
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
# Implementation plan — Console UI
|
||||
|
||||
## Current objectives
|
||||
- Maintain deterministic behaviour and offline parity across releases.
|
||||
- Keep documentation, telemetry, and runbooks aligned with the latest sprint outcomes.
|
||||
|
||||
## Workstreams
|
||||
- Backlog grooming: reconcile open stories in ../../TASKS.md with this module's roadmap.
|
||||
- Implementation: collaborate with service owners to land feature work defined in SPRINTS/EPIC docs.
|
||||
- Validation: extend tests/fixtures to preserve determinism and provenance requirements.
|
||||
|
||||
## Epic milestones
|
||||
- **Epic 2 – Policy Engine & Editor:** deliver policy editor simulation and explain UX.
|
||||
- **Epic 4 – Policy Studio:** build registry, approvals, and promotion experiences.
|
||||
- **Epic 5 – SBOM Graph Explorer:** implement graph navigation, overlays, and diff views.
|
||||
- **Epic 6 – Vulnerability Explorer:** surface triage dashboards, findings ledger, and audit exports.
|
||||
- **Epic 8 – Advisory AI:** integrate advisory summaries and remediation hints with strict provenance.
|
||||
- **Epic 9 – Orchestrator Dashboard:** expose job/source monitoring controls.
|
||||
- **Epic 11 – Notifications Studio:** provide notifications workspace with previews and audit trails.
|
||||
- Track supporting tasks (e.g., DOCS-CONSOLE-23-001, CONSOLE-OBS-52-001) in ../../TASKS.md.
|
||||
|
||||
## Coordination
|
||||
- Review ./AGENTS.md before picking up new work.
|
||||
- Sync with cross-cutting teams noted in ../../implplan/SPRINTS.md.
|
||||
- Update this plan whenever scope, dependencies, or guardrails change.
|
||||
# Implementation plan — Console UI
|
||||
|
||||
## Current objectives
|
||||
- Maintain deterministic behaviour and offline parity across releases.
|
||||
- Keep documentation, telemetry, and runbooks aligned with the latest sprint outcomes.
|
||||
|
||||
## Workstreams
|
||||
- Backlog grooming: reconcile open stories in ../../TASKS.md with this module's roadmap.
|
||||
- Implementation: collaborate with service owners to land feature work defined in SPRINTS/EPIC docs.
|
||||
- Validation: extend tests/fixtures to preserve determinism and provenance requirements.
|
||||
|
||||
## Epic milestones
|
||||
- **Epic 2 – Policy Engine & Editor:** deliver policy editor simulation and explain UX.
|
||||
- **Epic 4 – Policy Studio:** build registry, approvals, and promotion experiences.
|
||||
- **Epic 5 – SBOM Graph Explorer:** implement graph navigation, overlays, and diff views.
|
||||
- **Epic 6 – Vulnerability Explorer:** surface triage dashboards, findings ledger, and audit exports.
|
||||
- **Epic 8 – Advisory AI:** integrate advisory summaries and remediation hints with strict provenance.
|
||||
- **Epic 9 – Orchestrator Dashboard:** expose job/source monitoring controls.
|
||||
- **Epic 11 – Notifications Studio:** provide notifications workspace with previews and audit trails.
|
||||
- Track supporting tasks (e.g., DOCS-CONSOLE-23-001, CONSOLE-OBS-52-001) in ../../TASKS.md.
|
||||
|
||||
## Coordination
|
||||
- Review ./AGENTS.md before picking up new work.
|
||||
- Sync with cross-cutting teams noted in ../../implplan/SPRINTS.md.
|
||||
- Update this plan whenever scope, dependencies, or guardrails change.
|
||||
|
||||
Reference in New Issue
Block a user