Add tests for SBOM generation determinism across multiple formats
- Created `StellaOps.TestKit.Tests` project for unit tests related to determinism. - Implemented `DeterminismManifestTests` to validate deterministic output for canonical bytes and strings, file read/write operations, and error handling for invalid schema versions. - Added `SbomDeterminismTests` to ensure identical inputs produce consistent SBOMs across SPDX 3.0.1 and CycloneDX 1.6/1.7 formats, including parallel execution tests. - Updated project references in `StellaOps.Integration.Determinism` to include the new determinism testing library.
This commit is contained in:
@@ -1,264 +1,103 @@
|
||||
# 15 - Pragmatic UI Guide --- **Stella Ops**
|
||||
# Console (Web UI) Guide
|
||||
|
||||
# Stella Ops Web UI
|
||||
The StellaOps Console is the operator-facing web UI. It is built for fast triage and auditability: decisions link back to concrete evidence, and workflows continue to work in air-gapped deployments via Offline Kit snapshots.
|
||||
|
||||
A fast, modular single‑page application for controlling scans, policies, offline updates and platform‑wide settings.
|
||||
Built for sub‑second feedback, dark‑mode by default, and **no external CDNs** – everything ships inside the anonymous internal registry.
|
||||
This is a usage guide (what the Console does and how to operate it). For UI implementation architecture, see `docs/modules/ui/architecture.md`.
|
||||
|
||||
---
|
||||
## Scope
|
||||
|
||||
## 0 Fast Facts
|
||||
- Console workspaces and what each is for
|
||||
- Common operator workflows (triage, evidence review, exports)
|
||||
- Offline/air-gap posture and what to expect in the UI
|
||||
- Links to deeper module documentation
|
||||
|
||||
| Aspect | Detail |
|
||||
| ----------------- | -------------------------------------------------------------------------- |
|
||||
| Tech Stack | **Angular {{ angular }}** + Vite dev server |
|
||||
| Styling | **Tailwind CSS** |
|
||||
| State | Angular Signals + RxJS |
|
||||
| API Client | OpenAPI v3 generated services (Axios) |
|
||||
| Auth | OAuth2 /OIDC (tokens from backend or external IdP) |
|
||||
| i18n | JSON bundles – **`/locales/{lang}.json`** (English, Russian shipped) |
|
||||
| Offline Updates 📌 | UI supports “OUK” tarball upload to refresh NVD / Trivy DB when air‑gapped |
|
||||
| Build Artifacts | (`ui/dist/`) pushed to `registry.git.stella-ops.org/ui:${SHA}` |
|
||||
Out of scope: API shapes, schema details, and UI component implementation.
|
||||
|
||||
---
|
||||
## Core Concepts
|
||||
|
||||
## 1 Navigation Map
|
||||
- **Tenant context:** most views are tenant-scoped; switching tenants changes what evidence you see and what actions you can take.
|
||||
- **Evidence-linked decisions:** verdicts (ship/block/needs-exception) should link to the SBOM facts, advisory/VEX observations, reachability proofs, and policy explanations that justify them.
|
||||
- **Effective VEX:** the platform computes an effective status using issuer trust and policy rules, without rewriting upstream VEX (see `docs/16_VEX_CONSENSUS_GUIDE.md`).
|
||||
- **Snapshots and staleness:** offline sites operate on snapshots; the Console should surface snapshot identity and freshness rather than hide it.
|
||||
|
||||
```
|
||||
Dashboard
|
||||
└─ Scans
|
||||
├─ Active
|
||||
├─ History
|
||||
└─ Reports
|
||||
└─ Policies 📌
|
||||
├─ Editor (YAML / Rego) 📌
|
||||
├─ Import / Export 📌
|
||||
└─ History
|
||||
└─ Settings
|
||||
├─ SBOM Format 📌
|
||||
├─ Registry 📌
|
||||
├─ Offline Updates (OUK) 📌
|
||||
├─ Themes (Light / Dark / System) 📌
|
||||
└─ Advanced
|
||||
└─ Plugins 🛠
|
||||
└─ Help / About
|
||||
```
|
||||
## Workspaces (Navigation)
|
||||
|
||||
*The **Offline Updates (OUK)** node under **Settings** is new.*
|
||||
The Console is organized into workspaces. Names vary slightly by build, but the intent is stable:
|
||||
|
||||
---
|
||||
- **Dashboard:** fleet status, feed/VEX age, queue depth, and policy posture.
|
||||
- **Scans / SBOM:** scan history and scan detail; SBOM viewing and export.
|
||||
- **Findings / Triage:** the vulnerability triage surface (case view + evidence rail).
|
||||
- **Advisories & VEX:** provider status, conflicts, provenance, and issuer trust.
|
||||
- **Policies:** policy packs, previews, promotion workflow, and waiver/exception flows.
|
||||
- **Runs / Scheduler:** background jobs, re-evaluation, and reachability/delta work.
|
||||
- **Downloads / Offline:** Offline Kit and signed artifact distribution and mirroring.
|
||||
- **Admin:** tenants, roles/scopes, clients, quotas, and operational settings.
|
||||
|
||||
## 2 Technology Overview
|
||||
## Common Operator Workflows
|
||||
|
||||
### 2.1 Build & Deployment
|
||||
### Triage a Finding
|
||||
|
||||
1. `npm i && npm build` → generates `dist/` (~2.1 MB gzip).
|
||||
2. A CI job tags and pushes the artifact as `ui:${GIT_SHA}` to the internal registry.
|
||||
3. Backend serves static assets from `/srv/ui` (mounted from the image layer).
|
||||
1. Open **Findings** and filter to the tenant/environment you care about.
|
||||
2. Open a finding to review:
|
||||
- Verdict + "why" summary
|
||||
- Effective VEX status and issuer provenance
|
||||
- Reachability/impact signals (when available)
|
||||
- Policy explanation trace and the gate that produced the verdict
|
||||
3. Record a triage action (assign/comment/ack/mute/exception request) with justification.
|
||||
4. Export an evidence bundle when review, escalation, or offline verification is required.
|
||||
|
||||
_No external fonts or JS – true offline guarantee._
|
||||
See `docs/20_VULNERABILITY_EXPLORER_GUIDE.md` for the conceptual model and determinism requirements.
|
||||
|
||||
### 2.2 Runtime Boot
|
||||
### Review VEX Conflicts and Issuer Trust
|
||||
|
||||
1. **AppConfigService** pulls `/api/v1/config/ui` (contains feature flags, default theme, enabled plugins).
|
||||
2. Locale JSON fetched (`/locales/{lang}.json`, falls back to `en`).
|
||||
3. Root router mounts lazy‑loaded **feature modules** in the order supplied by backend – this is how future route plugins inject pages without forking the UI.
|
||||
- Use **Advisories & VEX** to see which providers contributed statements, whether signatures verified, and where conflicts exist.
|
||||
- The Console should not silently hide conflicts; it should show what disagrees and why, and how policy resolved it.
|
||||
|
||||
---
|
||||
See `docs/16_VEX_CONSENSUS_GUIDE.md` for the underlying concepts.
|
||||
|
||||
## 3 Feature Walk‑Throughs
|
||||
### Export and Verify Evidence Bundles
|
||||
|
||||
### 3.1 Dashboard – Real‑Time Status
|
||||
- Exports are intended to be portable and verifiable (audits, incident response, air-gap review).
|
||||
- Expect deterministic ordering, UTC timestamps, and hash manifests.
|
||||
|
||||
* **Δ‑SBOM heat‑map** 📌 shows how many scans used delta mode vs. full unpack.
|
||||
* “Feed Age” tile turns **orange** if NVD feed is older than 24 h; reverts after an **OUK** upload 📌.
|
||||
* Live WebSocket updates for scans in progress (SignalR channel).
|
||||
* **Quota Tile** – shows **Scans Today / {{ quota_token }}**; turns yellow at **≤ 10% remaining** (≈ 90% used),
|
||||
red at {{ quota_token }} .
|
||||
* **Token Expiry Tile** – shows days left on *client.jwt* (offline only);
|
||||
turns orange at < 7 days.
|
||||
See `docs/24_OFFLINE_KIT.md` for packaging and offline verification workflows.
|
||||
|
||||
### 3.2 Scans Module
|
||||
## Offline / Air-Gap Expectations
|
||||
|
||||
| View | What you can do |
|
||||
| ----------- | ------------------------------------------------------------------------------------------------- |
|
||||
| **Active** | Watch progress bar (ETA ≤ 5 s) – newly added **Format** and **Δ** badges appear beside each item. |
|
||||
| **History** | Filter by repo, tag, policy result (pass/block/soft‑fail). |
|
||||
| **Reports** | Click row → HTML or PDF report rendered by backend (`/report/{digest}/html`). |
|
||||
- The Console must operate against Offline Kit snapshots (no external lookups required).
|
||||
- The UI should surface snapshot identity and staleness budgets (feeds, VEX, policy versions).
|
||||
- Upload/import workflows for Offline Kit bundles should be auditable (who imported what, when).
|
||||
|
||||
### 3.3 📌 Policies Module (new)
|
||||
## Security and Access
|
||||
|
||||
*Embedded **Monaco** editor with YAML + Rego syntax highlighting.*
|
||||
- Authentication is typically OIDC/OAuth2 via Authority; scopes/roles govern write actions.
|
||||
- Treat tokens as sensitive; avoid copying secrets into notes/tickets.
|
||||
- For CSP, scopes, and DPoP posture, see `docs/security/console-security.md`.
|
||||
|
||||
| Tab | Capability |
|
||||
| ------------------- | ------------------------------------------------------------------------------------------------ |
|
||||
| **Editor** | Write or paste `scan-policy.yaml` or inline Rego snippet. Schema validation shown inline. |
|
||||
| **Import / Export** | Buttons map to `/policy/import` and `/policy/export`. Accepts `.yaml`, `.rego`, `.zip` (bundle). |
|
||||
| **History** | Immutable audit log; diff viewer highlights rule changes. |
|
||||
## Observability and Accessibility
|
||||
|
||||
#### 3.3.1 YAML → Rego Bridge
|
||||
|
||||
If you paste YAML but enable **Strict Mode** (toggle), backend converts to Rego under the hood, stores both representations, and shows a side‑by‑side diff.
|
||||
|
||||
#### 3.3.2 Preview / Report Fixtures
|
||||
|
||||
- Use the offline fixtures (`samples/policy/policy-preview-unknown.json` and `samples/policy/policy-report-unknown.json`) to exercise the Policies screens without a live backend; both payloads include confidence bands, unknown-age tags, and scoring inputs that map directly to the UI panels.
|
||||
- Keep them in lock-step with the API by validating any edits with Ajv:
|
||||
|
||||
```bash
|
||||
# install once per checkout (offline-safe):
|
||||
npm install --no-save ajv-cli@5 ajv-formats@2
|
||||
|
||||
npx ajv validate --spec=draft2020 -c ajv-formats \
|
||||
-s docs/schemas/policy-preview-sample@1.json \
|
||||
-d samples/policy/policy-preview-unknown.json
|
||||
|
||||
npx ajv validate --spec=draft2020 -c ajv-formats \
|
||||
-s docs/schemas/policy-report-sample@1.json \
|
||||
-d samples/policy/policy-report-unknown.json
|
||||
```
|
||||
|
||||
### 3.4 📌 Settings Enhancements
|
||||
- UI telemetry and metrics guidance: `docs/observability/ui-telemetry.md`.
|
||||
- Accessibility baseline and keyboard model: `docs/accessibility.md`.
|
||||
|
||||
| Setting | Details |
|
||||
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **SBOM Format** | Dropdown – *Trivy JSON*, *SPDX JSON*, *CycloneDX JSON*. |
|
||||
| **Registry** | Displays pull URL (`registry.git.stella-ops.ru`) and Cosign key fingerprint. |
|
||||
| **Offline Updates (OUK)** 📌 | Upload **`ouk*.tar.gz`** produced by the Offline Update Kit CLI. Backend unpacks, verifies SHA‑256 checksum & Cosign signature, then reloads Redis caches without restart. |
|
||||
| **Theme** | Light, Dark, or Auto (system). |
|
||||
## Deploy and Install References
|
||||
|
||||
#### 3.4.1 OUK Upload Screen 📌
|
||||
- Deployment configuration and health checks: `docs/deploy/console.md`.
|
||||
- Container install recipes: `docs/install/docker.md`.
|
||||
|
||||
*Page path:* **Settings → Offline Updates (OUK)**
|
||||
*Components:*
|
||||
## Legacy Pages
|
||||
|
||||
1. **Drop Zone** – drag or select `.tar.gz` (max 1 GB).
|
||||
2. **Progress Bar** – streaming upload with chunked HTTP.
|
||||
3. **Verification Step** – backend returns status:
|
||||
* *Signature valid* ✔️
|
||||
* *Digest mismatch* ❌
|
||||
4. **Feed Preview** – table shows *NVD date*, *OUI source build tag*, *CVE count delta*.
|
||||
5. **Activate** – button issues `/feeds/activate/{id}`; on success the Dashboard “Feed Age” tile refreshes to green.
|
||||
6. **History List** – previous OUK uploads with user, date, version; supports rollback.
|
||||
Several older, topic-specific pages were consolidated into this guide and related canonical docs. The previous locations remain as short "archived" stubs for compatibility:
|
||||
|
||||
*All upload actions are recorded in the Policies → History audit log as type `ouk_update`.*
|
||||
- `docs/ui/*.md`
|
||||
- `docs/console/*.md`
|
||||
- `docs/ux/*.md`
|
||||
- `docs/vuln/*.md`
|
||||
|
||||
### 3.5 Plugins Panel 🛠 (ships after UI modularisation)
|
||||
## Related Docs
|
||||
|
||||
Lists discovered UI plugins; each can inject routes/panels. Toggle on/off without reload.
|
||||
|
||||
### 3.6 Settings → **Quota & Tokens** (new)
|
||||
|
||||
* View current **Client‑JWT claims** (tier, maxScansPerDay, expiry).
|
||||
* **Generate Offline Token** – admin‑only button → POST `/token/offline` (UI wraps the API).
|
||||
* Upload new token file for manual refresh.
|
||||
|
||||
### 3.7 Notifications Panel (new)
|
||||
|
||||
Route: **`/notify`** (header shortcut “Notify”). The panel now exposes every Notify control-plane primitive without depending on the backend being online.
|
||||
|
||||
| Area | What you can do |
|
||||
| --- | --- |
|
||||
| **Channels** | Create/edit Slack/Teams/Email/Webhook channels, toggle enablement, maintain labels/metadata, and execute **test send** previews. Channel health cards show mocked status + trace IDs so ops can validate wiring before Notify.WebService is reachable. |
|
||||
| **Rules** | Manage routing rules (matchers, severity gates, throttles/digests, locale hints). A single-action form keeps Signal-style configuration quick while mirroring Notify schema (`match`, `actions[]`). |
|
||||
| **Deliveries** | Browsable ledger with status filter (All/Sent/Failed/Throttled/…), showing targets, kinds, and timestamps so operators confirm noise controls. |
|
||||
|
||||
The component leans on the mocked Notify API service in `src/app/testing/mock-notify-api.service.ts`, meaning Offline Kit demos run instantly yet the view stays API-shaped (same DTOs + tenant header expectations).
|
||||
|
||||
---
|
||||
|
||||
## 4 i18n & l10n
|
||||
|
||||
* JSON files under `/locales`.
|
||||
* Russian (`ru`) ships first‑class, translated security terms align with **GOST R ISO/IEC 27002‑2020**.
|
||||
* “Offline Update Kit” surfaces as **“Оффлайн‑обновление базы уязвимостей”** in Russian locale.
|
||||
* Community can add locales by uploading a new JSON via Plugins Panel once 🛠 ships.
|
||||
|
||||
---
|
||||
|
||||
## 5 Accessibility
|
||||
|
||||
* WCAG 2.1 AA conformance targeted.
|
||||
* All color pairs pass contrast (checked by `vite-plugin-wcag`).
|
||||
* Keyboard navigation fully supported; focus outlines visible in both themes.
|
||||
|
||||
---
|
||||
|
||||
## 6 Theming 📌
|
||||
|
||||
| Layer | How to change |
|
||||
| --------------- | ------------------------------------------------------------ |
|
||||
| Tailwind | Palette variables under `tailwind.config.js > theme.colors`. |
|
||||
| Runtime toggle | Stored in `localStorage.theme`, synced across tabs. |
|
||||
| Plugin override | Future route plugins may expose additional palettes 🛠. |
|
||||
|
||||
---
|
||||
|
||||
## 7 Extensibility Hooks
|
||||
|
||||
| Area | Contract | Example |
|
||||
| ------------- | ---------------------------------------- | ---------------------------------------------- |
|
||||
| New route | `window.stella.registerRoute()` | “Secrets” scanner plugin adds `/secrets` page. |
|
||||
| External link | `window.stella.addMenuLink(label, href)` | “Docs” link opens corporate Confluence. |
|
||||
| Theme | `window.stella.registerTheme()` | High‑contrast palette for accessibility. |
|
||||
|
||||
---
|
||||
|
||||
## 8 Road‑Map Tags
|
||||
|
||||
| Feature | Status |
|
||||
| ------------------------- | ------ |
|
||||
| Policy Editor (YAML) | ✅ |
|
||||
| Inline Rego validation | 🛠 |
|
||||
| OUK Upload UI | ✅ |
|
||||
| Plugin Marketplace UI | 🚧 |
|
||||
| SLSA Verification banner | 🛠 |
|
||||
| Rekor Transparency viewer | 🚧 |
|
||||
|
||||
---
|
||||
|
||||
## 9 Non‑Commercial Usage Rules 📌
|
||||
|
||||
*(Extracted & harmonised from the Russian UI help page so that English docs remain licence‑complete.)*
|
||||
|
||||
1. **Free for internal security assessments.**
|
||||
2. Commercial resale or SaaS re‑hosting **prohibited without prior written consent** under AGPL §13.
|
||||
3. If you distribute a fork **with UI modifications**, you **must**:
|
||||
* Make the complete source code (including UI assets) publicly available.
|
||||
* Retain original project attribution in footer.
|
||||
4. All dependencies listed in `ui/package.json` remain under their respective OSS licences (MIT, Apache 2.0, ISC).
|
||||
5. Use in government‑classified environments must comply with**applicable local regulations** governing cryptography and software distribution.
|
||||
|
||||
---
|
||||
|
||||
## 10 Troubleshooting Tips
|
||||
|
||||
| Symptom | Cause | Remedy |
|
||||
| ----------------------------------- | ----------------------------------- | ----------------------------------------------------------------- |
|
||||
| **White page** after login | `ui/dist/` hash mismatch | Clear browser cache; backend auto‑busts on version change. |
|
||||
| Policy editor shows “Unknown field” | YAML schema drift | Sync your policy file to latest sample in *Settings → Templates*. |
|
||||
| **OUK upload fails** at 99 % | Tarball built with outdated OUK CLI | Upgrade CLI (`ouk --version`) and rebuild package. |
|
||||
| Icons look broken in Safari | *SVG `mask` unsupported* | Use Safari 17+ or switch to PNG icon set in Settings > Advanced. |
|
||||
|
||||
---
|
||||
|
||||
## 11 Contributing
|
||||
|
||||
* Run `npm dev` and open `http://localhost:5173`.
|
||||
* Ensure `ng lint` and `ng test` pass before PR.
|
||||
* Sign the **DCO** in your commit footer (`Signed-off-by`).
|
||||
|
||||
---
|
||||
|
||||
## 12 Change Log
|
||||
|
||||
| Version | Date | Highlights |
|
||||
| ------- | ---------- |
|
||||
| v2.4 | 2025‑07‑15 | **Added full OUK Offline Update upload flow** – navigation node, Settings panel, dashboard linkage, audit hooks. |
|
||||
| v2.3 | 2025‑07‑14 | Added Policies module, SBOM Format & Registry settings, theming toggle, Δ‑SBOM indicators, extracted non‑commercial usage rules. |
|
||||
| v2.2 | 2025‑07‑12 | Added user tips/workflows, CI notes, DevSecOps section, troubleshooting, screenshots placeholders. |
|
||||
| v2.1 | 2025‑07‑12 | Removed PWA/Service‑worker; added oidc‑client‑ts; simplified roadmap |
|
||||
| v2.0 | 2025‑07‑12 | Accessibility, Storybook, perf budgets, security rules |
|
||||
| v1.1 | 2025‑07‑11 | Original OSS‑only guide |
|
||||
|
||||
(End of Pragmatic UI Guide v2.2)
|
||||
- `docs/16_VEX_CONSENSUS_GUIDE.md`
|
||||
- `docs/20_VULNERABILITY_EXPLORER_GUIDE.md`
|
||||
- `docs/24_OFFLINE_KIT.md`
|
||||
- `docs/cli-vs-ui-parity.md`
|
||||
- `docs/architecture/console-admin-rbac.md`
|
||||
- `docs/architecture/console-branding.md`
|
||||
|
||||
Reference in New Issue
Block a user