Rewrite architecture docs and add Vexer connector template

This commit is contained in:
2025-10-17 19:34:43 +03:00
parent 29a7d51e41
commit fbd1826ef3
25 changed files with 4885 additions and 777 deletions

342
docs/ARCHITECTURE_UI.md Normal file
View File

@@ -0,0 +1,342 @@
# component_architecture_web_ui.md — **StellaOps Web UI** (2025Q4)
> **Scope.** Implementationready architecture for the **Angular SPA** that operators and developers use to drive StellaOps. This document defines UX surfaces, module boundaries, data flows, auth, RBAC, realtime updates, performance targets, i18n/a11y, security headers, testing and deployment. The UI is a *consumer* of backend APIs (Scanner, Policy, Vexer, Feedser, Attestor, Authority) and never performs scanning, merging, or signing on its own.
---
## 0) Mission & nongoals
**Mission.** Provide a **fast, explainable** console for:
* Scans (status, SBOMs, diffs, EntryTrace, attestation).
* Policy management (rules, exemptions, VEX consumption view).
* Vulnerability intel (Feedser status), VEX consensus exploration (Vexer).
* Runtime posture (Zastava observer + admission).
* Admin operations (tenants, tokens, quotas, licensing posture).
**Nongoals.** No clientside 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+ (Standalone APIs / Signals), TypeScript 5.
* **Styling**: Tailwind CSS + headless component patterns; CSS variables for theming.
* **Charts**: Lightweight SVG (uPlot or Apache ECharts via ondemand import).
* **State**: Angular **Signals** + `@ngrx/signals` store for crosspage 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) Highlevel 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)
├─ feedser/ # 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; jumpto source viewer (readonly, hexdump fallback).
* **Attestation**: Rekor UUID, index, inclusion proof; **Verify** button calls Attestor `/verify`.
* **Export**: download buttons (CycloneDX JSON, Protobuf, SPDX JSON); size shown; SHA256 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**: pernamespace 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 (clientside 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 Vexer
* **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 Feedser
* **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 (25min TTL).
* **DPoP (browser)**: generate ephemeral **WebCrypto** keypair; store public JWK in memory, private key in **IndexedDB** (nonexportable if platform allows). Access token includes `cnf.jkt`; each API call adds `DPoP` proof; handle nonce challenges automatically.
* **Refresh**: optional DPoPbound 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 nonadmins.
### 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 antiCSRF if cookies are required (prefer pure bearer headers + DPoP).
---
## 5) HTTP layer & API clients
* **`core/http/api-client.ts`** centralizes:
* Base URLs (Scanner, Vexer, Feedser, Attestor).
* **Retry** policies on idempotent GETs (backoff + jitter).
* **Problem+JSON** parser → uniform error toasts with correlation ID.
* **SSE** helper (EventSource) with autoreconnect & backpressure.
* **DPoP** injector & nonce handling.
* Typed API clients (DTOs in `core/api/models.ts`):
* `ScannerApi`, `PolicyApi`, `VexerApi`, `FeedserApi`, `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 }[];
}
```
---
## 6) State, caching & realtime
* **Perpage stores** (Signals) for list filters, pagination, and selected entities.
* **Normalized caches** keyed by `(imageDigest, view, format)`; artifacts are downloaded via presigned URLs from Scanner and streamed; SHA256 verified clientside before exposing “verified” badge.
* **SSE channels**:
* `/scans/{id}/events` → progress log.
* `/runtime/events/stream` (optional) → live drift/admission feed (ratelimited).
* **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 clientside for ≤ 20k rows; beyond that, serverside queries via BOMIndex 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 rightpane with evidence: introducing paths, file hashes, VEX notes (from Vexer consensus) and links to advisories (Feedser).
---
## 8) Policy editor & VEX integration
* **YAML editor**: Monacobased with schema hints; previews show which rules matched.
* **Rego editor**: Monaco with WASMOPA sandbox for readonly evaluation on sample SBOMs.
* **VEX toggles**: perprovider enable/disable; “explain” drawer shows why a claim was accepted/rejected (justification gate, signature state, weight).
* **Staged → Active** promotion is a twostep flow with confirmation and automatic policy digest computation.
---
## 9) Accessibility, i18n & theming
* **A11y**: WCAG 2.2 AA; keyboard navigation, focus management, ARIA roles; colorcontrast 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.5s on 4G/slow CPU (first visit), ≤ 0.6s repeat (HTTP/2, cached).
* **JS** initial < 300KB gz (lazy routes).
* **SBOM list**: render 10k rows in < 70ms with virtualization; filter in < 150ms.
* **Diff view**: compute clientside grouping for 5k changes in < 120ms.
Techniques: routelevel code splitting; `ChangeDetectionStrategy.OnPush`; Signals; server compression (zstd/gzip), immutable assets with long maxage (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`.
* **XFrameOptions**: `DENY`.
* **COOP/COEP** to enable faster crossorigin isolation (for WASM OPA).
* **Subresource Integrity (SRI)** for thirdparty fonts (minimize thirdparty).
---
## 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**: preemptive refresh; unobtrusive banner when < 60s TTL; relogin modal if refresh fails.
* **Network down**: offline banner with queued actions (idempotent resubmits).
* **File verify**: show SHA256 mismatch warnings if artifact altered in transit.
---
## 13) Observability
* **Frontend telemetry** (OpenTelemetry Web): route timings, API latency by service, error counts; sampled to 15% 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 frontend 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; colorcontrast 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 plugins)
* **Manifest**: Backend provides a signed plugin manifest with remote module URLs and **cosign signature** per JS bundle.
* **Loader**: dynamic import with **SRI** and signature verification (WebCrypto).
* **Sandbox**: plugins 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 mixedcontent; 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 (readonly) for dashboards and cached scan details.
* **SBOM graph** visualization (forcedirected) for small components sets.
* **Runtime session replay** (privacysafe) to debug operator workflows (optin).
* **Assistive wizards** for policy creation with guided templates.