Stella Ops Web UI information architecture
Status: Current source-aligned reference (2026-07-13)
This document describes the operator-visible navigation, role paths, and action boundaries of the Stella Ops Web console. Source code remains authoritative when this document and the implementation differ.
Authorities
- Sidebar grouping and labels:
NAVIGATION_GROUPS - Navigation forcing tests:
navigation.config.spec.ts - Router families and compatibility redirects:
app.routes.ts - Route inventory forcing test:
ux-route-inventory.spec.ts - Shared navigation/route access and persona profiles:
route-access.ts - Web scope mirror:
scopes.ts - Canonical issued-scope catalog:
StellaOpsScopes.cs - Role and ABAC intent: Stella Ops user roles
Navigation model
The rail presents five mission pillars in this order. A router family is not automatically a rail destination: app.routes.ts owns resolvability, while NAVIGATION_GROUPS owns what the operator sees. Contextual and compatibility routes may therefore remain reachable without creating another first-level menu item.
Home
└─ Dashboard
Vulnerabilities
├─ Exposure
├─ Images
└─ Intelligence
Deployment
├─ Releases
├─ Promotions
└─ Environments
Proof
├─ Chain
├─ Estate
└─ Compliance
Operate
├─ Operations
├─ Connections
├─ Access
└─ Settings
Every pillar stays within the four-destination first-level limit enforced by navigation.config.spec.ts. Removing a duplicate door does not remove its owner route or valid deep links.
Pillars, destinations, and owner surfaces
Home
| First-level destination | Route | Purpose | Access |
|---|---|---|---|
| Dashboard | / | Persona- and scope-filtered daily health, readiness, and onboarding overview. | Authenticated shell; cards remain scope-filtered. |
Dashboard is the overview, not an owner for release, security, proof, or administration mutations. Its cards hand off to the owning destination with the current subject and scope context.
The dashboard offers one view per base profile and a neutral Overview: Operations (Release Operations Steward), Security (Security Risk Manager), Compliance (Executive Assurance Viewer) and My work (Service Release Contributor). A view selects presentation only; switching it never changes the session’s scopes or route access. A profile’s view is offered only when the session’s issued scopes satisfy that profile’s rule in PROFILE_HOME_VIEW_ACCESS (route-access.ts):
| View | Base profile | Required issued scopes |
|---|---|---|
| Compliance | Executive Assurance Viewer | release:read and policy:audit |
| Operations | Release Operations Steward | release:read and orch:operate |
| Security | Security Risk Manager | findings:read and vuln:investigate |
| My work | Service Release Contributor | release:read, release:write, findings:read and vuln:view |
Exactly one base profile bundle satisfies each rule, and admin or ui.admin never substitutes for a missing scope. The default view is the single offered profile view. A session offered no profile view (for example release:read alone) or several (for example an administrator or a combined custom role) opens on Overview. A remembered view choice is stored per account and tenant and applies only while the current session still offers that view; a choice from another account or tenant never applies. Until the session identifies its account and tenant, the selector offers only the default view. A card that loads its own data is shown, in any view, only to a session holding the read scope its owner endpoint requires; admin does not stand in for that scope.
Each profile view leads with that profile’s queue, built from the owner reads the dashboard already makes (role-queue.model.ts). The queue summarizes owner queues and assigns nothing. Each group names its owner read, its scope (tenant-wide, header scope, or the releases the session owns) and its observation time. A group shows at most five rows; its count opens the owner destination that lists the same set where one exists. Four sets have no such destination: promotions blocked by reachable risk (the Approvals Pending tab lists every pending approval), releases you own with a newer component version, running digests whose proofs are not verified (the Estate chain filter has no “not verified” choice), and running digests with an outstanding deviation (the Estate Watch filter also lists landing mismatches). Those groups offer no group link; each row opens its own record and the group says that the rest are not linked:
| View | Primary task | Queue groups, in order |
|---|---|---|
| Operations | Review pending approvals (/releases/approvals) | Pending approvals, tenant-wide (Approvals, Pending tab); cells whose latest deployment failed, header scope (/evidence/estate?state=failed); agents reporting drift, tenant-wide (/evidence/estate?focus=drift). |
| Security | Open triage queue (/triage/artifacts) | Promotions blocked by a gate that names a reachable vulnerability, tenant-wide, each opening its approval; critical findings, header scope (/security/findings?severity=critical). |
| Compliance | Review broken chains (/evidence/estate?chain=broken) | Running digests with an outstanding deviation: the Watch stage names the latest Release Orchestrator re-evaluation of the running release, which regressed against the decision that authorized it, and the row shows its reason; a running release not re-evaluated yet, without an authorizing decision that passed or failed, with an unknown re-evaluation outcome or whose re-evaluation could not be read is named in the group and never counted as clean, and a chain read that reports no re-evaluation leaves the group unavailable. A deviating digest is also a chain gap, so it is counted in the next group too. Then running digests with a missing or unverifiable custody stage; running digests without a gap whose recorded stages are not verified or could not be read; each row names the environment and the stages and opens /evidence/custody?subject=<digest>. Then active exceptions, a tenant-wide Policy count that no running digest is bound to (the exception list opens only for exception:read). |
| My work | Open your services (/developer/services) | Releases the session owns with a newer component version, each opening its Updates tab. |
A group the session cannot read names the scope it needs and makes no read; a failed read renders unavailable with Retry, never zero; a group with nothing in it says so; a queue with nothing in any group names its next step. A per-release currency read that fails counts as not checked, never as “no update”: My work then names how many owned releases could not be checked and is not shown as an empty queue, and it is unavailable when every check failed. Overview keeps a cross-area list of open items, each stating its scope. Tenant setup (registry connection, environments, signing key) appears on Home only for an administrator session (admin or ui.admin); the empty-install bootstrap guide still offers each role the setup steps its own grants complete.
Vulnerabilities
| First-level destination | Route | Owner and contextual surfaces | Navigation visibility |
|---|---|---|---|
| Exposure | /security/exposure | Action-led lenses for reachable risk, CVEs, images, releases, environments, and open work. Vulnerability and finding details remain contextual routes. | Any of findings:read, vuln:view, advisory:read. |
| Images | /security/image-inventory | Cross-registry scan coverage and verdict posture. An image opens the existing Image Security dossier at /security/images. | Exact registry:read; scan and configuration scopes do not substitute for inventory read. |
| Intelligence | /security/intelligence | Read-oriented feed freshness, distro, VEX/trust, and mirror coverage. Source configuration remains under Operate > Connections or Operations. | Any of advisory:read, vex:read. |
Exposure is the canonical risk-work entry. Older Risk Overview, Vulnerability Database, Findings Explorer, and Triage Queue doors are represented as Exposure lenses or contextual routes rather than parallel rail entries.
Advisory & VEX Sources preserves a read-only Mirror view for advisory:read. Mirror domain creation, configuration, credential regeneration, and deletion require the backend-aligned integration:write or integration:operate claim at both route and action boundaries. VEX statement creation is not exposed: VexHub has no authenticated statement-create endpoint, so /ops/policy/vex/create redirects to search until that server contract exists.
Deployment
| First-level destination | Route | Owner and contextual surfaces | Navigation visibility |
|---|---|---|---|
| Releases | /releases | Release library. Children: My services (/developer/services), Components (/releases/components), and release-content Bundles (/releases/bundles). | Any of release:read, release:write, release:publish; child gates are narrower. |
| Promotions | /releases/promotions | Gate, approve, and ship flow. Children: Approvals (/releases/approvals), Deployments (/releases/deployments), and Gate policies (/ops/policy/packs). | Any of release:read, release:write, release:publish, orch:read, orch:operate, policy:read. |
| Environments | /environments/overview | Deployed/runtime terrain and gate status. Topology & hosts (/ops/platform-setup) owns environment, target, host, and agent setup. | Any of orch:read, orch:operate. |
The same destinations reorder for the active persona; scope gates do not change. Operations and Security lead with Promotions, while Developer, Compliance, and Overview lead with the release library. Environments remains the third door.
Proof
| First-level destination | Route | Owner and contextual surfaces | Navigation visibility |
|---|---|---|---|
| Chain | Parent shelf | Chain of Custody (/evidence/custody), Verify (/evidence/verify), Proof Chains (/evidence/proofs), and Audit Trail (/ops/operations/audit). Audit tabs use tab=all-events, timeline, correlations, exports, or bundles; the exports and bundles tabs are visible and mounted only with export.viewer, so the shell never eagerly issues Export Center reads for a timeline-only session. | Per-child evidence, audit, release, signing, VEX, or verify gates; there is no all-scopes group gate. |
| Estate | /evidence/estate | Deployed version by environment crossed with evidence posture. Cells hand off to Chain of Custody with a subject query value. | Any of release:read, release:write, release:publish, orch:read. |
| Compliance | /compliance | Compliance cockpit with distinct routes /compliance/nis2, /compliance/dora, and /compliance/cra; also cross-lists the Transparency ledger (/setup/trust-signing/transparency, ui.admin). Legacy /assurance/* redirects here (c10 R1). | Any of policy:read, policy:audit, notify.viewer, findings:read. |
Proof distinguishes three questions: trace one record through Chain, inspect deployed proof coverage in Estate, and review regulator-facing coverage in Compliance. Audit Trail is the evidence audit surface even though its owner route remains under /ops/operations; it is not the same as Operate > Access > Admin activity or Settings > Trust Center > Audit.
Verify is an active deterministic read operation: its route requires replay:read. It reruns a recorded gate decision from sealed evidence and reports whether the result reproduces. Explicit durable replay token, bundle, or snapshot production remains gated by replay:write.
Chain of Custody and the Transparency entry drawer (/evidence/transparency) keep the Evidence owner’s verification result and reasons. Proven requires ok:true. A required missing or unendorsed witness is Unverifiable for ok:false; an evaluated signature/root/bundle mismatch remains Tampered. Witness absence alone cannot explain a walkable leaf mismatch, while missing path orientation still means Unverifiable. Policy refusal alone and unknown codes do not receive a blanket exception. A transport failure shows verification unavailable and retains the prior state. Receipt, unchecked-stage and request context stay attached to the same record. Source verified against b824a1b3b1ba5496e72b2e1a1bb515b9826efe87; recheck from src/Web/StellaOps.Web with npx vitest run --config vitest.codex.config.ts src/app/core/api/attestor-verification-verdict.spec.ts src/app/features/evidence-custody/evidence-custody.component.spec.ts src/app/features/evidence-transparency/evidence-transparency.component.spec.ts. Source checks do not complete the separately gated Console deployment or CCP-010/011 live scenarios.
Operate
Operate is the quiet back-of-house pillar. It groups owner workspaces into four questions and pushes administration gates to the relevant child so non-admin operators retain their lanes.
| First-level destination | Owner children and routes | Access summary |
|---|---|---|
| Operations | Schedules (/ops/operations/jobengine), Feeds & Vuln Data (/ops/operations/feeds-airgap), Scripts (/ops/scripts), Health (/ops/operations/doctor), Asset Inventory (/inventory). | Per-child orch:*, advisory/VEX read, ops.health, ui.admin, or graph:read. |
| Connections | Integrations (/setup/integrations) with Registries, Advisory & VEX, and Secrets children. | ui.admin. |
| Access | Tenants (/console-admin/tenants), Users (/console-admin/users), Roles (/console-admin/roles), Clients (/console-admin/clients), Tokens (/console-admin/tokens), Admin activity (/console-admin/audit), and Branding (/console-admin/branding) — the console-admin shell’s tabs, each a direct Access door (the “Tenants & Access” wrapper that duplicated its first child’s route was dissolved, c12 R1); Identity Providers (/setup/identity-providers). The shell page h1 is “Tenants & Access”. | ui.admin for the tenant/user/role/client/token/activity/branding doors; platform.idp.admin for Identity Providers. |
| Settings | Trust Center (/setup/trust-signing) and Telemetry Federation (/ops/operations/federation). | ui.admin for Trust Center; the matching telemetry participation or federation read/write scopes for federation pages. |
Security Data, Tenant & Branding, System Settings, and Platform Status are not duplicate first-level doors. Their valid functionality is owned by Feeds & Vuln Data, Tenants & Access, User Preferences/Appearance, or Health respectively; compatibility routes remain a router concern.
Role-oriented paths
Stella Ops authorizes with token scopes and backend ABAC, not a role name alone. The first four persona profiles below mirror PERSONA_ROUTE_MATRICES; they determine expected visibility, not an unconditional permission grant. Platform Access Administrator is a capability path governed by admin scopes rather than a fifth dashboard persona.
| User | Primary path | Expected actions | Mutation boundary |
|---|---|---|---|
| Executive Assurance Viewer | Home > Dashboard; Proof > Compliance, Estate, Chain/Audit/Verify; Deployment > Releases. | Review deployment, assurance, policy, finding, evidence, export, and audit posture; deterministically verify a recorded gate decision. | The profile is read-oriented and carries replay:read, but no replay production, vulnerability operation, release, policy, exception, or administration mutation scope. |
| Release Operations Steward | Home > Dashboard; Deployment > Promotions, Environments, Releases; Operate > Operations. | Compose/update releases, operate deployments, scan when needed, and inspect proof. | Profile includes release:write, orch:operate, and scanner:scan. Approve/reject still requires release:publish, which is not part of the base persona profile. |
| Security Risk Manager | Home > Dashboard; Vulnerabilities > Exposure, Images, Intelligence; Deployment > Promotions; Proof > Chain. | Investigate risk, browse tenant registry images, request scans, inspect VEX/advisories, simulate policy, and follow evidence. | Profile includes registry:read, vuln:investigate, scanner:scan, policy:simulate, raw-evidence vex:read, and the distinct VexHub statement-read claim vexhub:read; it does not include VexHub administration, registry administration, release:publish, exceptions:approve, or bypass scopes. |
| Service Release Contributor | Home > Dashboard; Deployment > Releases > My services; scoped Exposure and proof handoffs. | Select an owned service/digest, inspect scan/policy/findings, update an allowed environment or request promotion. | Requires release:write plus serviceIds, repositoryIds, imageNamespaces, environmentIds, maxEnvironmentType, and directUpdateAllowed. Backend checks repeat the service/environment/digest constraints. |
| Platform Access Administrator | Operate > Access, Connections, and Settings. | Manage tenants, users, roles, clients, tokens, branding, integrations, trust, and identity providers. | ui.admin opens Console Administration/integration/trust owners; Identity Providers specifically requires platform.idp.admin. Backend commands may require finer scopes and fresh authorization. |
Service contribution never implies broad operator, publisher, approver, bypass, or admin power. If directUpdateAllowed is false or the target is outside the user ABAC envelope, the UI must create an approval-required request or show why the action is unavailable.
Read visibility versus mutation authority
| Surface or action | Read/route visibility | Additional mutation authority |
|---|---|---|
| Approvals | /releases/approvals is visible with release:read. | Approve/reject requires release:publish, a valid decision state, and the decision reason/signing rules enforced by the surface and backend. Gate bypass is separate: release:gate-bypass. |
| Deployments | Deployment activity is readable with the release/orchestrator read envelope. | Operating a deployment requires orch:operate or the explicitly supported release:write path, plus backend policy/ABAC. |
| Scan now | Image/release context may be readable without scan authority. | Triggering a scan requires scanner:scan. |
| Images inventory | /security/image-inventory and its registry/image reads require registry:read. | Scan now still requires scanner:scan; Auto-scan configuration still requires integration:write. |
| Verify | Proof records may be readable through evidence scopes. | /evidence/verify requires replay:read; durable replay production requires replay:write. |
| Contributor update | My services requires the contributor scope profile. | release:write and all service/environment/digest ABAC checks; direct mutation additionally requires directUpdateAllowed=true. |
| Console Administration | Operate > Access is shown only for its child gates. | Console Administration requires ui.admin; Identity Provider mutation requires platform.idp.admin. |
Admin and ui.admin are guard wildcards in the Web route-access helper, but issued claims still come from the Authority catalog and backend endpoints remain the final authorization boundary.
Context, deep links, and Back behavior
Canonical owner pages must accept contextual handoffs without becoming duplicate menu doors. The shared context-route-state.ts defines the common contract:
returnTois an application-local absolute path. Values not starting with/, protocol-relative values beginning//, and values containing control characters are rejected.- Scope context uses
tenant/tenantId,region/regions,environment/environments,timeWindow, andstagequery keys. - View state may use
tab,panel,drawer,scope, orview. - Cross-pillar evidence handoffs use the documented subject passport:
/evidence/custody?subject=<URL-encoded canonical subject>. New producers usesubject; typeddigest/purl/releasekeys are compatibility inputs only. Owner details retain their path ids, and a source addsreturnToonly when it needs an exact Back destination. - Back follows a valid
returnTo; otherwise it returns to the target’s canonical owner list. Query merging must retain unrelated scope keys.
Current examples:
- Exposure -> vulnerability detail -> Chain of Custody carries the CVE in
subjectand preserves the originating Exposure lens inreturnTo. - Estate cells open
/evidence/custody?subject=...while retaining the active scope query. - Release and approval details build explicit
returnTovalues before handing off to findings, proof, or release-flow surfaces. - Images (
/security/image-inventory) -> Image Security (/security/images) -> Scan Image (/security/scan) carriesdigest, the registry’s full digest-pinnedreference, theregistryintegration id and the descriptivetag; the dossier adds the active scope keys and its own URL inreturnTo. The digest selects the bytes: a handed-over tag-only reference is pinned toname@digest, a reference that names another digest is refused and not passed on, and a digest without a known reference states that and links back to Images. Opening either page submits nothing, and neither grants scan authority: submission still needsscanner:scanorscanner:writein the session, and Scanner enforces its own policy. - Finding detail (
/security/findings/:findingId) keeps the finding id, a Scanner scan ID, a release id and a release run (deployment) id apart. The Policy Gate Trace tab links to Verify (/evidence/verify) with the active scope keys andreturnTo; when the Findings record names a release it addsrelease=<id>, so Verify lists that release’s replayable gate decisions for the reader to choose (auto-approve, seal and legacy decisions without a bound policy pack cannot be replayed and are not listed). Verify requires the exactreplay:readscope; a session without it gets that statement instead of the link. The Findings record names no gate decision, and today no release either, so the tab states that no release or gate decision is linked and builds no run URL. The witness handoff (/security/reachability/witnesses) carriesfindingId, the vulnerability assearch, the scope keys andreturnTo, and adds only thesourceScanIdrecorded by the selected Findings disposition. The Evidence tab shows that scan and the recorded image digest. A scan relation alone proves neither witness presence nor absence. With an absent relation the workspace states that no scan was handed over; it lists no earlier scans of an image and chooses none. A changed finding or scope clears the previous relation while loading and discards its late disposition, projection, CVE and score responses. - Witnesses -> witness detail -> proof of exposure carries the exact scan and witness: a witness row opens
/security/reachability/witnesses/<witnessId>with the scan list URL asreturnTo; the proof permalink is/security/reachability/poe/<witnessId>?scanId=<scanId>(the scan Scanner recorded for that witness; a recorded run id is not a scan); a proof id that is not a witness of the loaded scan is reported, and no other proof opens in its place. A witness read for a scan the page has left is discarded; the witness page shows no response for a witness it has left and no record whose id differs from the requested witness. Scan IDs are trimmed nonblank opaque values, including Scanner’s 40-hex IDs; the Console rejects control characters and uses normal query-parameter encoding. It imposes no UUID or hex-only grammar. The persisted witness id, payload content id, scan id and run id remain separate. The canonical nested payload supplies the component PURL, vulnerability, ordered path and recorded provenance; repeated symbols retain their path positions. Malformed nodes never create a shortened proof path. Unrecorded reachability, confidence and verification remain unknown, including after a later selection or failed verification; an envelope alone is not a verification result. - Chain of Custody -> Verify (Replay decision) carries the recorded decision tuple (
packId,version,subject), the release id inrelease, and the current custody URL inreturnTo; Verify’s Back returns to that exact trace. The custody Verify attestations action checks only stages with an attestor receipt and, after a run, labels every stage checked, failed, unavailable or not checked. Each verified stage also states whether Evidence recorded the run: the receipt id, time, requester and the checks not run, or “Not recorded” with the reason. The page does not list earlier runs. - Audit sections use one owner route with a
tabquery, while Assurance framework lenses use distinct canonical routes rather than a framework query parameter. - Legacy route helpers preserve relevant query and fragment context when redirecting to a current owner route; new links should target the current route directly.
Canonical terminology
| Term | Meaning and placement |
|---|---|
| Dashboard | The Home overview. It summarizes and hands off; it does not own domain mutations. |
| Exposure | The Vulnerabilities work entry for reachable risk, lenses, and open work. Do not recreate separate Risk Overview or Triage Queue rail doors. |
| Approvals | Signed promotion decisions under Deployment > Promotions, not a top-level pillar. |
| Chain of Custody | The subject-level evidence trace under Proof > Chain. |
| Estate | Deployed version by environment crossed with evidence posture under Proof. |
| Verify | Deterministic gate replay from sealed evidence under Proof > Chain; a scoped verification action, not a generic evidence status label. |
| Compliance / Assurance | Compliance is the Proof destination; /assurance is its cockpit and framework route family. |
| Audit Trail | Evidence/audit records under Proof > Chain. Keep it distinct from Admin activity and Trust Center Audit. |
| Bundles | Under Deployment, release-content bundles; under Audit Trail, sealed evidence/audit bundles. Always qualify the context. |
Related documentation
- Web UI architecture
- Accessibility
- Component library
- Stella Ops user roles
- Historical v2 rewire package
