feat: Document completed tasks for KMS, Cryptography, and Plugin Libraries

- Added detailed task completion records for KMS interface implementation and CLI support for file-based keys.
- Documented security enhancements including Argon2id password hashing, audit event contracts, and rate limiting configurations.
- Included scoped service support and integration updates for the Plugin platform, ensuring proper DI handling and testing coverage.
This commit is contained in:
master
2025-10-31 14:37:45 +02:00
parent 240e8ff25d
commit 15b4a1de6a
312 changed files with 6399 additions and 3319 deletions

View File

@@ -138,10 +138,10 @@ Audit entries appear for every user/token change. CLI parity: `stella auth token
## 11. Screenshot coordination
- Placeholders:
- `![Admin tenants placeholder](../assets/ui/admin/tenants-placeholder.png)`
- `![Admin roles placeholder](../assets/ui/admin/roles-placeholder.png)`
- `![Admin tokens placeholder](../assets/ui/admin/tokens-placeholder.png)`
- Placeholders (captures pending upload):
- `docs/assets/ui/admin/tenants-placeholder.png`
- `docs/assets/ui/admin/roles-placeholder.png`
- `docs/assets/ui/admin/tokens-placeholder.png`
- Capture real screenshots with Authority Guild once Sprint 23 UI is final (tracked in `#console-screenshots`, 2025-10-26 entry). Provide both light and dark theme variants.
---
@@ -171,4 +171,3 @@ Audit entries appear for every user/token change. CLI parity: `stella auth token
---
*Last updated: 2025-10-26 (Sprint 23).*

View File

@@ -1,199 +1,198 @@
# StellaOps Console - Advisories and VEX
> **Audience:** Console UX team, Concelier and Excititor guilds, support and compliance engineers.
> **Scope:** Advisory aggregation UX, VEX consensus display, conflict indicators, raw document viewer, provenance banners, CLI parity, and Aggregation-Only Contract (AOC) guardrails for Sprint 23.
The Advisories and VEX surfaces expose Concelier and Excititor outputs without mutating the underlying data. Operators can review upstream statements, check consensus summaries, inspect conflicts, and hand off evidence to downstream tooling while staying within the Aggregation-Only Contract.
---
## 1. Access and prerequisites
- **Routes:**
- `/console/advisories` (advisory list and detail)
- `/console/vex` (VEX consensus and raw claim explorer)
- **Scopes:** `advisory.read` and `vex.read` (base access), `advisory.verify` / `vex.verify` for verification actions, `downloads.read` for evidence exports.
- **Feature flags:** `advisoryExplorer.enabled`, `vexExplorer.enabled`, `aggregation.conflictIndicators`.
- **Dependencies:** Concelier WebService (aggregation API + delta metrics), Excititor WebService (consensus API + conflict feeds), Policy Engine explain hints (optional link-outs), Authority tenant enforcement.
- **Offline behaviour:** Uses Offline Kit snapshots when gateway is in sealed mode; verify buttons queue until connectivity resumes.
---
## 2. Layout overview
```
+---------------------------------------------------------------------+
| Header: Tenant badge - global filters - status ticker - actions |
+---------------------------------------------------------------------+
| Left rail: Saved views - provider filters - verification queue |
+---------------------------------------------------------------------+
| Main split pane |
| - Advisories tab (grid + detail drawer) |
| - VEX tab (consensus table + claim drawer) |
| Tabs remember last active view per tenant. |
+---------------------------------------------------------------------+
```
The header reuses console-wide context chips (`Tenant`, `Severity`, `Source`, `Time`) and the status ticker that streams Concelier and Excititor deltas.
---
## 3. Advisory aggregation view
| Element | Description |
|---------|-------------|
| **Grid columns** | Vulnerability key (CVE/GHSA/vendor), Title, Source set, Last merged, Severity badge, KEV flag, Affected product count, Merge hash. |
| **Source chips** | Show contributing providers (NVD, Red Hat, Debian, vendor PSIRT). Hover reveals precedence order and timestamps. |
| **Severity** | Displays the highest severity declared by any source; tooltip lists per-source severities and vectors. |
| **KEV / Exploit status** | Badge highlights known exploited status from Concelier enrichment; links to KEV reference. |
| **Merge hash** | Deterministic hash from Concelier `merge_event`. Clicking copies hash and opens provenance banner. |
| **Filters** | Vulnerability identifier search, provider multi-select, severity picker, KEV toggle, affected product range slider, time window. |
| **List actions** | `Open detail`, `Copy CLI` (`stella advisory show ...`), `Compare sources`, `Queue verify`. |
The grid virtualises up to 15,000 advisories per tenant. Beyond that, the UI engages server-side pagination with cursor hints supplied by Concelier.
---
## 4. Advisory detail drawer
Sections within the drawer:
1. **Summary cards** (title, published/modified timestamps, advisory merge hash, total sources, exploited flag).
2. **Sources timeline** listing each contributing document with signature status, fetched timestamps, precedence rank, and quick links to raw view.
3. **Affected products** table (product key, introduced/fixed, range semantics, distro qualifiers, notes). Column toggles allow switching between SemVer and distro notation.
4. **Conflict indicators** show when sources disagree on fixed versions, severity, or affected sets. Each conflict row links to an explainer panel that describes the winning value, losing sources, and precedence rule.
5. **References** collapsible list (patches, advisories, exploits).
6. **Raw JSON** viewer (read-only) using canonical Concelier payload. Users can copy JSON or download via `GET /console/advisories/raw/{id}`.
7. **CLI parity** card with commands:
- `stella advisory show --tenant <tenant> --vuln <id>`
- `stella advisory sources --tenant <tenant> --vuln <id>`
- `stella advisory export --tenant <tenant> --vuln <id> --format cdx-json`
Provenance banner at the top indicates whether all sources are signed, partially signed, or unsigned, referencing AOC guardrails. Unsigned sources trigger a warning and link to the verification checklist.
---
## 5. VEX explorer
| Feature | Description |
|---------|-------------|
| **Consensus table** | Rows keyed by `(vulnId, productKey)` with rollup status (affected, not affected, fixed, under investigation), confidence score, provider count, and last evaluation timestamp. |
| **Status badges** | Colour-coded (red affected, green not affected, blue fixed, amber under investigation). Tooltips show justification and policy revision used. |
| **Provider breakdown** | Hover or expand to see source list with accepted/ignored flag, status, justification code, signature state, weight. |
| **Filters** | Product search (PURL), status filter, provider filter, justification codes, confidence threshold slider. |
| **Saved views** | Prebuilt presets: `Vendor consensus`, `Distro overrides`, `Conflicts`, `Pending investigation`. |
---
## 6. VEX detail drawer
Tabs within the drawer:
- **Consensus summary**: Restates rollup status, policy revision, confidence benchmarks, and referencing runs.
- **Claims list**: Every raw claim from Excititor with provenance, signature result, justification, supersedes chain, evidence snippets. Claims are grouped by provider tier (vendor, distro, ecosystem, CERT).
- **Conflict explainers**: For conflicting claims, shows why a claim was ignored (weight, stale timestamp, failing justification gate). Includes inline diff between competing claims.
- **Events**: Timeline of claim arrivals and consensus evaluations with correlation IDs, accessible for debugging.
- **Raw JSON**: Canonical `VexClaim` or `VexConsensus` payloads with copy/download. CLI parity callouts:
- `stella vex consensus show --tenant <tenant> --vuln <id> --product <purl>`
- `stella vex claims show --tenant <tenant> --vuln <id> --provider <provider>`
---
## 7. Raw viewers and provenance
- Raw viewers display canonical payloads with syntax highlighting and copy-as-JSON support.
- Provenance banner presents: source URI, document digest, signature status, fetch timestamps, collector version.
- Users can open raw documents in a modal that includes:
- `sha256` digest with copy button
- Signature verification summary (passing keys, missing signatures, errors)
- `Download DSSE bundle` button when the document is attested
- `Open in logs` link that copies search query (`correlationId=...`) for log aggregation tools.
All raw views are read-only to maintain Aggregation-Only guarantees.
---
## 8. Conflict indicators and aggregation-not-merge UX
- Concelier retains every source; the UI surfaces conflicts rather than merging them.
- Conflict badges appear in grids and detail views when sources disagree on affected ranges, fixed versions, severity, or exploit flags.
- Clicking a badge opens the conflict explainer panel (powered by Concelier merge metadata) that lists winning/losing sources, ranks, and reasoning (e.g., "Vendor PSIRT overrides ecosystem advisory").
- Excititor conflicts highlight discarded claims with reasons (stale, failing justification, low weight). Operators can override weights downstream via Policy Engine if needed.
- UI copy explicitly reminds users that policy decisions happen elsewhere; these views show aggregated facts only.
---
## 9. Verification workflows
- **Run verify** buttons call Concelier or Excititor verification endpoints (`POST /console/advisories/verify`, `POST /console/vex/verify`) scoped by tenant and source filters.
- Verification results appear as banners summarising documents checked, signatures verified, and guard violations.
- Failed verifications show actionable error IDs (`ERR_AOC_00x`), matching CLI output.
- Verification history accessible via the status ticker dropdown; entries include operator, scope, and correlation IDs.
---
## 10. Exports and automation
- Advisory tab exposes export actions: `Download normalized advisory`, `Download affected products CSV`, `Download source bundle` (raw documents packaged with manifest).
- VEX tab supports exports for consensus snapshots, raw claims, and provider deltas.
- Export manifests include merge hash or consensus digest, tenant ID, timestamp, and signature state.
- CLI parity snippets accompany each export (e.g., `stella advisory export`, `stella vex export`).
- Automation: copy buttons for webhook subscription (`/downloads/hooks/subscribe`) and ORAS push commands when using remote registries.
---
## 11. Observability and SSE updates
- Status ticker shows ingest lag (`advisory_delta_minutes`, `vex_delta_minutes`), last merge event hash, and verification queue depth.
- Advisory and VEX grids refresh via SSE channels; updates animate row badges (new source, conflict resolved).
- Metrics surfaced in drawers: ingestion age, signature pass rate, consensus evaluation duration.
- Errors display correlation IDs linking to Concelier/Excititor logs.
---
## 12. Offline and air-gap behaviour
- When offline, list views display snapshot badge, staleness timer, and disable real-time verification.
- Raw downloads reference local snapshot directories and include checksum instructions.
- Exports queue locally; UI offers `Copy to removable media` instructions.
- CLI parity switches to offline commands (`--offline`, `--snapshot`).
- Tenant picker hides tenants not present in the snapshot to avoid partial data views.
---
## 13. Screenshot coordination
- Placeholders:
- `![Advisory grid placeholder](../assets/ui/advisories/grid-placeholder.png)`
- `![VEX consensus placeholder](../assets/ui/advisories/vex-placeholder.png)`
- Coordinate with Console Guild to capture updated screenshots (dark and light themes) once Sprint 23 build candidate is tagged. Tracking in Slack channel `#console-screenshots` (entry 2025-10-26).
---
## 14. References
- `/docs/ui/console-overview.md` - shell, filters, tenant model.
- `/docs/ui/navigation.md` - command palette, deep-link schema.
- `/docs/ingestion/aggregation-only-contract.md` - AOC guardrails.
- `/docs/architecture/CONCELIER.md` - merge rules, provenance.
- `/docs/architecture/EXCITITOR.md` - VEX consensus model.
- `/docs/security/console-security.md` - scopes, DPoP, CSP.
- `/docs/cli-vs-ui-parity.md` - CLI equivalence matrix.
---
## 15. Compliance checklist
- [ ] Advisory grid columns, filters, and merge hash behaviour documented.
- [ ] VEX consensus view covers status badges, provider breakdown, and filters.
- [ ] Raw viewer and provenance banners explained with AOC alignment.
- [ ] Conflict indicators and explainers tied to aggregation-not-merge rules.
- [ ] Verification workflow and CLI parity documented.
- [ ] Offline behaviour and automation paths captured.
- [ ] Screenshot placeholders and coordination notes recorded.
- [ ] References validated.
---
*Last updated: 2025-10-26 (Sprint 23).*
# StellaOps Console - Advisories and VEX
> **Audience:** Console UX team, Concelier and Excititor guilds, support and compliance engineers.
> **Scope:** Advisory aggregation UX, VEX consensus display, conflict indicators, raw document viewer, provenance banners, CLI parity, and Aggregation-Only Contract (AOC) guardrails for Sprint 23.
The Advisories and VEX surfaces expose Concelier and Excititor outputs without mutating the underlying data. Operators can review upstream statements, check consensus summaries, inspect conflicts, and hand off evidence to downstream tooling while staying within the Aggregation-Only Contract.
---
## 1. Access and prerequisites
- **Routes:**
- `/console/advisories` (advisory list and detail)
- `/console/vex` (VEX consensus and raw claim explorer)
- **Scopes:** `advisory.read` and `vex.read` (base access), `advisory.verify` / `vex.verify` for verification actions, `downloads.read` for evidence exports.
- **Feature flags:** `advisoryExplorer.enabled`, `vexExplorer.enabled`, `aggregation.conflictIndicators`.
- **Dependencies:** Concelier WebService (aggregation API + delta metrics), Excititor WebService (consensus API + conflict feeds), Policy Engine explain hints (optional link-outs), Authority tenant enforcement.
- **Offline behaviour:** Uses Offline Kit snapshots when gateway is in sealed mode; verify buttons queue until connectivity resumes.
---
## 2. Layout overview
```
+---------------------------------------------------------------------+
| Header: Tenant badge - global filters - status ticker - actions |
+---------------------------------------------------------------------+
| Left rail: Saved views - provider filters - verification queue |
+---------------------------------------------------------------------+
| Main split pane |
| - Advisories tab (grid + detail drawer) |
| - VEX tab (consensus table + claim drawer) |
| Tabs remember last active view per tenant. |
+---------------------------------------------------------------------+
```
The header reuses console-wide context chips (`Tenant`, `Severity`, `Source`, `Time`) and the status ticker that streams Concelier and Excititor deltas.
---
## 3. Advisory aggregation view
| Element | Description |
|---------|-------------|
| **Grid columns** | Vulnerability key (CVE/GHSA/vendor), Title, Source set, Last merged, Severity badge, KEV flag, Affected product count, Merge hash. |
| **Source chips** | Show contributing providers (NVD, Red Hat, Debian, vendor PSIRT). Hover reveals precedence order and timestamps. |
| **Severity** | Displays the highest severity declared by any source; tooltip lists per-source severities and vectors. |
| **KEV / Exploit status** | Badge highlights known exploited status from Concelier enrichment; links to KEV reference. |
| **Merge hash** | Deterministic hash from Concelier `merge_event`. Clicking copies hash and opens provenance banner. |
| **Filters** | Vulnerability identifier search, provider multi-select, severity picker, KEV toggle, affected product range slider, time window. |
| **List actions** | `Open detail`, `Copy CLI` (`stella advisory show ...`), `Compare sources`, `Queue verify`. |
The grid virtualises up to 15,000 advisories per tenant. Beyond that, the UI engages server-side pagination with cursor hints supplied by Concelier.
---
## 4. Advisory detail drawer
Sections within the drawer:
1. **Summary cards** (title, published/modified timestamps, advisory merge hash, total sources, exploited flag).
2. **Sources timeline** listing each contributing document with signature status, fetched timestamps, precedence rank, and quick links to raw view.
3. **Affected products** table (product key, introduced/fixed, range semantics, distro qualifiers, notes). Column toggles allow switching between SemVer and distro notation.
4. **Conflict indicators** show when sources disagree on fixed versions, severity, or affected sets. Each conflict row links to an explainer panel that describes the winning value, losing sources, and precedence rule.
5. **References** collapsible list (patches, advisories, exploits).
6. **Raw JSON** viewer (read-only) using canonical Concelier payload. Users can copy JSON or download via `GET /console/advisories/raw/{id}`.
7. **CLI parity** card with commands:
- `stella advisory show --tenant <tenant> --vuln <id>`
- `stella advisory sources --tenant <tenant> --vuln <id>`
- `stella advisory export --tenant <tenant> --vuln <id> --format cdx-json`
Provenance banner at the top indicates whether all sources are signed, partially signed, or unsigned, referencing AOC guardrails. Unsigned sources trigger a warning and link to the verification checklist.
---
## 5. VEX explorer
| Feature | Description |
|---------|-------------|
| **Consensus table** | Rows keyed by `(vulnId, productKey)` with rollup status (affected, not affected, fixed, under investigation), confidence score, provider count, and last evaluation timestamp. |
| **Status badges** | Colour-coded (red affected, green not affected, blue fixed, amber under investigation). Tooltips show justification and policy revision used. |
| **Provider breakdown** | Hover or expand to see source list with accepted/ignored flag, status, justification code, signature state, weight. |
| **Filters** | Product search (PURL), status filter, provider filter, justification codes, confidence threshold slider. |
| **Saved views** | Prebuilt presets: `Vendor consensus`, `Distro overrides`, `Conflicts`, `Pending investigation`. |
---
## 6. VEX detail drawer
Tabs within the drawer:
- **Consensus summary**: Restates rollup status, policy revision, confidence benchmarks, and referencing runs.
- **Claims list**: Every raw claim from Excititor with provenance, signature result, justification, supersedes chain, evidence snippets. Claims are grouped by provider tier (vendor, distro, ecosystem, CERT).
- **Conflict explainers**: For conflicting claims, shows why a claim was ignored (weight, stale timestamp, failing justification gate). Includes inline diff between competing claims.
- **Events**: Timeline of claim arrivals and consensus evaluations with correlation IDs, accessible for debugging.
- **Raw JSON**: Canonical `VexClaim` or `VexConsensus` payloads with copy/download. CLI parity callouts:
- `stella vex consensus show --tenant <tenant> --vuln <id> --product <purl>`
- `stella vex claims show --tenant <tenant> --vuln <id> --provider <provider>`
---
## 7. Raw viewers and provenance
- Raw viewers display canonical payloads with syntax highlighting and copy-as-JSON support.
- Provenance banner presents: source URI, document digest, signature status, fetch timestamps, collector version.
- Users can open raw documents in a modal that includes:
- `sha256` digest with copy button
- Signature verification summary (passing keys, missing signatures, errors)
- `Download DSSE bundle` button when the document is attested
- `Open in logs` link that copies search query (`correlationId=...`) for log aggregation tools.
All raw views are read-only to maintain Aggregation-Only guarantees.
---
## 8. Conflict indicators and aggregation-not-merge UX
- Concelier retains every source; the UI surfaces conflicts rather than merging them.
- Conflict badges appear in grids and detail views when sources disagree on affected ranges, fixed versions, severity, or exploit flags.
- Clicking a badge opens the conflict explainer panel (powered by Concelier merge metadata) that lists winning/losing sources, ranks, and reasoning (e.g., "Vendor PSIRT overrides ecosystem advisory").
- Excititor conflicts highlight discarded claims with reasons (stale, failing justification, low weight). Operators can override weights downstream via Policy Engine if needed.
- UI copy explicitly reminds users that policy decisions happen elsewhere; these views show aggregated facts only.
---
## 9. Verification workflows
- **Run verify** buttons call Concelier or Excititor verification endpoints (`POST /console/advisories/verify`, `POST /console/vex/verify`) scoped by tenant and source filters.
- Verification results appear as banners summarising documents checked, signatures verified, and guard violations.
- Failed verifications show actionable error IDs (`ERR_AOC_00x`), matching CLI output.
- Verification history accessible via the status ticker dropdown; entries include operator, scope, and correlation IDs.
---
## 10. Exports and automation
- Advisory tab exposes export actions: `Download normalized advisory`, `Download affected products CSV`, `Download source bundle` (raw documents packaged with manifest).
- VEX tab supports exports for consensus snapshots, raw claims, and provider deltas.
- Export manifests include merge hash or consensus digest, tenant ID, timestamp, and signature state.
- CLI parity snippets accompany each export (e.g., `stella advisory export`, `stella vex export`).
- Automation: copy buttons for webhook subscription (`/downloads/hooks/subscribe`) and ORAS push commands when using remote registries.
---
## 11. Observability and SSE updates
- Status ticker shows ingest lag (`advisory_delta_minutes`, `vex_delta_minutes`), last merge event hash, and verification queue depth.
- Advisory and VEX grids refresh via SSE channels; updates animate row badges (new source, conflict resolved).
- Metrics surfaced in drawers: ingestion age, signature pass rate, consensus evaluation duration.
- Errors display correlation IDs linking to Concelier/Excititor logs.
---
## 12. Offline and air-gap behaviour
- When offline, list views display snapshot badge, staleness timer, and disable real-time verification.
- Raw downloads reference local snapshot directories and include checksum instructions.
- Exports queue locally; UI offers `Copy to removable media` instructions.
- CLI parity switches to offline commands (`--offline`, `--snapshot`).
- Tenant picker hides tenants not present in the snapshot to avoid partial data views.
---
## 13. Screenshot coordination
- Placeholders (captures pending upload):
- `docs/assets/ui/advisories/grid-placeholder.png`
- `docs/assets/ui/advisories/vex-placeholder.png`
- Coordinate with Console Guild to capture updated screenshots (dark and light themes) once Sprint 23 build candidate is tagged. Tracking in Slack channel `#console-screenshots` (entry 2025-10-26).
---
## 14. References
- `/docs/ui/console-overview.md` - shell, filters, tenant model.
- `/docs/ui/navigation.md` - command palette, deep-link schema.
- `/docs/ingestion/aggregation-only-contract.md` - AOC guardrails.
- `/docs/architecture/CONCELIER.md` - merge rules, provenance.
- `/docs/architecture/EXCITITOR.md` - VEX consensus model.
- `/docs/security/console-security.md` - scopes, DPoP, CSP.
- `/docs/cli-vs-ui-parity.md` - CLI equivalence matrix.
---
## 15. Compliance checklist
- [ ] Advisory grid columns, filters, and merge hash behaviour documented.
- [ ] VEX consensus view covers status badges, provider breakdown, and filters.
- [ ] Raw viewer and provenance banners explained with AOC alignment.
- [ ] Conflict indicators and explainers tied to aggregation-not-merge rules.
- [ ] Verification workflow and CLI parity documented.
- [ ] Offline behaviour and automation paths captured.
- [ ] Screenshot placeholders and coordination notes recorded.
- [ ] References validated.
---
*Last updated: 2025-10-26 (Sprint 23).*

View File

@@ -1,130 +1,130 @@
# StellaOps Console Overview
> **Audience:** Console product leads, Docs Guild writers, backend/API partners.
> **Scope:** Information architecture, tenant scoping, global filters, and AggregationOnly Contract (AOC) alignment for the unified StellaOps Console that lands with Sprint23.
The StellaOps Console is the single entry point for operators to explore SBOMs, advisories, policies, runs, and administrative surfaces. This overview explains how the console is organised, how users move between tenants, and how shared filters keep data views consistent across modules while respecting AOC boundaries.
---
## 1·Mission & Principles
- **Deterministic navigation.** Every route is stable and deep-link friendly. URLs carry enough context (tenant, filter tokens, view modes) to let operators resume work without reapplying filters.
- **Tenant isolation first.** Any cross-tenant action requires fresh authority, and cross-tenant comparisons are made explicit so users never accidentally mix data sets.
- **Aggregation-not-merge UX.** Console surfaces advisory and VEX rollups exactly as produced by Concelier and Excititor—no client-side re-weighting or mutation.
- **Offline parity.** Every view has an offline equivalent powered by Offline Kit bundles or cached data, and exposes the staleness budget prominently.
---
## 2·Information Architecture
### 2.1 Primary navigation
```
Console Root
├─ Dashboard # KPIs, alerts, feed age, queue depth
├─ Findings # Aggregated vulns + explanations (Policy Engine)
├─ SBOM Explorer # Catalog, component graph, overlays
├─ Advisories & VEX # Concelier / Excititor aggregation outputs
├─ Runs # Scheduler runs, scan evidence, retry controls
├─ Policies # Editor, simulations, approvals
├─ Downloads # Signed artifacts, Offline Kit parity
├─ Admin # Tenants, roles, tokens, integrations
└─ Help & Tours # Contextual docs, guided walkthroughs
```
Routes lazy-load feature shells so the UI can grow without increasing first-paint cost. Each feature owns its sub-navigation and exposes a `KeyboardShortcuts` modal describing the available accelerators.
### 2.2 Shared surfaces
| Surface | Purpose | Notes |
|---------|---------|-------|
| **Top bar** | Shows active tenant, environment badge (prod/non-prod), offline status pill, user menu, notifications inbox, and the command palette trigger (`⌘/CtrlK`). | Offline status turns amber when data staleness exceeds configured thresholds. |
| **Global filter tray** | Expands from the right edge (`ShiftF`). Hosts universal filters (tenant, time window, tags, severity) that apply across compatible routes. | Filter tray remembers per-tenant presets; stored in IndexedDB (non-sensitive). |
| **Context chips** | Display active global filters underneath page titles, with one-click removal (`⌫`). | Chips include the origin (e.g., `Tenant: west-prod`). |
| **Status ticker** | SSE-driven strip that surfaces Concelier/Excititor ingestion deltas, scheduler lag, and attestor queue depth. | Pulls from `/console/status` proxy (see WEB-CONSOLE-23-002). |
---
## 3·Tenant Model
| Aspect | Detail |
|--------|--------|
| **Tenant sources** | The console obtains the tenant list and metadata from Authority `/v1/tenants` after login. Tenant descriptors include display name, slug, environment tag, and RBAC hints (role mask). |
| **Selection workflow** | First visit prompts for a default tenant. Afterwards, the tenant picker (`⌘/CtrlT`) switches context without full reload, issuing `Authorization` refresh with the new tenant scope. |
| **Token handling** | Each tenant change generates a short-lived, DPoP-bound access token (`aud=console`, `tenant=<id>`). Tokens live in memory; metadata persists in `sessionStorage` for reload continuity. |
| **Cross-tenant comparisons** | Side-by-side dashboards (Dashboard, Findings, SBOM Explorer) allow multi-tenant comparison only via explicit *"Add tenant"* control. Requests issue parallel API calls with separate tokens; results render in split panes labelled per tenant. |
| **Fresh-auth gated actions** | Admin and policy approvals call `Authority /fresh-auth` before executing. UI enforces a 5-minute window; afterwards, actions remain visible but disabled pending re-auth. |
| **Audit trail** | Tenant switches emit structured logs (`action=ui.tenant.switch`, `tenantId`, `subject`, `previousTenant`) and appear in Authority audit exports. |
### 3.1 Offline operation
In offline or sealed environments, the tenant picker only lists tenants bundled within the Offline Kit snapshot. Switching tenants prompts an "offline snapshot" banner showing the snapshot timestamp. Actions that require round-trips to Authority (fresh-auth, token rotation) show guidance to perform the step on an online bastion and import credentials later.
---
## 4·Global Filters & Context Tokens
| Filter | Applies To | Source & Behaviour |
|--------|------------|--------------------|
| **Tenant** | All modules | Primary isolation control. Stored in URL (`?tenant=`) and via `x-tenant-id` header injected by the web proxy. Changes invalidate cached data stores. |
| **Time window** | Dashboard, Findings, Advisories & VEX, Runs | Options: `24h`, `7d`, `30d`, custom ISO range. Default aligns with Compliance/Authority reporting window. Shared via query param `since=`/`until=`. |
| **Severity / Impact** | Findings, Advisories & VEX, SBOM Explorer overlays | Multi-select (Critical/High/Medium/Low/Informational, plus `Exploited` tag). Values map to Policy Engine impact buckets and Concelier KEV flags. |
| **Component tags** | SBOM Explorer, Findings | Tags drawn from SBOM metadata (`component.tags[]`). Includes search-as-you-type with scoped suggestions (package type, supplier, license). |
| **Source providers** | Advisories & VEX | Filter by provider IDs (e.g., NVD, GHSA, vendor VEX). Tied to Aggregation-Only provenance; filtering never alters base precedence. |
| **Run status** | Runs, Dashboard | States: `queued`, `running`, `completed`, `failed`, `cancelled`. Pulled from Scheduler SSE stream; default shows non-terminal states. |
| **Policy view** | Findings, Policies | Toggles between Active policy, Staged policy, and Simulation snapshots. Selecting Simulation requires prior simulation run; console links to create one if absent. |
Filters emit deterministic tokens placed in the URL hash for copy/paste parity with CLI commands (see `/docs/cli-vs-ui-parity.md`). The console warns when a filter combination has no effect on the current view and offers to reset to defaults.
### 4.1 Presets & Saved Views
Users can save a set of global filters as named presets (stored per tenant). Presets show up in the command palette and the dashboard landing cards for quick access (`⌘/Ctrl1..9`).
---
## 5·Aggregation-Only Alignment
- **Read-only aggregation.** Pages that list advisories or VEX claims consume the canonical aggregation endpoints (`/console/advisories`, `/console/vex`). They never merge or reconcile records client-side. Instead, they highlight the source lineage and precedence as supplied by Concelier and Excititor.
- **Consistency indicators.** Each aggregated item displays source badges, precedence order, and a "last merge event hash" so operators can cross-reference Concelier logs. When a source is missing or stale, the UI surfaces a provenance banner linking to the raw document.
- **AOC guardrails.** Workflow actions (e.g., "request verify", "download evidence bundle") route through Concelier WebService guard endpoints that enforce Aggregation-Only rules. UI strings reinforce that policy decisions happen in Policy Engine, not here.
- **Audit alignment.** Any cross-navigation from aggregated data into findings or policies preserves the underlying IDs so analysts can track how aggregated data influences policy verdicts without altering the data itself.
- **CLI parity.** Inline callouts copy the equivalent `stella` CLI commands, ensuring console users can recreate the exact aggregation query offline.
---
## 6·Performance & Telemetry Anchors
- Initial boot target: **<2.5s** `LargestContentfulPaint` on 4vCPU air-gapped runner with cached assets.
- Route budget: each feature shell must keep first interaction (hydrated data + filters) under **1.5s** once tokens resolve.
- Telemetry: console emits metrics via the `/console/telemetry` batch endpoint`ui_route_render_seconds`, `ui_filter_apply_total`, `ui_tenant_switch_total`, `ui_offline_banner_seconds`. Logs carry correlation IDs matching backend responses for unified tracing.
- Lighthouse CI runs in the console pipeline (see `DEVOPS-CONSOLE-23-001`) and asserts budgets above; failing runs gate releases.
---
## 7·References
- `/docs/architecture/console.md` component-level diagrams (pending Sprint23 task).
- `/docs/ui/navigation.md` detailed routes, breadcrumbs, keyboard shortcuts.
- `/docs/ui/downloads.md` downloads manifest, parity workflows, offline guidance.
- `/docs/ui/sbom-explorer.md` SBOM-specific flows and overlays.
- `/docs/ui/advisories-and-vex.md` aggregation UX details.
- `/docs/ui/findings.md` explain drawer and filter matrix.
- `/docs/security/console-security.md` OIDC, scopes, CSP, evidence handling.
- `/docs/cli-vs-ui-parity.md` CLI equivalents and regression automation.
---
## 8·Compliance Checklist
- [ ] Tenant picker enforces Authority-issued scopes and logs `ui.tenant.switch`.
- [ ] Global filters update URLs/query tokens for deterministic deep links.
- [ ] Aggregation views show provenance badges and merge hash indicators.
- [ ] CLI parity callouts aligned with `stella` commands for equivalent queries.
- [ ] Offline banner tested with Offline Kit snapshot import and documented staleness thresholds.
- [ ] Accessibility audit covers global filter tray, tenant picker, and keyboard shortcuts (WCAG2.2 AA).
- [ ] Telemetry and Lighthouse budgets tracked in console CI (`DEVOPS-CONSOLE-23-001`).
---
*Last updated: 2025-10-26 (Sprint23).*
# StellaOps Console Overview
> **Audience:** Console product leads, Docs Guild writers, backend/API partners.
> **Scope:** Information architecture, tenant scoping, global filters, and AggregationOnly Contract (AOC) alignment for the unified StellaOps Console that lands with Sprint23.
The StellaOps Console is the single entry point for operators to explore SBOMs, advisories, policies, runs, and administrative surfaces. This overview explains how the console is organised, how users move between tenants, and how shared filters keep data views consistent across modules while respecting AOC boundaries.
---
## 1·Mission & Principles
- **Deterministic navigation.** Every route is stable and deep-link friendly. URLs carry enough context (tenant, filter tokens, view modes) to let operators resume work without reapplying filters.
- **Tenant isolation first.** Any cross-tenant action requires fresh authority, and cross-tenant comparisons are made explicit so users never accidentally mix data sets.
- **Aggregation-not-merge UX.** Console surfaces advisory and VEX rollups exactly as produced by Concelier and Excititor—no client-side re-weighting or mutation.
- **Offline parity.** Every view has an offline equivalent powered by Offline Kit bundles or cached data, and exposes the staleness budget prominently.
---
## 2·Information Architecture
### 2.1 Primary navigation
```
Console Root
├─ Dashboard # KPIs, alerts, feed age, queue depth
├─ Findings # Aggregated vulns + explanations (Policy Engine)
├─ SBOM Explorer # Catalog, component graph, overlays
├─ Advisories & VEX # Concelier / Excititor aggregation outputs
├─ Runs # Scheduler runs, scan evidence, retry controls
├─ Policies # Editor, simulations, approvals
├─ Downloads # Signed artifacts, Offline Kit parity
├─ Admin # Tenants, roles, tokens, integrations
└─ Help & Tours # Contextual docs, guided walkthroughs
```
Routes lazy-load feature shells so the UI can grow without increasing first-paint cost. Each feature owns its sub-navigation and exposes a `KeyboardShortcuts` modal describing the available accelerators.
### 2.2 Shared surfaces
| Surface | Purpose | Notes |
|---------|---------|-------|
| **Top bar** | Shows active tenant, environment badge (prod/non-prod), offline status pill, user menu, notifications inbox, and the command palette trigger (`⌘/CtrlK`). | Offline status turns amber when data staleness exceeds configured thresholds. |
| **Global filter tray** | Expands from the right edge (`ShiftF`). Hosts universal filters (tenant, time window, tags, severity) that apply across compatible routes. | Filter tray remembers per-tenant presets; stored in IndexedDB (non-sensitive). |
| **Context chips** | Display active global filters underneath page titles, with one-click removal (`⌫`). | Chips include the origin (e.g., `Tenant: west-prod`). |
| **Status ticker** | SSE-driven strip that surfaces Concelier/Excititor ingestion deltas, scheduler lag, and attestor queue depth. | Pulls from `/console/status` proxy (see WEB-CONSOLE-23-002). |
---
## 3·Tenant Model
| Aspect | Detail |
|--------|--------|
| **Tenant sources** | The console obtains the tenant list and metadata from Authority `/v1/tenants` after login. Tenant descriptors include display name, slug, environment tag, and RBAC hints (role mask). |
| **Selection workflow** | First visit prompts for a default tenant. Afterwards, the tenant picker (`⌘/CtrlT`) switches context without full reload, issuing `Authorization` refresh with the new tenant scope. |
| **Token handling** | Each tenant change generates a short-lived, DPoP-bound access token (`aud=console`, `tenant=<id>`). Tokens live in memory; metadata persists in `sessionStorage` for reload continuity. |
| **Cross-tenant comparisons** | Side-by-side dashboards (Dashboard, Findings, SBOM Explorer) allow multi-tenant comparison only via explicit *"Add tenant"* control. Requests issue parallel API calls with separate tokens; results render in split panes labelled per tenant. |
| **Fresh-auth gated actions** | Admin and policy approvals call `Authority /fresh-auth` before executing. UI enforces a 5-minute window; afterwards, actions remain visible but disabled pending re-auth. |
| **Audit trail** | Tenant switches emit structured logs (`action=ui.tenant.switch`, `tenantId`, `subject`, `previousTenant`) and appear in Authority audit exports. |
### 3.1 Offline operation
In offline or sealed environments, the tenant picker only lists tenants bundled within the Offline Kit snapshot. Switching tenants prompts an "offline snapshot" banner showing the snapshot timestamp. Actions that require round-trips to Authority (fresh-auth, token rotation) show guidance to perform the step on an online bastion and import credentials later.
---
## 4·Global Filters & Context Tokens
| Filter | Applies To | Source & Behaviour |
|--------|------------|--------------------|
| **Tenant** | All modules | Primary isolation control. Stored in URL (`?tenant=`) and via `x-tenant-id` header injected by the web proxy. Changes invalidate cached data stores. |
| **Time window** | Dashboard, Findings, Advisories & VEX, Runs | Options: `24h`, `7d`, `30d`, custom ISO range. Default aligns with Compliance/Authority reporting window. Shared via query param `since=`/`until=`. |
| **Severity / Impact** | Findings, Advisories & VEX, SBOM Explorer overlays | Multi-select (Critical/High/Medium/Low/Informational, plus `Exploited` tag). Values map to Policy Engine impact buckets and Concelier KEV flags. |
| **Component tags** | SBOM Explorer, Findings | Tags drawn from SBOM metadata (`component.tags[]`). Includes search-as-you-type with scoped suggestions (package type, supplier, license). |
| **Source providers** | Advisories & VEX | Filter by provider IDs (e.g., NVD, GHSA, vendor VEX). Tied to Aggregation-Only provenance; filtering never alters base precedence. |
| **Run status** | Runs, Dashboard | States: `queued`, `running`, `completed`, `failed`, `cancelled`. Pulled from Scheduler SSE stream; default shows non-terminal states. |
| **Policy view** | Findings, Policies | Toggles between Active policy, Staged policy, and Simulation snapshots. Selecting Simulation requires prior simulation run; console links to create one if absent. |
Filters emit deterministic tokens placed in the URL hash for copy/paste parity with CLI commands (see `/docs/cli-vs-ui-parity.md`). The console warns when a filter combination has no effect on the current view and offers to reset to defaults.
### 4.1 Presets & Saved Views
Users can save a set of global filters as named presets (stored per tenant). Presets show up in the command palette and the dashboard landing cards for quick access (`⌘/Ctrl1..9`).
---
## 5·Aggregation-Only Alignment
- **Read-only aggregation.** Pages that list advisories or VEX claims consume the canonical aggregation endpoints (`/console/advisories`, `/console/vex`). They never merge or reconcile records client-side. Instead, they highlight the source lineage and precedence as supplied by Concelier and Excititor.
- **Consistency indicators.** Each aggregated item displays source badges, precedence order, and a "last merge event hash" so operators can cross-reference Concelier logs. When a source is missing or stale, the UI surfaces a provenance banner linking to the raw document.
- **AOC guardrails.** Workflow actions (e.g., "request verify", "download evidence bundle") route through Concelier WebService guard endpoints that enforce Aggregation-Only rules. UI strings reinforce that policy decisions happen in Policy Engine, not here.
- **Audit alignment.** Any cross-navigation from aggregated data into findings or policies preserves the underlying IDs so analysts can track how aggregated data influences policy verdicts without altering the data itself.
- **CLI parity.** Inline callouts copy the equivalent `stella` CLI commands, ensuring console users can recreate the exact aggregation query offline.
---
## 6·Performance & Telemetry Anchors
- Initial boot target: **<2.5s** `LargestContentfulPaint` on 4vCPU air-gapped runner with cached assets.
- Route budget: each feature shell must keep first interaction (hydrated data + filters) under **1.5s** once tokens resolve.
- Telemetry: console emits metrics via the `/console/telemetry` batch endpoint`ui_route_render_seconds`, `ui_filter_apply_total`, `ui_tenant_switch_total`, `ui_offline_banner_seconds`. Logs carry correlation IDs matching backend responses for unified tracing.
- Lighthouse CI runs in the console pipeline (see `DEVOPS-CONSOLE-23-001`) and asserts budgets above; failing runs gate releases.
---
## 7·References
- `/docs/architecture/console.md` component-level diagrams (pending Sprint23 task).
- `/docs/ui/navigation.md` detailed routes, breadcrumbs, keyboard shortcuts.
- `/docs/ui/downloads.md` downloads manifest, parity workflows, offline guidance.
- `/docs/ui/sbom-explorer.md` SBOM-specific flows and overlays.
- `/docs/ui/advisories-and-vex.md` aggregation UX details.
- `/docs/ui/findings.md` explain drawer and filter matrix.
- `/docs/security/console-security.md` OIDC, scopes, CSP, evidence handling.
- `/docs/cli-vs-ui-parity.md` CLI equivalents and regression automation.
---
## 8·Compliance Checklist
- [ ] Tenant picker enforces Authority-issued scopes and logs `ui.tenant.switch`.
- [ ] Global filters update URLs/query tokens for deterministic deep links.
- [ ] Aggregation views show provenance badges and merge hash indicators.
- [ ] CLI parity callouts aligned with `stella` commands for equivalent queries.
- [ ] Offline banner tested with Offline Kit snapshot import and documented staleness thresholds.
- [ ] Accessibility audit covers global filter tray, tenant picker, and keyboard shortcuts (WCAG2.2 AA).
- [ ] Telemetry and Lighthouse budgets tracked in console CI (`DEVOPS-CONSOLE-23-001`).
---
*Last updated: 2025-10-26 (Sprint23).*

View File

@@ -1,212 +1,212 @@
# StellaOps Console - Downloads Manager
> **Audience:** DevOps guild, Console engineers, enablement writers, and operators who promote releases or maintain offline mirrors.
> **Scope:** `/console/downloads` workspace covering artifact catalog, signed manifest plumbing, export status handling, CLI parity, automation hooks, and offline guidance (Sprint 23).
The Downloads workspace centralises every artefact required to deploy or validate StellaOps in connected and air-gapped environments. It keeps Console operators aligned with release engineering by surfacing the signed downloads manifest, live export jobs, parity checks against Offline Kit bundles, and automation hooks that mirror the CLI experience.
---
## 1 - Access and prerequisites
- **Route:** `/console/downloads` (list) with detail drawer `/console/downloads/:artifactId`.
- **Scopes:** `downloads.read` (baseline) and `downloads.manage` for cancelling or expiring stale exports. Evidence bundles inherit the originating scope (`runs.read`, `findings.read`, etc.).
- **Dependencies:** Web gateway `/console/downloads` API (WEB-CONSOLE-23-005), DevOps manifest pipeline (`deploy/downloads/manifest.json`), Offline Kit metadata (`manifest/offline-manifest.json`), and export orchestrator `/console/exports`.
- **Feature flags:** `downloads.workspace.enabled`, `downloads.exportQueue`, `downloads.offlineParity`.
- **Tenancy:** Artefacts are tenant-agnostic except evidence bundles, which are tagged with originating tenant and require matching Authority scopes.
---
## 2 - Workspace layout
```
+---------------------------------------------------------------+
| Header: Snapshot timestamp - Manifest signature status |
+---------------------------------------------------------------+
| Cards: Latest release - Offline kit parity - Export queue |
+---------------------------------------------------------------+
| Tabs: Artefacts | Exports | Offline Kits | Webhooks |
+---------------------------------------------------------------+
| Filter bar: Channel - Kind - Architecture - Scope tags |
+---------------------------------------------------------------+
| Table (virtualised): Artifact | Channel | Digest | Status |
| Detail drawer: Metadata | Commands | Provenance | History |
+---------------------------------------------------------------+
```
- **Snapshot banner:** shows `manifest.version`, `generatedAt`, and cosign verification state. If verification fails, the banner turns red and links to troubleshooting guidance.
- **Quick actions:** Copy manifest URL, download attestation bundle, trigger parity check, open CLI parity doc (`/docs/cli-vs-ui-parity.md`).
- **Filters:** allow narrowing by channel (`edge`, `stable`, `airgap`), artefact kind (`container.image`, `helm.chart`, `compose.bundle`, `offline.bundle`, `export.bundle`), architecture (`linux/amd64`, `linux/arm64`), and scope tags (`console`, `scheduler`, `authority`).
---
## 3 - Artefact catalogue
| Category | Artefacts surfaced | Source | Notes |
|----------|-------------------|--------|-------|
| **Core containers** | `stellaops/web-ui`, `stellaops/web`, `stellaops/concelier`, `stellaops/excititor`, `stellaops/scanner-*`, `stellaops/authority`, `stellaops/attestor`, `stellaops/scheduler-*` | `deploy/downloads/manifest.json` (`artifacts[].kind = "container.image"`) | Digest-only pulls with copy-to-clipboard `docker pull` and `oras copy` commands; badges show arch availability. |
| **Helm charts** | `deploy/helm/stellaops-*.tgz` plus values files | Manifest entries where `kind = "helm.chart"` | Commands reference `helm repo add` (online) and `helm install --values` (offline). UI links to values matrix in `/docs/install/helm-prod.md` when available. |
| **Compose bundles** | `deploy/compose/docker-compose.*.yaml`, `.env` seeds | `kind = "compose.bundle"` | Inline diff viewer highlights digest changes vs previous snapshot; `docker compose pull` command copies digest pins. |
| **Offline kit** | `stella-ops-offline-kit-<ver>-<channel>.tar.gz` + signatures and manifest | Offline Kit metadata (`manifest/offline-manifest.json`) merged into downloads view | Drawer shows bundle size, signed manifest digest, cosign verification command (mirrors `/docs/24_OFFLINE_KIT.md`). |
| **Evidence exports** | Completed jobs from `/console/exports` (findings delta, policy explain, run evidence) | Export orchestrator job queue | Entries expire after retention window; UI exposes `stella runs export` and `stella findings export` parity buttons. |
| **Webhooks & parity** | `/downloads/hooks/subscribe` configs, CI parity reports | Manifest extras (`kind = "webhook.config"`, `kind = "parity.report"`) | Operators can download webhook payload templates and review the latest CLI parity check report generated by docs CI. |
---
## 4 - Manifest structure
The DevOps pipeline publishes a deterministic manifest at `deploy/downloads/manifest.json`, signed with the release Cosign key (`DOWNLOADS-CONSOLE-23-001`). The Console fetches it on workspace load and caches it with `If-None-Match` headers to avoid redundant pulls. The manifest schema:
- **`version`** - monotonically increasing integer tied to pipeline run.
- **`generatedAt`** - ISO-8601 UTC timestamp.
- **`signature`** - URL to detached Cosign signature (`manifest.json.sig`).
- **`artifacts[]`** - ordered list keyed by `id`.
Each artefact contains:
| Field | Description |
|-------|-------------|
| `id` | Stable identifier (`<type>:<name>:<version>`). |
| `kind` | One of `container.image`, `helm.chart`, `compose.bundle`, `offline.bundle`, `export.bundle`, `webhook.config`, `parity.report`. |
| `channel` | `edge`, `stable`, or `airgap`. |
| `version` | Semantic or calendar version (for containers, matches release manifest). |
| `architectures` | Array of supported platforms (empty for arch-agnostic artefacts). |
| `digest` | SHA-256 for immutable artefacts; Compose bundles include file hash. |
| `sizeBytes` | File size (optional for export bundles that stream). |
| `downloadUrl` | HTTPS endpoint (registry, object store, or mirror). |
| `signatureUrl` | Detached signature (Cosign, DSSE, or attestation) if available. |
| `sbomUrl` | Optional SBOM pointer (CycloneDX JSON). |
| `attestationUrl` | Optional in-toto/SLSA attestation. |
| `docs` | Array of documentation links (e.g., `/docs/install/docker.md`). |
| `tags` | Free-form tags (e.g., `["console","ui","offline"]`). |
### 4.1 Example excerpt
```json
{
"version": 42,
"generatedAt": "2025-10-27T04:00:00Z",
"signature": "https://downloads.stella-ops.org/manifest/manifest.json.sig",
"artifacts": [
{
"id": "container.image:web-ui:2025.10.0-edge",
"kind": "container.image",
"channel": "edge",
"version": "2025.10.0-edge",
"architectures": ["linux/amd64", "linux/arm64"],
"digest": "sha256:38b225fa7767a5b94ebae4dae8696044126aac429415e93de514d5dd95748dcf",
"sizeBytes": 187563210,
"downloadUrl": "https://registry.stella-ops.org/v2/stellaops/web-ui/manifests/sha256:38b225fa7767a5b94ebae4dae8696044126aac429415e93de514d5dd95748dcf",
"signatureUrl": "https://downloads.stella-ops.org/signatures/web-ui-2025.10.0-edge.cosign.sig",
"sbomUrl": "https://downloads.stella-ops.org/sbom/web-ui-2025.10.0-edge.cdx.json",
"attestationUrl": "https://downloads.stella-ops.org/attestations/web-ui-2025.10.0-edge.intoto.jsonl",
"docs": ["/docs/install/docker.md", "/docs/security/console-security.md"],
"tags": ["console", "ui"]
},
{
"id": "offline.bundle:ouk:2025.10.0-edge",
"kind": "offline.bundle",
"channel": "edge",
"version": "2025.10.0-edge",
"digest": "sha256:4f7d2f7a8d0cf4b5f3af689f6c74cd213f4c1b3a1d76d24f6f9f3d9075e51f90",
"downloadUrl": "https://downloads.stella-ops.org/offline/stella-ops-offline-kit-2025.10.0-edge.tar.gz",
"signatureUrl": "https://downloads.stella-ops.org/offline/stella-ops-offline-kit-2025.10.0-edge.tar.gz.sig",
"sbomUrl": "https://downloads.stella-ops.org/offline/offline-manifest-2025.10.0-edge.json",
"docs": ["/docs/24_OFFLINE_KIT.md"],
"tags": ["offline", "airgap"]
}
]
}
```
Console caches the manifest hash and surfaces differences when a new version lands, helping operators confirm digests drift only when expected.
---
## 5 - Download workflows and statuses
| Status | Applies to | Behaviour |
|--------|------------|-----------|
| **Ready** | Immutable artefacts (images, Helm/Compose bundles, offline kit) | Commands available immediately. Digest, size, and last verification timestamp display in the table. |
| **Pending export** | Async exports queued via `/console/exports` | Shows job owner, scope, and estimated completion time. UI polls every 15 s and updates progress bar. |
| **Processing** | Long-running export (evidence bundle, large SBOM) | Drawer shows current stage (`collecting`, `compressing`, `signing`). Operators can cancel if they own the request and hold `downloads.manage`. |
| **Delivered** | Completed export within retention window | Provides download links, resume token, and parity snippet for CLI. |
| **Expired** | Export past retention or manually expired | Row grays out; clicking opens housekeeping guidance with CLI command to regenerate (`stella runs export --run <id>`). |
Exports inherit retention defaults defined in policy (`downloads.retentionDays`, min 3, max 30). Operators can override per tenant if they have the appropriate scope.
---
## 6 - CLI parity and copy-to-clipboard
- **Digest pulls:** Each container entry exposes `docker pull <image>@<digest>` and `oras copy <image>@<digest> --to-dir ./downloads` buttons. Commands include architecture hints for multi-platform images.
- **Helm/Compose:** Buttons output `helm pull` / `helm install` with the manifest URL and `docker compose --env-file` commands referencing the downloaded bundle.
- **Offline kit:** Copy buttons produce the full verification sequence:
```bash
curl -LO https://downloads.stella-ops.org/offline/stella-ops-offline-kit-2025.10.0-edge.tar.gz
curl -LO https://downloads.stella-ops.org/offline/stella-ops-offline-kit-2025.10.0-edge.tar.gz.sig
cosign verify-blob \
--key https://stella-ops.org/keys/cosign.pub \
--signature stella-ops-offline-kit-2025.10.0-edge.tar.gz.sig \
stella-ops-offline-kit-2025.10.0-edge.tar.gz
```
- **Exports:** Drawer lists CLI equivalents (for example, `stella findings export --run <id>`). When the CLI supports resume tokens, the command includes `--resume-token` from the manifest entry.
- **Automation:** Webhook tab copies `curl` snippets to subscribe to `/downloads/hooks/subscribe?topic=<artifact>` and includes payload schema for integration tests.
Parity buttons write commands to the clipboard and display a toast confirming scope hints (for example, `Requires downloads.read + tenant scope`). Accessibility shortcuts (`Shift+D`) trigger the primary copy action for keyboard users.
---
## 7 - Offline and air-gap workflow
- **Manifest sync:** Offline users download `manifest/offline-manifest.json` plus detached JWS and import it via `stella offline kit import`. Console highlights if the offline manifest predates the online manifest by more than 7 days.
- **Artefact staging:** The workspace enumerates removable media instructions (export to `./staging/<channel>/`) and warns when artefacts exceed configured media size thresholds.
- **Mirrors:** Buttons copy `oras copy` commands that mirror images to an internal registry (`registry.<tenant>.internal`). Operators can toggle `--insecure-policy` if the destination uses custom trust roots.
- **Parity checks:** `downloads.offlineParity` flag surfaces the latest parity report verifying that Offline Kit contents match the downloads manifest digests. If diff detected, UI raises a banner linking to remediation steps.
- **Audit logging:** Every download command triggered from the UI emits `ui.download.commandCopied` with artifact ID, digest, and tenant. Logs feed the evidence locker so air-gap imports can demonstrate provenance.
---
## 8 - Observability and quotas
| Signal | Source | Description |
|--------|--------|-------------|
| `ui_download_manifest_refresh_seconds` | Console metrics | Measures time to fetch and verify manifest. Targets < 3 s. |
| `ui_download_export_queue_depth` | `/console/downloads` API | Number of pending exports (per tenant). Surfaces as card and Grafana panel. |
| `ui_download_command_copied_total` | Console logs | Count of copy actions by artifact type, used to gauge CLI parity adoption. |
| `downloads.export.duration` | Export orchestrator | Duration histograms for bundle generation; alerts if P95 > 60 s. |
| `downloads.quota.remaining` | Authority quota service | Anonymous users limited to 33 exports/day, verified users 333/day. Banner turns amber at 90 % usage as per platform policy. |
Telemetry entries include correlation IDs that match backend manifest refresh logs and export job records to keep troubleshooting deterministic.
---
## 9 - References
- `/docs/ui/console-overview.md` - primary shell, tenant controls, SSE ticker.
- `/docs/ui/navigation.md` - route ownership and keyboard shortcuts.
- `/docs/ui/sbom-explorer.md` - export flows feeding the downloads queue.
- `/docs/ui/runs.md` - evidence bundle integration.
- `/docs/24_OFFLINE_KIT.md` - offline kit packaging and verification.
- `/docs/security/console-security.md` - scopes, CSP, and download token handling.
- `/docs/cli-vs-ui-parity.md` - CLI equivalence checks (pending).
- `deploy/releases/*.yaml` - source of container digests mirrored into the manifest.
---
## 10 - Compliance checklist
- [ ] Manifest schema documented (fields, signature, caching) and sample kept current.
- [ ] Artefact categories mapped to manifest entries and parity workflows.
- [ ] Download statuses, retention, and cancellation rules explained.
- [ ] CLI copy-to-clipboard commands mirror console actions with scope hints.
- [ ] Offline/air-gap parity workflow, mirror commands, and audit logging captured.
- [ ] Observability metrics and quota signalling documented.
- [ ] References cross-linked to adjacent docs (navigation, exports, offline kit).
- [ ] Accessibility shortcuts and copy-to-clipboard behaviour noted with compliance reminder.
---
*Last updated: 2025-10-27 (Sprint 23).*
# StellaOps Console - Downloads Manager
> **Audience:** DevOps guild, Console engineers, enablement writers, and operators who promote releases or maintain offline mirrors.
> **Scope:** `/console/downloads` workspace covering artifact catalog, signed manifest plumbing, export status handling, CLI parity, automation hooks, and offline guidance (Sprint 23).
The Downloads workspace centralises every artefact required to deploy or validate StellaOps in connected and air-gapped environments. It keeps Console operators aligned with release engineering by surfacing the signed downloads manifest, live export jobs, parity checks against Offline Kit bundles, and automation hooks that mirror the CLI experience.
---
## 1 - Access and prerequisites
- **Route:** `/console/downloads` (list) with detail drawer `/console/downloads/:artifactId`.
- **Scopes:** `downloads.read` (baseline) and `downloads.manage` for cancelling or expiring stale exports. Evidence bundles inherit the originating scope (`runs.read`, `findings.read`, etc.).
- **Dependencies:** Web gateway `/console/downloads` API (WEB-CONSOLE-23-005), DevOps manifest pipeline (`deploy/downloads/manifest.json`), Offline Kit metadata (`manifest/offline-manifest.json`), and export orchestrator `/console/exports`.
- **Feature flags:** `downloads.workspace.enabled`, `downloads.exportQueue`, `downloads.offlineParity`.
- **Tenancy:** Artefacts are tenant-agnostic except evidence bundles, which are tagged with originating tenant and require matching Authority scopes.
---
## 2 - Workspace layout
```
+---------------------------------------------------------------+
| Header: Snapshot timestamp - Manifest signature status |
+---------------------------------------------------------------+
| Cards: Latest release - Offline kit parity - Export queue |
+---------------------------------------------------------------+
| Tabs: Artefacts | Exports | Offline Kits | Webhooks |
+---------------------------------------------------------------+
| Filter bar: Channel - Kind - Architecture - Scope tags |
+---------------------------------------------------------------+
| Table (virtualised): Artifact | Channel | Digest | Status |
| Detail drawer: Metadata | Commands | Provenance | History |
+---------------------------------------------------------------+
```
- **Snapshot banner:** shows `manifest.version`, `generatedAt`, and cosign verification state. If verification fails, the banner turns red and links to troubleshooting guidance.
- **Quick actions:** Copy manifest URL, download attestation bundle, trigger parity check, open CLI parity doc (`/docs/cli-vs-ui-parity.md`).
- **Filters:** allow narrowing by channel (`edge`, `stable`, `airgap`), artefact kind (`container.image`, `helm.chart`, `compose.bundle`, `offline.bundle`, `export.bundle`), architecture (`linux/amd64`, `linux/arm64`), and scope tags (`console`, `scheduler`, `authority`).
---
## 3 - Artefact catalogue
| Category | Artefacts surfaced | Source | Notes |
|----------|-------------------|--------|-------|
| **Core containers** | `stellaops/web-ui`, `stellaops/web`, `stellaops/concelier`, `stellaops/excititor`, `stellaops/scanner-*`, `stellaops/authority`, `stellaops/attestor`, `stellaops/scheduler-*` | `deploy/downloads/manifest.json` (`artifacts[].kind = "container.image"`) | Digest-only pulls with copy-to-clipboard `docker pull` and `oras copy` commands; badges show arch availability. |
| **Helm charts** | `deploy/helm/stellaops-*.tgz` plus values files | Manifest entries where `kind = "helm.chart"` | Commands reference `helm repo add` (online) and `helm install --values` (offline). UI links to values matrix in `/docs/install/helm-prod.md` when available. |
| **Compose bundles** | `deploy/compose/docker-compose.*.yaml`, `.env` seeds | `kind = "compose.bundle"` | Inline diff viewer highlights digest changes vs previous snapshot; `docker compose pull` command copies digest pins. |
| **Offline kit** | `stella-ops-offline-kit-<ver>-<channel>.tar.gz` + signatures and manifest | Offline Kit metadata (`manifest/offline-manifest.json`) merged into downloads view | Drawer shows bundle size, signed manifest digest, cosign verification command (mirrors `/docs/24_OFFLINE_KIT.md`). |
| **Evidence exports** | Completed jobs from `/console/exports` (findings delta, policy explain, run evidence) | Export orchestrator job queue | Entries expire after retention window; UI exposes `stella runs export` and `stella findings export` parity buttons. |
| **Webhooks & parity** | `/downloads/hooks/subscribe` configs, CI parity reports | Manifest extras (`kind = "webhook.config"`, `kind = "parity.report"`) | Operators can download webhook payload templates and review the latest CLI parity check report generated by docs CI. |
---
## 4 - Manifest structure
The DevOps pipeline publishes a deterministic manifest at `deploy/downloads/manifest.json`, signed with the release Cosign key (`DOWNLOADS-CONSOLE-23-001`). The Console fetches it on workspace load and caches it with `If-None-Match` headers to avoid redundant pulls. The manifest schema:
- **`version`** - monotonically increasing integer tied to pipeline run.
- **`generatedAt`** - ISO-8601 UTC timestamp.
- **`signature`** - URL to detached Cosign signature (`manifest.json.sig`).
- **`artifacts[]`** - ordered list keyed by `id`.
Each artefact contains:
| Field | Description |
|-------|-------------|
| `id` | Stable identifier (`<type>:<name>:<version>`). |
| `kind` | One of `container.image`, `helm.chart`, `compose.bundle`, `offline.bundle`, `export.bundle`, `webhook.config`, `parity.report`. |
| `channel` | `edge`, `stable`, or `airgap`. |
| `version` | Semantic or calendar version (for containers, matches release manifest). |
| `architectures` | Array of supported platforms (empty for arch-agnostic artefacts). |
| `digest` | SHA-256 for immutable artefacts; Compose bundles include file hash. |
| `sizeBytes` | File size (optional for export bundles that stream). |
| `downloadUrl` | HTTPS endpoint (registry, object store, or mirror). |
| `signatureUrl` | Detached signature (Cosign, DSSE, or attestation) if available. |
| `sbomUrl` | Optional SBOM pointer (CycloneDX JSON). |
| `attestationUrl` | Optional in-toto/SLSA attestation. |
| `docs` | Array of documentation links (e.g., `/docs/install/docker.md`). |
| `tags` | Free-form tags (e.g., `["console","ui","offline"]`). |
### 4.1 Example excerpt
```json
{
"version": 42,
"generatedAt": "2025-10-27T04:00:00Z",
"signature": "https://downloads.stella-ops.org/manifest/manifest.json.sig",
"artifacts": [
{
"id": "container.image:web-ui:2025.10.0-edge",
"kind": "container.image",
"channel": "edge",
"version": "2025.10.0-edge",
"architectures": ["linux/amd64", "linux/arm64"],
"digest": "sha256:38b225fa7767a5b94ebae4dae8696044126aac429415e93de514d5dd95748dcf",
"sizeBytes": 187563210,
"downloadUrl": "https://registry.stella-ops.org/v2/stellaops/web-ui/manifests/sha256:38b225fa7767a5b94ebae4dae8696044126aac429415e93de514d5dd95748dcf",
"signatureUrl": "https://downloads.stella-ops.org/signatures/web-ui-2025.10.0-edge.cosign.sig",
"sbomUrl": "https://downloads.stella-ops.org/sbom/web-ui-2025.10.0-edge.cdx.json",
"attestationUrl": "https://downloads.stella-ops.org/attestations/web-ui-2025.10.0-edge.intoto.jsonl",
"docs": ["/docs/install/docker.md", "/docs/security/console-security.md"],
"tags": ["console", "ui"]
},
{
"id": "offline.bundle:ouk:2025.10.0-edge",
"kind": "offline.bundle",
"channel": "edge",
"version": "2025.10.0-edge",
"digest": "sha256:4f7d2f7a8d0cf4b5f3af689f6c74cd213f4c1b3a1d76d24f6f9f3d9075e51f90",
"downloadUrl": "https://downloads.stella-ops.org/offline/stella-ops-offline-kit-2025.10.0-edge.tar.gz",
"signatureUrl": "https://downloads.stella-ops.org/offline/stella-ops-offline-kit-2025.10.0-edge.tar.gz.sig",
"sbomUrl": "https://downloads.stella-ops.org/offline/offline-manifest-2025.10.0-edge.json",
"docs": ["/docs/24_OFFLINE_KIT.md"],
"tags": ["offline", "airgap"]
}
]
}
```
Console caches the manifest hash and surfaces differences when a new version lands, helping operators confirm digests drift only when expected.
---
## 5 - Download workflows and statuses
| Status | Applies to | Behaviour |
|--------|------------|-----------|
| **Ready** | Immutable artefacts (images, Helm/Compose bundles, offline kit) | Commands available immediately. Digest, size, and last verification timestamp display in the table. |
| **Pending export** | Async exports queued via `/console/exports` | Shows job owner, scope, and estimated completion time. UI polls every 15 s and updates progress bar. |
| **Processing** | Long-running export (evidence bundle, large SBOM) | Drawer shows current stage (`collecting`, `compressing`, `signing`). Operators can cancel if they own the request and hold `downloads.manage`. |
| **Delivered** | Completed export within retention window | Provides download links, resume token, and parity snippet for CLI. |
| **Expired** | Export past retention or manually expired | Row grays out; clicking opens housekeeping guidance with CLI command to regenerate (`stella runs export --run <id>`). |
Exports inherit retention defaults defined in policy (`downloads.retentionDays`, min 3, max 30). Operators can override per tenant if they have the appropriate scope.
---
## 6 - CLI parity and copy-to-clipboard
- **Digest pulls:** Each container entry exposes `docker pull <image>@<digest>` and `oras copy <image>@<digest> --to-dir ./downloads` buttons. Commands include architecture hints for multi-platform images.
- **Helm/Compose:** Buttons output `helm pull` / `helm install` with the manifest URL and `docker compose --env-file` commands referencing the downloaded bundle.
- **Offline kit:** Copy buttons produce the full verification sequence:
```bash
curl -LO https://downloads.stella-ops.org/offline/stella-ops-offline-kit-2025.10.0-edge.tar.gz
curl -LO https://downloads.stella-ops.org/offline/stella-ops-offline-kit-2025.10.0-edge.tar.gz.sig
cosign verify-blob \
--key https://stella-ops.org/keys/cosign.pub \
--signature stella-ops-offline-kit-2025.10.0-edge.tar.gz.sig \
stella-ops-offline-kit-2025.10.0-edge.tar.gz
```
- **Exports:** Drawer lists CLI equivalents (for example, `stella findings export --run <id>`). When the CLI supports resume tokens, the command includes `--resume-token` from the manifest entry.
- **Automation:** Webhook tab copies `curl` snippets to subscribe to `/downloads/hooks/subscribe?topic=<artifact>` and includes payload schema for integration tests.
Parity buttons write commands to the clipboard and display a toast confirming scope hints (for example, `Requires downloads.read + tenant scope`). Accessibility shortcuts (`Shift+D`) trigger the primary copy action for keyboard users.
---
## 7 - Offline and air-gap workflow
- **Manifest sync:** Offline users download `manifest/offline-manifest.json` plus detached JWS and import it via `stella offline kit import`. Console highlights if the offline manifest predates the online manifest by more than 7 days.
- **Artefact staging:** The workspace enumerates removable media instructions (export to `./staging/<channel>/`) and warns when artefacts exceed configured media size thresholds.
- **Mirrors:** Buttons copy `oras copy` commands that mirror images to an internal registry (`registry.<tenant>.internal`). Operators can toggle `--insecure-policy` if the destination uses custom trust roots.
- **Parity checks:** `downloads.offlineParity` flag surfaces the latest parity report verifying that Offline Kit contents match the downloads manifest digests. If diff detected, UI raises a banner linking to remediation steps.
- **Audit logging:** Every download command triggered from the UI emits `ui.download.commandCopied` with artifact ID, digest, and tenant. Logs feed the evidence locker so air-gap imports can demonstrate provenance.
---
## 8 - Observability and quotas
| Signal | Source | Description |
|--------|--------|-------------|
| `ui_download_manifest_refresh_seconds` | Console metrics | Measures time to fetch and verify manifest. Targets < 3 s. |
| `ui_download_export_queue_depth` | `/console/downloads` API | Number of pending exports (per tenant). Surfaces as card and Grafana panel. |
| `ui_download_command_copied_total` | Console logs | Count of copy actions by artifact type, used to gauge CLI parity adoption. |
| `downloads.export.duration` | Export orchestrator | Duration histograms for bundle generation; alerts if P95 > 60 s. |
| `downloads.quota.remaining` | Authority quota service | Anonymous users limited to 33 exports/day, verified users 333/day. Banner turns amber at 90 % usage as per platform policy. |
Telemetry entries include correlation IDs that match backend manifest refresh logs and export job records to keep troubleshooting deterministic.
---
## 9 - References
- `/docs/ui/console-overview.md` - primary shell, tenant controls, SSE ticker.
- `/docs/ui/navigation.md` - route ownership and keyboard shortcuts.
- `/docs/ui/sbom-explorer.md` - export flows feeding the downloads queue.
- `/docs/ui/runs.md` - evidence bundle integration.
- `/docs/24_OFFLINE_KIT.md` - offline kit packaging and verification.
- `/docs/security/console-security.md` - scopes, CSP, and download token handling.
- `/docs/cli-vs-ui-parity.md` - CLI equivalence checks (pending).
- `deploy/releases/*.yaml` - source of container digests mirrored into the manifest.
---
## 10 - Compliance checklist
- [ ] Manifest schema documented (fields, signature, caching) and sample kept current.
- [ ] Artefact categories mapped to manifest entries and parity workflows.
- [ ] Download statuses, retention, and cancellation rules explained.
- [ ] CLI copy-to-clipboard commands mirror console actions with scope hints.
- [ ] Offline/air-gap parity workflow, mirror commands, and audit logging captured.
- [ ] Observability metrics and quota signalling documented.
- [ ] References cross-linked to adjacent docs (navigation, exports, offline kit).
- [ ] Accessibility shortcuts and copy-to-clipboard behaviour noted with compliance reminder.
---
*Last updated: 2025-10-27 (Sprint 23).*

View File

@@ -143,9 +143,9 @@ Explain drawer includes copy-to-clipboard buttons for rule chain and evidence JS
## 10. Screenshot coordination
- Placeholders:
- `![Findings grid placeholder](../assets/ui/findings/grid-placeholder.png)`
- `![Explain drawer placeholder](../assets/ui/findings/explain-placeholder.png)`
- Placeholders (captures pending upload):
- `docs/assets/ui/findings/grid-placeholder.png`
- `docs/assets/ui/findings/explain-placeholder.png`
- Coordinate with Console Guild (Slack `#console-screenshots`, entry 2025-10-26) to capture updated light and dark theme shots before release.
---
@@ -176,4 +176,3 @@ Explain drawer includes copy-to-clipboard buttons for rule chain and evidence JS
---
*Last updated: 2025-10-26 (Sprint 23).*

View File

@@ -1,163 +1,163 @@
# StellaOps Console - Navigation
> **Audience:** Console UX writers, UI engineers, QA, and enablement teams.
> **Scope:** Primary route map, layout conventions, keyboard shortcuts, deep-link patterns, and tenant context switching for the StellaOps Console (Sprint 23).
The navigation framework keeps Console workflows predictable across tenants and deployment modes. This guide explains how the global shell, feature routes, and context tokens cooperate so operators can jump between findings, SBOMs, advisories, policies, and runs without losing scope.
---
## 1. Information Architecture
### 1.1 Primary routes
| Route pattern | Module owner | Purpose | Required scopes (minimum) | Core services |
|---------------|--------------|---------|---------------------------|---------------|
| `/console/dashboard` | Web gateway | Landing KPIs, feed age, queue depth, alerts | `ui.read` | Web, Scheduler WebService, Concelier WebService, Excititor WebService |
| `/console/findings` | Policy Engine | Aggregated findings, explain drawer, export | `findings.read` | Policy Engine, Concelier WebService, SBOM Service |
| `/console/sbom` | SBOM Service | Catalog view, component graph, overlays | `sbom.read` | SBOM Service, Policy Engine (overlays) |
| `/console/advisories` | Concelier | Advisory aggregation with provenance banners | `advisory.read` | Concelier WebService |
| `/console/vex` | Excititor | VEX aggregation, consensus, conflicts | `vex.read` | Excititor WebService |
| `/console/runs` | Scheduler | Run list, live progress, evidence downloads | `runs.read` | Scheduler WebService, Policy Engine, Scanner WebService |
| `/console/policies` | Policy Engine | Editor, simulations, approvals | `policy.read` (read) / `policy.write` (edit) | Policy Engine, Authority |
| `/console/downloads` | DevOps | Signed artifacts, Offline Kit parity checklist | `downloads.read` | DevOps manifest API, Offline Kit |
| `/console/admin` | Authority | Tenants, roles, tokens, integrations | `ui.admin` (plus scoped `authority:*`) | Authority |
| `/console/help` | Docs Guild | Guides, tours, release notes | `ui.read` | Docs static assets |
### 1.2 Secondary navigation elements
- **Left rail:** highlights the active top-level route, exposes quick metrics, and shows pinned saved views. Keyboard focus cycles through rail entries with `Tab`/`Shift+Tab`.
- **Breadcrumb bar:** renders `Home / Module / Detail` format. Detail crumbs include IDs and titles for shareable context (for example, `Findings / High Severity / CVE-2025-1234`).
- **Action shelf:** right-aligned controls for context actions (export, verify, retry). Buttons disable automatically if the current subject lacks the requisite scope.
---
## 2. Command Palette and Search
- **Trigger:** `Ctrl/Cmd + K`. Palette opens in place, keeps focus, and announces results via ARIA live region.
- **Capabilities:** jump to routes, saved views, tenants, recent entities (findings, SBOMs, advisories), and command actions (for example, "Start verification", "Open explain drawer").
- **Result tokens:** palette entries carry metadata (`type`, `tenant`, `filters`). Selecting an item updates the URL and applies stored filters without a full reload.
- **Offline fallback:** in sealed/offline mode, palette restricts actions to cached routes and saved views; remote-only items show a grayed-out badge.
---
## 3. Global Filters and Context Chips
| Control | Shortcut | Persistence | Notes |
|---------|----------|-------------|-------|
| **Tenant picker** | `Ctrl/Cmd + T` | SessionStorage + URL `tenant` query | Issues fresh Authority token, invalidates caches, emits `ui.tenant.switch` log. |
| **Filter tray** | `Shift + F` | IndexedDB (per tenant) + URL query (`since`, `severity`, `tags`, `source`, `status`, `policyView`) | Applies instantly to compatible routes; incompatible filters show a reset suggestion. |
| **Component search** | `/` when filters closed | URL `component` query | Context-aware; scopes results to current tenant and module. |
| **Time window** | `Ctrl/Cmd + Shift + 1-4` | URL `since`/`until`, palette preset | Mapped to preset windows: 24 h, 7 d, 30 d, custom. |
Context chips appear beneath page titles summarising active filters (for example, `Tenant: west-prod`, `Severity: Critical+High`, `Time: Last 7 days`). Removing a chip updates the tray and URL atomically.
---
## 4. Keyboard Shortcut Matrix
| Scope | Shortcut (Mac / Windows) | Action | Notes |
|-------|--------------------------|--------|-------|
| Global | `Cmd+K / Ctrl+K` | Open command palette | Accessible from any route except modal dialogs. |
| Global | `Cmd+T / Ctrl+T` | Open tenant switcher | Requires `ui.read`. Confirm selection with `Enter`; `Esc` cancels without switching. |
| Global | `Shift+F` | Toggle global filter tray | Focus lands on first filter control. |
| Global | `Cmd+1-9 / Ctrl+1-9` | Load saved view preset | Each preset bound per tenant; non-assigned keys show tooltip. |
| Global | `?` | Show keyboard reference overlay | Overlay lists context-specific shortcuts; closes with `Esc`. |
| Findings module | `Cmd+/ / Ctrl+/` | Focus explain search | Works when explain drawer is open. |
| SBOM module | `Cmd+G / Ctrl+G` | Toggle graph overlays | Persists per session. |
| Advisories & VEX | `Cmd+Opt+F / Ctrl+Alt+F` | Focus provider filter | Highlights provider chip strip. |
| Runs module | `Cmd+R / Ctrl+R` | Refresh SSE snapshot | Schedules soft refresh (no hard reload). |
| Policies module | `Cmd+S / Ctrl+S` | Save draft (if edit rights) | Mirrors Policy Editor behaviour. |
Shortcut handling follows WCAG 2.2 best practices: all accelerators are remappable via Settings -> Accessibility -> Keyboard shortcuts, and the overlay documents platform differences.
---
## 5. Deep-Link Patterns
### 5.1 URL schema
Console URLs adopt the format:
```
/console/<route>[/:id][/:tab]?tenant=<slug>&since=<iso>&severity=<list>&view=<token>&panel=<drawer>&component=<purl>
```
- **`tenant`** is mandatory and matches Authority slugs (e.g., `acme-prod`).
- **`since` / `until`** use ISO-8601 timestamps (UTC). Preset ranges set only `since`; UI computes `until` on load.
- **`severity`** accepts comma-separated policy buckets (e.g., `critical,high,kev`).
- **`view`** stores module-specific state (e.g., `sbomView=usage`, `findingsPreset=threat-hunting`).
- **`panel`** selects drawers or tabs (`panel=explain`, `panel=timeline`).
### 5.2 Copyable links
- Share links from the action shelf or context chips; both copy canonical URLs with all active filters.
- CLI parity: inline callouts provide `stella` commands derived from the URL parameters to ensure console/CLI equivalence.
- Offline note: links copied in sealed mode include the snapshot ID (`snapshot=<hash>`) so recipients know which offline data set to load.
### 5.3 Examples
- **`since` / `until`** use ISO-8601 timestamps (UTC). Preset ranges set only `since`; UI computes `until` on load.
- **`severity`** accepts comma-separated policy buckets (e.g., `critical,high,kev`).
- **`view`** stores module-specific state (e.g., `sbomView=usage`, `findingsPreset=threat-hunting`).
- **`panel`** selects drawers or tabs (`panel=explain`, `panel=timeline`).
- **`component`** encodes package selection using percent-encoded PURL syntax.
- **`snapshot`** appears when copying links offline to reference Offline Kit build hash.
@@
| Use case | Example URL | Description |
|----------|-------------|-------------|
| Findings triage | `/console/findings?v=table&severity=critical,high&tenant=west-prod&since=2025-10-20T00:00:00Z` | Opens the findings table limited to critical/high for west-prod, last 7 days. |
| SBOM component focus | `/console/sbom/sha256:abcd?tenant=west-prod&component=pkg:npm/react@18.3.0&view=usage` | Deep-links to a specific image digest and highlights an NPM package in Usage view. |
| Advisory explain | `/console/advisories?tenant=west-prod&source=nvd&panel=detail&documentId=CVE-2025-1234` | Opens advisory list filtered to NVD and expands CVE detail drawer. |
| Run monitor | `/console/runs/42?tenant=west-prod&panel=progress` | Focuses run ID 42 with progress drawer active (SSE stream attached). |
---
## 6. Tenant Switching Lifecycle
1. **Initiate:** User triggers `Ctrl/Cmd + T` or clicks the tenant badge. Switcher modal lists authorised tenants and recent selections.
2. **Preview:** Selecting a tenant shows summary (environment, last snapshot, role coverage). The modal flags tenants missing required scopes for the current route.
3. **Confirm:** On confirmation, the UI requests a new DPoP-bound access token from Authority (`aud=console`, `tenant=<id>`).
4. **Invalidate caches:** Stores keyed by tenant purge automatically; modules emit `tenantChanged` events so in-flight SSE streams reconnect with new headers.
5. **Restore state:** Global filters reapply where valid. Incompatible filters (for example, a saved view unavailable in the new tenant) prompt users to pick a fallback.
6. **Audit and telemetry:** `ui.tenant.switch` log writes subject, from/to tenant, correlation ID. Metric `ui_tenant_switch_total` increments for observability dashboards.
7. **Offline behaviour:** If the target tenant is absent from the offline snapshot, switcher displays guidance to import updated Offline Kit data before proceeding.
---
## 7. Breadcrumbs, Tabs, and Focus Management
- Breadcrumb titles update synchronously with route data loads. When fragments change (for example, selecting a finding), the breadcrumb text updates without pushing a new history entry to keep back/forward predictable.
- Detail views rely on accessible tabs (`role="tablist"`) with keyboard support (`ArrowLeft/Right`). Tab selection updates the URL `tab` parameter for deep linking.
- Focus management:
- Route changes send focus to the primary heading (`h1`) using the live region announcer.
- Opening drawers or modals traps focus until closed; ESC returns focus to the triggering element.
- Keyboard-only navigation is validated via automated Playwright accessibility checks as part of `DEVOPS-CONSOLE-23-001`.
---
## 8. References
- `/docs/ui/console-overview.md` - structural overview, tenant model, global filters.
- `/docs/ui/sbom-explorer.md` - SBOM-specific navigation and graphs (pending).
- `/docs/ui/advisories-and-vex.md` - aggregation UX details (pending).
- `/docs/ui/findings.md` - findings filters and explain drawer (pending).
- `/docs/security/console-security.md` - Authority, scopes, CSP.
- `/docs/cli-vs-ui-parity.md` - CLI equivalence matrix.
- `/docs/accessibility.md` - keyboard remapping, WCAG validation checklists.
---
## 9. Compliance Checklist
- [ ] Route table matches Console build (paths, scopes, owners verified with Console Guild).
- [ ] Keyboard shortcut matrix reflects implemented accelerators and accessibility overlay.
- [ ] Deep-link examples tested for copy/share parity and CLI alignment.
- [ ] Tenant switching flow documents cache invalidation and audit logging.
- [ ] Filter tray, command palette, and presets cross-referenced with accessibility guidance.
- [ ] Offline/air-gap notes included for palette, tenant switcher, and deep-link metadata.
- [ ] Links to dependent docs (`/docs/ui/*`, `/docs/security/*`) validated.
---
*Last updated: 2025-10-26 (Sprint 23).*
# StellaOps Console - Navigation
> **Audience:** Console UX writers, UI engineers, QA, and enablement teams.
> **Scope:** Primary route map, layout conventions, keyboard shortcuts, deep-link patterns, and tenant context switching for the StellaOps Console (Sprint 23).
The navigation framework keeps Console workflows predictable across tenants and deployment modes. This guide explains how the global shell, feature routes, and context tokens cooperate so operators can jump between findings, SBOMs, advisories, policies, and runs without losing scope.
---
## 1. Information Architecture
### 1.1 Primary routes
| Route pattern | Module owner | Purpose | Required scopes (minimum) | Core services |
|---------------|--------------|---------|---------------------------|---------------|
| `/console/dashboard` | Web gateway | Landing KPIs, feed age, queue depth, alerts | `ui.read` | Web, Scheduler WebService, Concelier WebService, Excititor WebService |
| `/console/findings` | Policy Engine | Aggregated findings, explain drawer, export | `findings.read` | Policy Engine, Concelier WebService, SBOM Service |
| `/console/sbom` | SBOM Service | Catalog view, component graph, overlays | `sbom.read` | SBOM Service, Policy Engine (overlays) |
| `/console/advisories` | Concelier | Advisory aggregation with provenance banners | `advisory.read` | Concelier WebService |
| `/console/vex` | Excititor | VEX aggregation, consensus, conflicts | `vex.read` | Excititor WebService |
| `/console/runs` | Scheduler | Run list, live progress, evidence downloads | `runs.read` | Scheduler WebService, Policy Engine, Scanner WebService |
| `/console/policies` | Policy Engine | Editor, simulations, approvals | `policy.read` (read) / `policy.write` (edit) | Policy Engine, Authority |
| `/console/downloads` | DevOps | Signed artifacts, Offline Kit parity checklist | `downloads.read` | DevOps manifest API, Offline Kit |
| `/console/admin` | Authority | Tenants, roles, tokens, integrations | `ui.admin` (plus scoped `authority:*`) | Authority |
| `/console/help` | Docs Guild | Guides, tours, release notes | `ui.read` | Docs static assets |
### 1.2 Secondary navigation elements
- **Left rail:** highlights the active top-level route, exposes quick metrics, and shows pinned saved views. Keyboard focus cycles through rail entries with `Tab`/`Shift+Tab`.
- **Breadcrumb bar:** renders `Home / Module / Detail` format. Detail crumbs include IDs and titles for shareable context (for example, `Findings / High Severity / CVE-2025-1234`).
- **Action shelf:** right-aligned controls for context actions (export, verify, retry). Buttons disable automatically if the current subject lacks the requisite scope.
---
## 2. Command Palette and Search
- **Trigger:** `Ctrl/Cmd + K`. Palette opens in place, keeps focus, and announces results via ARIA live region.
- **Capabilities:** jump to routes, saved views, tenants, recent entities (findings, SBOMs, advisories), and command actions (for example, "Start verification", "Open explain drawer").
- **Result tokens:** palette entries carry metadata (`type`, `tenant`, `filters`). Selecting an item updates the URL and applies stored filters without a full reload.
- **Offline fallback:** in sealed/offline mode, palette restricts actions to cached routes and saved views; remote-only items show a grayed-out badge.
---
## 3. Global Filters and Context Chips
| Control | Shortcut | Persistence | Notes |
|---------|----------|-------------|-------|
| **Tenant picker** | `Ctrl/Cmd + T` | SessionStorage + URL `tenant` query | Issues fresh Authority token, invalidates caches, emits `ui.tenant.switch` log. |
| **Filter tray** | `Shift + F` | IndexedDB (per tenant) + URL query (`since`, `severity`, `tags`, `source`, `status`, `policyView`) | Applies instantly to compatible routes; incompatible filters show a reset suggestion. |
| **Component search** | `/` when filters closed | URL `component` query | Context-aware; scopes results to current tenant and module. |
| **Time window** | `Ctrl/Cmd + Shift + 1-4` | URL `since`/`until`, palette preset | Mapped to preset windows: 24 h, 7 d, 30 d, custom. |
Context chips appear beneath page titles summarising active filters (for example, `Tenant: west-prod`, `Severity: Critical+High`, `Time: Last 7 days`). Removing a chip updates the tray and URL atomically.
---
## 4. Keyboard Shortcut Matrix
| Scope | Shortcut (Mac / Windows) | Action | Notes |
|-------|--------------------------|--------|-------|
| Global | `Cmd+K / Ctrl+K` | Open command palette | Accessible from any route except modal dialogs. |
| Global | `Cmd+T / Ctrl+T` | Open tenant switcher | Requires `ui.read`. Confirm selection with `Enter`; `Esc` cancels without switching. |
| Global | `Shift+F` | Toggle global filter tray | Focus lands on first filter control. |
| Global | `Cmd+1-9 / Ctrl+1-9` | Load saved view preset | Each preset bound per tenant; non-assigned keys show tooltip. |
| Global | `?` | Show keyboard reference overlay | Overlay lists context-specific shortcuts; closes with `Esc`. |
| Findings module | `Cmd+/ / Ctrl+/` | Focus explain search | Works when explain drawer is open. |
| SBOM module | `Cmd+G / Ctrl+G` | Toggle graph overlays | Persists per session. |
| Advisories & VEX | `Cmd+Opt+F / Ctrl+Alt+F` | Focus provider filter | Highlights provider chip strip. |
| Runs module | `Cmd+R / Ctrl+R` | Refresh SSE snapshot | Schedules soft refresh (no hard reload). |
| Policies module | `Cmd+S / Ctrl+S` | Save draft (if edit rights) | Mirrors Policy Editor behaviour. |
Shortcut handling follows WCAG 2.2 best practices: all accelerators are remappable via Settings -> Accessibility -> Keyboard shortcuts, and the overlay documents platform differences.
---
## 5. Deep-Link Patterns
### 5.1 URL schema
Console URLs adopt the format:
```
/console/<route>[/:id][/:tab]?tenant=<slug>&since=<iso>&severity=<list>&view=<token>&panel=<drawer>&component=<purl>
```
- **`tenant`** is mandatory and matches Authority slugs (e.g., `acme-prod`).
- **`since` / `until`** use ISO-8601 timestamps (UTC). Preset ranges set only `since`; UI computes `until` on load.
- **`severity`** accepts comma-separated policy buckets (e.g., `critical,high,kev`).
- **`view`** stores module-specific state (e.g., `sbomView=usage`, `findingsPreset=threat-hunting`).
- **`panel`** selects drawers or tabs (`panel=explain`, `panel=timeline`).
### 5.2 Copyable links
- Share links from the action shelf or context chips; both copy canonical URLs with all active filters.
- CLI parity: inline callouts provide `stella` commands derived from the URL parameters to ensure console/CLI equivalence.
- Offline note: links copied in sealed mode include the snapshot ID (`snapshot=<hash>`) so recipients know which offline data set to load.
### 5.3 Examples
- **`since` / `until`** use ISO-8601 timestamps (UTC). Preset ranges set only `since`; UI computes `until` on load.
- **`severity`** accepts comma-separated policy buckets (e.g., `critical,high,kev`).
- **`view`** stores module-specific state (e.g., `sbomView=usage`, `findingsPreset=threat-hunting`).
- **`panel`** selects drawers or tabs (`panel=explain`, `panel=timeline`).
- **`component`** encodes package selection using percent-encoded PURL syntax.
- **`snapshot`** appears when copying links offline to reference Offline Kit build hash.
@@
| Use case | Example URL | Description |
|----------|-------------|-------------|
| Findings triage | `/console/findings?v=table&severity=critical,high&tenant=west-prod&since=2025-10-20T00:00:00Z` | Opens the findings table limited to critical/high for west-prod, last 7 days. |
| SBOM component focus | `/console/sbom/sha256:abcd?tenant=west-prod&component=pkg:npm/react@18.3.0&view=usage` | Deep-links to a specific image digest and highlights an NPM package in Usage view. |
| Advisory explain | `/console/advisories?tenant=west-prod&source=nvd&panel=detail&documentId=CVE-2025-1234` | Opens advisory list filtered to NVD and expands CVE detail drawer. |
| Run monitor | `/console/runs/42?tenant=west-prod&panel=progress` | Focuses run ID 42 with progress drawer active (SSE stream attached). |
---
## 6. Tenant Switching Lifecycle
1. **Initiate:** User triggers `Ctrl/Cmd + T` or clicks the tenant badge. Switcher modal lists authorised tenants and recent selections.
2. **Preview:** Selecting a tenant shows summary (environment, last snapshot, role coverage). The modal flags tenants missing required scopes for the current route.
3. **Confirm:** On confirmation, the UI requests a new DPoP-bound access token from Authority (`aud=console`, `tenant=<id>`).
4. **Invalidate caches:** Stores keyed by tenant purge automatically; modules emit `tenantChanged` events so in-flight SSE streams reconnect with new headers.
5. **Restore state:** Global filters reapply where valid. Incompatible filters (for example, a saved view unavailable in the new tenant) prompt users to pick a fallback.
6. **Audit and telemetry:** `ui.tenant.switch` log writes subject, from/to tenant, correlation ID. Metric `ui_tenant_switch_total` increments for observability dashboards.
7. **Offline behaviour:** If the target tenant is absent from the offline snapshot, switcher displays guidance to import updated Offline Kit data before proceeding.
---
## 7. Breadcrumbs, Tabs, and Focus Management
- Breadcrumb titles update synchronously with route data loads. When fragments change (for example, selecting a finding), the breadcrumb text updates without pushing a new history entry to keep back/forward predictable.
- Detail views rely on accessible tabs (`role="tablist"`) with keyboard support (`ArrowLeft/Right`). Tab selection updates the URL `tab` parameter for deep linking.
- Focus management:
- Route changes send focus to the primary heading (`h1`) using the live region announcer.
- Opening drawers or modals traps focus until closed; ESC returns focus to the triggering element.
- Keyboard-only navigation is validated via automated Playwright accessibility checks as part of `DEVOPS-CONSOLE-23-001`.
---
## 8. References
- `/docs/ui/console-overview.md` - structural overview, tenant model, global filters.
- `/docs/ui/sbom-explorer.md` - SBOM-specific navigation and graphs (pending).
- `/docs/ui/advisories-and-vex.md` - aggregation UX details (pending).
- `/docs/ui/findings.md` - findings filters and explain drawer (pending).
- `/docs/security/console-security.md` - Authority, scopes, CSP.
- `/docs/cli-vs-ui-parity.md` - CLI equivalence matrix.
- `/docs/accessibility.md` - keyboard remapping, WCAG validation checklists.
---
## 9. Compliance Checklist
- [ ] Route table matches Console build (paths, scopes, owners verified with Console Guild).
- [ ] Keyboard shortcut matrix reflects implemented accelerators and accessibility overlay.
- [ ] Deep-link examples tested for copy/share parity and CLI alignment.
- [ ] Tenant switching flow documents cache invalidation and audit logging.
- [ ] Filter tray, command palette, and presets cross-referenced with accessibility guidance.
- [ ] Offline/air-gap notes included for palette, tenant switcher, and deep-link metadata.
- [ ] Links to dependent docs (`/docs/ui/*`, `/docs/security/*`) validated.
---
*Last updated: 2025-10-26 (Sprint 23).*

View File

@@ -158,9 +158,9 @@ UI disables controls not allowed by current scope and surfaces tooltip with requ
## 12. Screenshot coordination
- Placeholders:
- `![Policy list placeholder](../assets/ui/policies/list-placeholder.png)`
- `![Policy approval placeholder](../assets/ui/policies/approval-placeholder.png)`
- `![Simulation diff placeholder](../assets/ui/policies/simulation-placeholder.png)`
- `docs/assets/ui/policies/list-placeholder.png` (capture pending)
- `docs/assets/ui/policies/approval-placeholder.png` (capture pending)
- `docs/assets/ui/policies/simulation-placeholder.png` (capture pending)
- Coordinate with Console Guild via `#console-screenshots` (entry 2025-10-26) to replace placeholders once UI captures are ready (light and dark themes).
---

View File

@@ -46,7 +46,7 @@ The Policy Editor is the primary Console workspace for composing, simulating, an
- *Explain Explorer* (optional drawer for findings)
- **Right rail:** context cards for VEX providers, policy metadata, quick links to CLI/API docs.
> Placeholder screenshot: `![Policy editor workspace](../assets/policy-editor/workspace.png)` (add after UI team captures latest build).
> Placeholder screenshot: `docs/assets/policy-editor/workspace.png` (pending upload after UI team captures latest build).
---

View File

@@ -134,8 +134,8 @@ Sections:
## 11. Screenshot coordination
- Placeholders:
- `![Runs dashboard placeholder](../assets/ui/runs/dashboard-placeholder.png)`
- `![Run detail placeholder](../assets/ui/runs/detail-placeholder.png)`
- `docs/assets/ui/runs/dashboard-placeholder.png` (capture pending)
- `docs/assets/ui/runs/detail-placeholder.png` (capture pending)
- Coordinate with Scheduler Guild for updated screenshots after Sprint 23 UI stabilises (tracked in `#console-screenshots`, entry 2025-10-26).
---

View File

@@ -161,8 +161,8 @@ Saved views store combinations of these filters and expose command palette short
## 10. Screenshot coordination
- Placeholder images:
- `![SBOM catalog view placeholder](../assets/ui/sbom/catalog-placeholder.png)`
- `![Overlay graph placeholder](../assets/ui/sbom/overlay-placeholder.png)`
- `docs/assets/ui/sbom/catalog-placeholder.png` (capture pending)
- `docs/assets/ui/sbom/overlay-placeholder.png` (capture pending)
- Coordinate with Console Guild to capture updated screenshots (dark and light theme) once Sprint 23 UI stabilises. Track follow-up in Console Guild thread `#console-screenshots` dated 2025-10-26.
---