86 KiB
I’m sharing this because I think the comparison will help sharpen some of the UI/UX & data-model decisions for StellaOps — especially around how “evidence + suppression + audit/export” flows are implemented in existing tools and which patterns we might want to emulate or avoid.
Here’s a compact snapshot (with recent documentation/screens and dates) of how a few major players — Snyk, GitHub (via repo scanning), Aqua Security / container scanning, Anchore/Grype, and Prisma Cloud — handle evidence, ignores (suppression / VEX), and audit/export primitives.
✅ What works: Evidence & audit flows that provide clarity
Snyk — good “evidence + data flow + context” for code vulnerabilities
- In Snyk Code, each issue links to a full “Data flow” trace from source to sink. (Snyk User Docs)
- The UI hyperlinks to the Git repo, providing code-level context and version control traceability. (Snyk User Docs)
- “Fix analysis” surfaces recommended fixes, diff examples, and community-driven suggestions. (Snyk User Docs)
This deep evidence linkage is a valuable pattern for StellaOps triage and remediation.
Anchore/Grype — VEX-aware suppression + SBOM export readiness
- Anchore Enterprise documents vulnerability annotations + VEX support (SBOM scanning, annotations, fix statuses). (Anchore Documentation)
- Grype respects VEX statuses (
not_affected,fixed) and can expose suppressed matches via--show-suppressed. (GitHub) - Justifications can be scoped (e.g.,
vulnerable_code_not_presentfilters) and the API surfaces (Oct 2025) enable automation of SBOM + VEX + diffed results. (Anchore Documentation)
This forms a solid SBOM → vulnerability → VEX → audit/export pipeline.
⚠️ Where things are brittle
Snyk — suppression semantics vary across scan types
- Ignore rules are project/integration-specific; UI ignores may not carry over to CLI import flows. (Snyk)
- Snyk Code uses separate suppression UX (IDE/CLI) from OSS scans, leading to fragmentation. (Snyk User Docs)
Anchore/Grype — operational caveats
- Feb 2025 issue: VEX suppression failed for directory scans because the source type wasn’t supported. (GitHub)
- Some suppressions require explicit config (
GRYPE_VEX_ADD). (GitHub) - Ensuring SBOM + VEX + diffed outputs for audits often needs extra orchestration.
Prisma Cloud — audit/export primitives are coarse
- “Suppress Code Issues” feature exists, but no public doc shows an end-to-end SBOM + VEX + audit export flow. (Prisma Cloud Documentation)
- Repo scanning + suppression features exist, but forensic traceability appears limited to “report + suppress”. (Prisma Cloud Documentation)
🔑 What StellaOps should copy / avoid
Copy
- Snyk Code evidence + fix linking provides actionable traceability.
- Anchore/Grype SBOM → VEX suppression → facade for automation is the workflow to engineer.
- Surface suppression metadata (reason, status, justification) for auditing suppressed items.
Avoid
- Fragmented ignore rules per scan surface (OSS vs Code vs Container). Instead, keep suppression consistent.
- Hidden suppression; tie it to the main UI instead of a “show suppressed” toggle.
- Incomplete VEX support for certain source types; test across containers, directories, binaries, SBOMs.
If helpful, I can build a spreadsheet (Snyk, GitHub, Aqua, Anchore/Grype, Prisma Cloud) comparing evidence, suppression, APIs, exports, and gaps with doc links.
Matrix built. I’ll keep it compact enough to scan quickly, but detailed enough that you can lift it straight into a Google Sheet / Confluence page.
1. Evidence & context: what a single finding looks like
| Dimension | Snyk | GitHub Advanced Security | Aqua / Trivy | Anchore / Grype (Anchore Enterprise) | Prisma Cloud |
|---|---|---|---|---|---|
| Code-level evidence | Snyk Code shows a Data flow view (taint graph) from source → sink with step-by-step code lines in the UI and IDE. (docs.snyk.io) | Code scanning alerts show file/line and, for data-flow rules, a “how data moves through the code” view with Show paths for the full flow. (GitHub Docs) | Trivy is not a SAST engine; evidence is per-file / resource for vulnerabilities & misconfigurations (IaC, K8s, etc.), not data-flow graphs. (Trivy) | No SAST; evidence is package / image / SBOM level (CVE, package, version, location). Grype is focused on images/filesystems, not code flows. (Chainguard Academy) | AppSec module shows issues mapped to file & line and offers inline remediation/fix flows; surfaced in console and IDE plugins (JetBrains/VS Code). (Palo Alto Networks) |
| Dependency / container evidence | For OSS & containers, Snyk shows dependency paths and has a project issue paths API that returns the introduction chain for a vuln. (docs.snyk.io) | Dependabot alerts show vulnerable package, version, advisories, and affected functions to help decide if code actually uses them. (GitHub Docs) | Trivy shows image → layer → package → vuln with installed/fixed versions; same for repos & filesystems in JSON/SARIF. (GitHub) | Grype output lists artifact, package, version, location, severity; when paired with Syft SBOM, you get full component graph for images and other artifacts. (Chainguard Academy) | Prisma’s Vulnerability Explorer & scan reports show image/host, package, severity and compliance IDs for image and host scans. (docs.prismacloud.io) |
| SBOM / supply-chain context | snyk sbom generates CycloneDX and SPDX SBOMs for local projects; Snyk also supports SBOM export in enterprise tiers. (docs.snyk.io) |
GitHub builds a dependency graph from manifests and ingests SARIF from external scanners; it is SBOM-adjacent but not an SBOM UI. (GitHub Docs) | Trivy can output SBOMs (CycloneDX, SPDX, SPDX-JSON) and Kubernetes “KBOM” views, and is often used as the SBOM generator. (Chainguard Academy) | Anchore Enterprise is explicitly “SBOM-powered”; SBOM management views let you navigate applications and export SBOM-centric vulnerability views. (docs.anchore.com) | Prisma Cloud is inventory-/RQL-centric; SBOMs are not a first-class UI artifact and there is no public doc for full SBOM navigation comparable to Anchore or Trivy. (Palo Alto Networks) |
| Where the evidence appears | Web UI, CLI, IDEs (VS Code, JetBrains) and PR checks. Ignores for Snyk Code are now “consistent” across UI/CLI/IDE (2025-11 EA). (docs.snyk.io) | Web UI (Security tab), PR Conversation tab for code scanning reviews, REST & GraphQL APIs, and SARIF imports from many scanners. (GitHub Docs) | Trivy: CLI / JSON / SARIF / CI integrations (GitHub Actions, etc.). Aqua Platform adds a CNAPP UI with risk-based vulnerability views. (GitHub) | Grype: CLI & JSON/SARIF outputs; Anchore Enterprise: browser UI (dashboards, SBOM views, reporting) plus REST/GraphQL APIs. (Chainguard Academy) | Prisma Cloud: web console (AppSec dashboards, Vulnerability Explorer), REST APIs, IDE plugins for JetBrains & VS Code. (docs.prismacloud.io) |
2. Suppression / ignore / VEX behavior
| Dimension | Snyk | GitHub Advanced Security | Aqua / Trivy | Anchore / Grype (Anchore Enterprise) | Prisma Cloud |
|---|---|---|---|---|---|
| Suppression primitives | .snyk policy file for OSS & container & IaC; snyk ignore CLI; “Ignore” in web UI; Snyk Code uses UI/CLI/IDE ignores but not .snyk. (docs.snyk.io) |
Code scanning and Dependabot alerts can be dismissed with reasons; Dependabot has auto-triage rules (auto-dismiss/snooze). (GitHub Docs) | Trivy: .trivyignore / .trivyignore.yaml lists vuln IDs; --ignore-policy for Rego-based filtering; severity filters. (aquasecurity.github.io) |
Grype: VEX-aware filtering via --vex and ignore rules; Anchore Enterprise: UI-driven vulnerability annotations that act as a structured “suppress or re-classify” layer. (GitHub) |
AppSec: “Suppress Code Issues” (per-issue or globally) and more general suppression rules (disable policy / by source / by resource / by tag). (docs.prismacloud.io) |
| Metadata captured with suppression | snyk ignore supports --reason and --expiry; UI shows who ignored and allows editing/unignore; APIs expose ignoreReasons on issues. (docs.snyk.io) |
Dismissal reason: false positive, won't fix, used in tests; optional comment. Dismissal requests for code scanning add requester/reviewer, timestamps, status. (GitHub Docs) |
Ignores live in repo-local files (.trivyignore*) or Rego policies; VEX documents contribute status metadata (per CVE, per product). No central UI metadata by default. (aquasecurity.github.io) |
Annotations carry VEX-aligned status plus explanatory text; RBAC role vuln-annotator-editor controls who can create/modify/delete them. (docs.anchore.com) |
Suppressions include justification text; there is a dedicated API to retrieve suppression justifications by policy ID and query (auditable). (pan.dev) |
| Scope & consistency | Ignores are local to project/integration/org; ignoring in a Git repo project does not automatically ignore the same issue imported via CLI. Snyk Code ignore semantics differ from OSS/Container (no .snyk). (Snyk) |
Dismissals attach to a specific alert (repo, branch baseline); PRs inherit baseline. Dependabot has repo-level config (dependabot.yml) and org-level alert configuration. (GitHub Docs) |
Suppression is run-local: .trivyignore travels with source, policies live in config repos; VEX docs are attached per artifact or discovered via VEX Hub / registries. Reproducible but not centralized unless you build it. (aquasecurity.github.io) |
Grype suppression is per scan & VEX document; Anchore Enterprise stores annotations centrally per artifact and exposes them consistently in UI/API and exported VEX. (GitHub) | Suppression rules can be global, per source, per resource, or tag-scoped; they affect console views and API results consistently when filters are applied. (pan.dev) |
| VEX support (ingest + semantics) | Snyk generates SBOMs but has no documented first-class VEX ingestion or export; VEX is referenced mostly at the SBOM/standards level, not as a product feature. (Snyk) | No native VEX semantics in alerts; GitHub consumes SARIF only. VEX can exist in repos or external systems but is not interpreted by GHAS. (GitHub Docs) | Trivy has explicit VEX support: supports OpenVEX, CycloneDX VEX, and CSAF VEX, using local files, VEX repositories, SBOM externalReferences, and OCI VEX attestations to filter results. (Trivy) | Grype has VEX-first behavior: --vex to ingest OpenVEX; by default not_affected/fixed go to an ignore set; --show-suppressed exposes them. Anchore Enterprise 5.22+ adds OpenVEX export and CycloneDX VEX export (5.23). (GitHub) |
No public documentation of native VEX ingestion or export; prioritization is via policies/RQL rather than VEX semantics. |
| Default handling of suppressed items | Ignored issues are hidden by default in UI/CLI/IDE views to reduce noise; some tools like snyk-to-html will still show ignored Snyk Code issues. (docs.snyk.io) |
Dismissed / auto-dismissed alerts are not shown by default (is:open filter); you must explicitly filter for closed / auto-dismissed alerts. (GitHub Docs) |
When VEX is supplied, non-affected/fixed statuses are filtered out; suppressed entries are generally not shown unless you adjust filters/output. Some edge-cases exist around .trivyignore.yaml behavior. (Trivy) |
Grype hides suppressed matches unless --show-suppressed is set; community discussions explicitly argue for “suppressed hidden by default” across all formats. (artifacthub.io) |
Suppressed / excluded issues are hidden from normal risk views and searches and only visible via explicit filters or suppression APIs. (pan.dev) |
| Known pain points | Fragmented semantics: Snyk Code vs OSS/Container vs IaC handle ignores differently; ignores are not global across ingest types. (docs.snyk.io) | Dismissal is per-tool: Dependabot rules don’t govern CodeQL and vice-versa; no VEX; you must build cross-tool policy on top. | Some rough edges reported around .trivyignore.yaml and SARIF vs exit-code behavior; VEX support is powerful but still labeled experimental in docs. (GitHub) |
VEX support for certain source types (e.g., some directory + SBOM combos) has had bugs; suppressed entries disappear by default unless you remember --show-suppressed. (GitHub) |
No VEX, and suppression semantics may diverge across CSPM/AppSec/Compute; complexity of RQL and multiple modules can make suppression strategy opaque without good governance. (Palo Alto Networks) |
3. Audit & export primitives
| Dimension | Snyk | GitHub Advanced Security | Aqua / Trivy | Anchore / Grype (Anchore Enterprise) | Prisma Cloud |
|---|---|---|---|---|---|
| Built-in UI exports | Reporting UI lets you export reports as PDF and table data as CSV; you can also download CSV from several report views. (docs.snyk.io) | UI is mostly “view only”; some security overview exports are available, but reports are usually built via API or marketplace actions (e.g., PDF report GitHub Action). (GitHub Docs) | Aqua Platform provides CSV exports and API integrations for vulnerability reports; on-prem deployments can export “user policy data, vulnerability data and system settings data.” (Aqua) | SBOM/Vulnerability views have an Export CSV button; the Reports service aggregates via GraphQL into CSV/JSON from pre-built templates and dashboards. (docs.anchore.com) | Vulnerability Explorer and scan reports allow CSV export; code-build issues can be exported with filters as CSV from the AppSec UI. (docs.prismacloud.io) |
| Machine-readable exports / APIs | REST Issues API; Export API (GA) to create CSV exports via async jobs; SBOM CLI (snyk sbom) for CycloneDX/SPDX; audit log export for user actions. (docs.snyk.io) |
SARIF input/output; REST & GraphQL APIs for code scanning & Dependabot; many third-party actions to transform alerts into PDFs/CSVs or send to other systems. (GitHub Docs) | Trivy outputs JSON, SARIF, CycloneDX, SPDX, SPDX-JSON, GitHub formats; these can be uploaded into GHAS or other platforms. Aqua exposes vulnerability data via API. (Trivy) | Grype outputs JSON, table, CycloneDX, SARIF, plus Go-template based CSV; Anchore Enterprise exposes APIs for vulnerabilities, policies, and reports. (Chainguard Academy) | CSPM/AppSec APIs: vulnerabilities/search (JSON) and .../search/download (GZIP CSV) for RQL queries; broader Prisma Cloud API for automation/integration. (pan.dev) |
| VEX / “authoritative statement” export | No native VEX export; at best you can export SBOMs and issues and post-process into VEX with external tooling. (Snyk) | None. Vendors can publish VEX separately, but GHAS doesn’t emit VEX. | Trivy consumes VEX but does not itself author VEX; Aqua operates VEX Hub as a central repository of vendor VEX documents rather than as a generator. (Trivy) | Anchore Enterprise 5.22/5.23 is currently the most “productized” VEX exporter: OpenVEX and CycloneDX VEX including annotations, PURLs, metadata about the scanned image. (docs.anchore.com) | No VEX export; risk posture is expressed via internal policies, not standardized exploitability statements. |
| Suppression / ignore audit | Ignored issues can be exported by filtering for “Ignored” in Reporting and downloading CSV; APIs expose ignore reasons; audit log export records user actions such as ignoring issues. (docs.snyk.io) | Code scanning dismissal requests are full audit records (who requested, who approved, reason, timestamps). Dependabot dismissal comments & auto-dismissed alerts are queryable via GraphQL/REST and UI filters. (GitHub Docs) | Auditability is repo-driven: .trivyignore/VEX/rego live in version control; Aqua’s own reporting/APIs can include current vulnerability state but do not (publicly) expose a dedicated VEX change log. (aquasecurity.github.io) |
Annotations are first-class objects, controlled via RBAC and exportable as OpenVEX/CycloneDX VEX; this effectively is an audit log of “why we suppressed or downgraded this CVE” over time. (docs.anchore.com) | Suppression justification APIs provide a structured record of why and where policies are suppressed; combined with CSV/API exports of vulns, this gives a workable audit trail for regulators. (pan.dev) |
4. What this suggests for StellaOps UX & data-model
Patterns worth copying
-
Data-flow & path-level “evidence” as the default detail view
-
Snyk Code’s taint-flow UI and GitHub’s “Show paths” for CodeQL alerts make a single issue explain itself without leaving the tool. (docs.snyk.io)
-
For StellaOps:
- For code: provide a path graph (source → sanitizers → sinks) with line-level jumps.
- For SBOM/containers: mirror Snyk’s Project Issue Paths & Grype/Syft by showing a dependency path or image-layer path for each CVE.
-
-
VEX-first suppression semantics
- Trivy and Grype treat VEX as the canonical suppression mechanism; statuses like
not_affected/fixedhide findings by default, with CLI flags to show suppressed. (Trivy) - Anchore Enterprise adds a full annotation workflow and emits OpenVEX/CycloneDX VEX as the authoritative vendor statement. (docs.anchore.com)
- For StellaOps: make VEX status the single source of truth for suppression across all modules, and always be able to reconstruct a proof tree: SBOM → vuln → VEX statement → policy decision.
- Trivy and Grype treat VEX as the canonical suppression mechanism; statuses like
-
Rich suppression metadata with explicit justification & expiry
- Snyk captures reason + expiry; GitHub uses structured reasons + free-form comment; Prisma provides a dedicated suppression-justification API. (docs.snyk.io)
- For StellaOps: require a reason taxonomy + free-text + optional “proof link” (e.g., internal ticket, upstream vendor VEX) for any “Not Affected” or “Won’t Fix,” and store that as part of the public proof spine.
-
Strong export & API stories for regulators
-
Snyk’s Export API, Anchore’s Reports service, and Prisma’s RQL+CSV APIs give customers reliable machine-readable exports for audits and custom BI. (updates.snyk.io)
-
Anchore’s CycloneDX VEX export is the best current model for “signable, portable, regulator-friendly” proofs. (Security Boulevard)
-
For StellaOps:
- Treat CSV/JSON/SBOM/VEX exports as first-class features, not add-ons.
- Tie them to deterministic scan manifests and graph revision IDs (your “trust algebra” backbone) so an auditor can replay any historical report.
-
-
Repo-local suppression files as “policy as code”
.snyk,.trivyignore, Rego policies, and VEX docs living alongside source are proven patterns for reproducible suppression. (docs.snyk.io)- For StellaOps: mirror this with a small set of declarative files (
stellaops.vexmap.yaml,trust-lattice.yaml) that your engine and UI both honor.
Patterns to deliberately avoid
-
Fragmented ignore semantics by scan type
- Snyk’s different behavior across Code vs OSS vs Container vs IaC (e.g.,
.snyknot honored for Snyk Code) is a recurring source of confusion. (docs.snyk.io) - For StellaOps: a single suppression model (VEX+policy) must apply consistently whether the evidence came from SAST, SBOM, container scan, or runtime telemetry.
- Snyk’s different behavior across Code vs OSS vs Container vs IaC (e.g.,
-
Making suppressed issues effectively invisible
-
Grype and GitHub both hide suppressed/dismissed issues by default and require extra flags/filters to see them. (artifacthub.io)
-
For StellaOps:
- Default UI for any artifact should show a small, always-visible “suppressed” counter with a click-through view.
- Every export format should have an option to include suppressed entries with their VEX status and reasoning.
-
-
Lack of a standard “authoritative statement” artifact
- Snyk, GitHub, Prisma Cloud all rely on internal notions of suppression and policy without emitting a standardized VEX or equivalent artifact. (Snyk)
- For StellaOps: your “Proof-of-Integrity Graph” and VEX exports should be the primary way vendors and customers communicate risk, not just internal UI states.
-
Over-reliance on informal text for serious decisions
- Many tools lean heavily on free-form comments (GitHub dismissal comments, Snyk ignore reasons) without tying them to structured policies or verifiable upstream evidence. (GitHub Docs)
- For StellaOps: keep free text, but anchor it in structured fields (VEX status, justification category, linked upstream VEX/SBOM, ticket ID) and make these queryable across the entire system.
If you want, next step can be a StellaOps UX spec that maps each of these rows to concrete screens and micro-interactions (e.g., “Finding details drawer,” “Suppression dialog,” “Export / attest dialog”) so your .NET/Angular team has something they can implement directly.
Matrix built. I’ll keep it compact enough to scan quickly, but detailed enough that you can lift it straight into a Google Sheet / Confluence page.
1. Evidence & context: what a single finding looks like
| Dimension | Snyk | GitHub Advanced Security | Aqua / Trivy | Anchore / Grype (Anchore Enterprise) | Prisma Cloud |
|---|---|---|---|---|---|
| Code-level evidence | Snyk Code shows a Data flow view (taint graph) from source → sink with step-by-step code lines in the UI and IDE. (docs.snyk.io) | Code scanning alerts show file/line and, for data-flow rules, a “how data moves through the code” view with Show paths for the full flow. (GitHub Docs) | Trivy is not a SAST engine; evidence is per-file / resource for vulnerabilities & misconfigurations (IaC, K8s, etc.), not data-flow graphs. (Trivy) | No SAST; evidence is package / image / SBOM level (CVE, package, version, location). Grype is focused on images/filesystems, not code flows. (Chainguard Academy) | AppSec module shows issues mapped to file & line and offers inline remediation/fix flows; surfaced in console and IDE plugins (JetBrains/VS Code). (Palo Alto Networks) |
| Dependency / container evidence | For OSS & containers, Snyk shows dependency paths and has a project issue paths API that returns the introduction chain for a vuln. (docs.snyk.io) | Dependabot alerts show vulnerable package, version, advisories, and affected functions to help decide if code actually uses them. (GitHub Docs) | Trivy shows image → layer → package → vuln with installed/fixed versions; same for repos & filesystems in JSON/SARIF. (GitHub) | Grype output lists artifact, package, version, location, severity; when paired with Syft SBOM, you get full component graph for images and other artifacts. (Chainguard Academy) | Prisma’s Vulnerability Explorer & scan reports show image/host, package, severity and compliance IDs for image and host scans. (docs.prismacloud.io) |
| SBOM / supply-chain context | snyk sbom generates CycloneDX and SPDX SBOMs for local projects; Snyk also supports SBOM export in enterprise tiers. (docs.snyk.io) |
GitHub builds a dependency graph from manifests and ingests SARIF from external scanners; it is SBOM-adjacent but not an SBOM UI. (GitHub Docs) | Trivy can output SBOMs (CycloneDX, SPDX, SPDX-JSON) and Kubernetes “KBOM” views, and is often used as the SBOM generator. (Chainguard Academy) | Anchore Enterprise is explicitly “SBOM-powered”; SBOM management views let you navigate applications and export SBOM-centric vulnerability views. (docs.anchore.com) | Prisma Cloud is inventory-/RQL-centric; SBOMs are not a first-class UI artifact and there is no public doc for full SBOM navigation comparable to Anchore or Trivy. (Palo Alto Networks) |
| Where the evidence appears | Web UI, CLI, IDEs (VS Code, JetBrains) and PR checks. Ignores for Snyk Code are now “consistent” across UI/CLI/IDE (2025-11 EA). (docs.snyk.io) | Web UI (Security tab), PR Conversation tab for code scanning reviews, REST & GraphQL APIs, and SARIF imports from many scanners. (GitHub Docs) | Trivy: CLI / JSON / SARIF / CI integrations (GitHub Actions, etc.). Aqua Platform adds a CNAPP UI with risk-based vulnerability views. (GitHub) | Grype: CLI & JSON/SARIF outputs; Anchore Enterprise: browser UI (dashboards, SBOM views, reporting) plus REST/GraphQL APIs. (Chainguard Academy) | Prisma Cloud: web console (AppSec dashboards, Vulnerability Explorer), REST APIs, IDE plugins for JetBrains & VS Code. (docs.prismacloud.io) |
2. Suppression / ignore / VEX behavior
| Dimension | Snyk | GitHub Advanced Security | Aqua / Trivy | Anchore / Grype (Anchore Enterprise) | Prisma Cloud |
|---|---|---|---|---|---|
| Suppression primitives | .snyk policy file for OSS & container & IaC; snyk ignore CLI; “Ignore” in web UI; Snyk Code uses UI/CLI/IDE ignores but not .snyk. (docs.snyk.io) |
Code scanning and Dependabot alerts can be dismissed with reasons; Dependabot has auto-triage rules (auto-dismiss/snooze). (GitHub Docs) | Trivy: .trivyignore / .trivyignore.yaml lists vuln IDs; --ignore-policy for Rego-based filtering; severity filters. (aquasecurity.github.io) |
Grype: VEX-aware filtering via --vex and ignore rules; Anchore Enterprise: UI-driven vulnerability annotations that act as a structured “suppress or re-classify” layer. (GitHub) |
AppSec: “Suppress Code Issues” (per-issue or globally) and more general suppression rules (disable policy / by source / by resource / by tag). (docs.prismacloud.io) |
| Metadata captured with suppression | snyk ignore supports --reason and --expiry; UI shows who ignored and allows editing/unignore; APIs expose ignoreReasons on issues. (docs.snyk.io) |
Dismissal reason: false positive, won't fix, used in tests; optional comment. Dismissal requests for code scanning add requester/reviewer, timestamps, status. (GitHub Docs) |
Ignores live in repo-local files (.trivyignore*) or Rego policies; VEX documents contribute status metadata (per CVE, per product). No central UI metadata by default. (aquasecurity.github.io) |
Annotations carry VEX-aligned status plus explanatory text; RBAC role vuln-annotator-editor controls who can create/modify/delete them. (docs.anchore.com) |
Suppressions include justification text; there is a dedicated API to retrieve suppression justifications by policy ID and query (auditable). (pan.dev) |
| Scope & consistency | Ignores are local to project/integration/org; ignoring in a Git repo project does not automatically ignore the same issue imported via CLI. Snyk Code ignore semantics differ from OSS/Container (no .snyk). (Snyk) |
Dismissals attach to a specific alert (repo, branch baseline); PRs inherit baseline. Dependabot has repo-level config (dependabot.yml) and org-level alert configuration. (GitHub Docs) |
Suppression is run-local: .trivyignore travels with source, policies live in config repos; VEX docs are attached per artifact or discovered via VEX Hub / registries. Reproducible but not centralized unless you build it. (aquasecurity.github.io) |
Grype suppression is per scan & VEX document; Anchore Enterprise stores annotations centrally per artifact and exposes them consistently in UI/API and exported VEX. (GitHub) | Suppression rules can be global, per source, per resource, or tag-scoped; they affect console views and API results consistently when filters are applied. (pan.dev) |
| VEX support (ingest + semantics) | Snyk generates SBOMs but has no documented first-class VEX ingestion or export; VEX is referenced mostly at the SBOM/standards level, not as a product feature. (Snyk) | No native VEX semantics in alerts; GitHub consumes SARIF only. VEX can exist in repos or external systems but is not interpreted by GHAS. (GitHub Docs) | Trivy has explicit VEX support: supports OpenVEX, CycloneDX VEX, and CSAF VEX, using local files, VEX repositories, SBOM externalReferences, and OCI VEX attestations to filter results. (Trivy) | Grype has VEX-first behavior: --vex to ingest OpenVEX; by default not_affected/fixed go to an ignore set; --show-suppressed exposes them. Anchore Enterprise 5.22+ adds OpenVEX export and CycloneDX VEX export (5.23). (GitHub) |
No public documentation of native VEX ingestion or export; prioritization is via policies/RQL rather than VEX semantics. |
| Default handling of suppressed items | Ignored issues are hidden by default in UI/CLI/IDE views to reduce noise; some tools like snyk-to-html will still show ignored Snyk Code issues. (docs.snyk.io) |
Dismissed / auto-dismissed alerts are not shown by default (is:open filter); you must explicitly filter for closed / auto-dismissed alerts. (GitHub Docs) |
When VEX is supplied, non-affected/fixed statuses are filtered out; suppressed entries are generally not shown unless you adjust filters/output. Some edge-cases exist around .trivyignore.yaml behavior. (Trivy) |
Grype hides suppressed matches unless --show-suppressed is set; community discussions explicitly argue for “suppressed hidden by default” across all formats. (artifacthub.io) |
Suppressed / excluded issues are hidden from normal risk views and searches and only visible via explicit filters or suppression APIs. (pan.dev) |
| Known pain points | Fragmented semantics: Snyk Code vs OSS/Container vs IaC handle ignores differently; ignores are not global across ingest types. (docs.snyk.io) | Dismissal is per-tool: Dependabot rules don’t govern CodeQL and vice-versa; no VEX; you must build cross-tool policy on top. | Some rough edges reported around .trivyignore.yaml and SARIF vs exit-code behavior; VEX support is powerful but still labeled experimental in docs. (GitHub) |
VEX support for certain source types (e.g., some directory + SBOM combos) has had bugs; suppressed entries disappear by default unless you remember --show-suppressed. (GitHub) |
No VEX, and suppression semantics may diverge across CSPM/AppSec/Compute; complexity of RQL and multiple modules can make suppression strategy opaque without good governance. (Palo Alto Networks) |
3. Audit & export primitives
| Dimension | Snyk | GitHub Advanced Security | Aqua / Trivy | Anchore / Grype (Anchore Enterprise) | Prisma Cloud |
|---|---|---|---|---|---|
| Built-in UI exports | Reporting UI lets you export reports as PDF and table data as CSV; you can also download CSV from several report views. (docs.snyk.io) | UI is mostly “view only”; some security overview exports are available, but reports are usually built via API or marketplace actions (e.g., PDF report GitHub Action). (GitHub Docs) | Aqua Platform provides CSV exports and API integrations for vulnerability reports; on-prem deployments can export “user policy data, vulnerability data and system settings data.” (Aqua) | SBOM/Vulnerability views have an Export CSV button; the Reports service aggregates via GraphQL into CSV/JSON from pre-built templates and dashboards. (docs.anchore.com) | Vulnerability Explorer and scan reports allow CSV export; code-build issues can be exported with filters as CSV from the AppSec UI. (docs.prismacloud.io) |
| Machine-readable exports / APIs | REST Issues API; Export API (GA) to create CSV exports via async jobs; SBOM CLI (snyk sbom) for CycloneDX/SPDX; audit log export for user actions. (docs.snyk.io) |
SARIF input/output; REST & GraphQL APIs for code scanning & Dependabot; many third-party actions to transform alerts into PDFs/CSVs or send to other systems. (GitHub Docs) | Trivy outputs JSON, SARIF, CycloneDX, SPDX, SPDX-JSON, GitHub formats; these can be uploaded into GHAS or other platforms. Aqua exposes vulnerability data via API. (Trivy) | Grype outputs JSON, table, CycloneDX, SARIF, plus Go-template based CSV; Anchore Enterprise exposes APIs for vulnerabilities, policies, and reports. (Chainguard Academy) | CSPM/AppSec APIs: vulnerabilities/search (JSON) and .../search/download (GZIP CSV) for RQL queries; broader Prisma Cloud API for automation/integration. (pan.dev) |
| VEX / “authoritative statement” export | No native VEX export; at best you can export SBOMs and issues and post-process into VEX with external tooling. (Snyk) | None. Vendors can publish VEX separately, but GHAS doesn’t emit VEX. | Trivy consumes VEX but does not itself author VEX; Aqua operates VEX Hub as a central repository of vendor VEX documents rather than as a generator. (Trivy) | Anchore Enterprise 5.22/5.23 is currently the most “productized” VEX exporter: OpenVEX and CycloneDX VEX including annotations, PURLs, metadata about the scanned image. (docs.anchore.com) | No VEX export; risk posture is expressed via internal policies, not standardized exploitability statements. |
| Suppression / ignore audit | Ignored issues can be exported by filtering for “Ignored” in Reporting and downloading CSV; APIs expose ignore reasons; audit log export records user actions such as ignoring issues. (docs.snyk.io) | Code scanning dismissal requests are full audit records (who requested, who approved, reason, timestamps). Dependabot dismissal comments & auto-dismissed alerts are queryable via GraphQL/REST and UI filters. (GitHub Docs) | Auditability is repo-driven: .trivyignore/VEX/rego live in version control; Aqua’s own reporting/APIs can include current vulnerability state but do not (publicly) expose a dedicated VEX change log. (aquasecurity.github.io) |
Annotations are first-class objects, controlled via RBAC and exportable as OpenVEX/CycloneDX VEX; this effectively is an audit log of “why we suppressed or downgraded this CVE” over time. (docs.anchore.com) | Suppression justification APIs provide a structured record of why and where policies are suppressed; combined with CSV/API exports of vulns, this gives a workable audit trail for regulators. (pan.dev) |
4. What this suggests for StellaOps UX & data-model
Patterns worth copying
-
Data-flow & path-level “evidence” as the default detail view
-
Snyk Code’s taint-flow UI and GitHub’s “Show paths” for CodeQL alerts make a single issue explain itself without leaving the tool. (docs.snyk.io)
-
For StellaOps:
- For code: provide a path graph (source → sanitizers → sinks) with line-level jumps.
- For SBOM/containers: mirror Snyk’s Project Issue Paths & Grype/Syft by showing a dependency path or image-layer path for each CVE.
-
-
VEX-first suppression semantics
- Trivy and Grype treat VEX as the canonical suppression mechanism; statuses like
not_affected/fixedhide findings by default, with CLI flags to show suppressed. (Trivy) - Anchore Enterprise adds a full annotation workflow and emits OpenVEX/CycloneDX VEX as the authoritative vendor statement. (docs.anchore.com)
- For StellaOps: make VEX status the single source of truth for suppression across all modules, and always be able to reconstruct a proof tree: SBOM → vuln → VEX statement → policy decision.
- Trivy and Grype treat VEX as the canonical suppression mechanism; statuses like
-
Rich suppression metadata with explicit justification & expiry
- Snyk captures reason + expiry; GitHub uses structured reasons + free-form comment; Prisma provides a dedicated suppression-justification API. (docs.snyk.io)
- For StellaOps: require a reason taxonomy + free-text + optional “proof link” (e.g., internal ticket, upstream vendor VEX) for any “Not Affected” or “Won’t Fix,” and store that as part of the public proof spine.
-
Strong export & API stories for regulators
-
Snyk’s Export API, Anchore’s Reports service, and Prisma’s RQL+CSV APIs give customers reliable machine-readable exports for audits and custom BI. (updates.snyk.io)
-
Anchore’s CycloneDX VEX export is the best current model for “signable, portable, regulator-friendly” proofs. (Security Boulevard)
-
For StellaOps:
- Treat CSV/JSON/SBOM/VEX exports as first-class features, not add-ons.
- Tie them to deterministic scan manifests and graph revision IDs (your “trust algebra” backbone) so an auditor can replay any historical report.
-
-
Repo-local suppression files as “policy as code”
.snyk,.trivyignore, Rego policies, and VEX docs living alongside source are proven patterns for reproducible suppression. (docs.snyk.io)- For StellaOps: mirror this with a small set of declarative files (
stellaops.vexmap.yaml,trust-lattice.yaml) that your engine and UI both honor.
Patterns to deliberately avoid
-
Fragmented ignore semantics by scan type
- Snyk’s different behavior across Code vs OSS vs Container vs IaC (e.g.,
.snyknot honored for Snyk Code) is a recurring source of confusion. (docs.snyk.io) - For StellaOps: a single suppression model (VEX+policy) must apply consistently whether the evidence came from SAST, SBOM, container scan, or runtime telemetry.
- Snyk’s different behavior across Code vs OSS vs Container vs IaC (e.g.,
-
Making suppressed issues effectively invisible
-
Grype and GitHub both hide suppressed/dismissed issues by default and require extra flags/filters to see them. (artifacthub.io)
-
For StellaOps:
- Default UI for any artifact should show a small, always-visible “suppressed” counter with a click-through view.
- Every export format should have an option to include suppressed entries with their VEX status and reasoning.
-
-
Lack of a standard “authoritative statement” artifact
- Snyk, GitHub, Prisma Cloud all rely on internal notions of suppression and policy without emitting a standardized VEX or equivalent artifact. (Snyk)
- For StellaOps: your “Proof-of-Integrity Graph” and VEX exports should be the primary way vendors and customers communicate risk, not just internal UI states.
-
Over-reliance on informal text for serious decisions
- Many tools lean heavily on free-form comments (GitHub dismissal comments, Snyk ignore reasons) without tying them to structured policies or verifiable upstream evidence. (GitHub Docs)
- For StellaOps: keep free text, but anchor it in structured fields (VEX status, justification category, linked upstream VEX/SBOM, ticket ID) and make these queryable across the entire system.
If you want, next step can be a StellaOps UX spec that maps each of these rows to concrete screens and micro-interactions (e.g., “Finding details drawer,” “Suppression dialog,” “Export / attest dialog”) so your .NET/Angular team has something they can implement directly.
I’ll treat this as a concrete UX blueprint your .NET/Angular team can build against, centered on three pillars:
- Evidence views (how a single finding “explains itself”)
- Suppression/VEX (how risk decisions are captured)
- Audit/export (how you prove those decisions later)
1. Design principles specific to StellaOps
- Graph-first: Every view is anchored to a graph snapshot ID from your trust algebra / proof engine. Users always know “which build / which graph revision” they’re looking at.
- Single suppression model: One suppression semantics layer (VEX + policy) across code, SBOM, containers, and runtime.
- Evidence before opinion: Detail views always show raw evidence (paths, SBOM lines, runtime traces) before risk ratings, policies, or comments.
- Audit-ready by default: Any action that changes risk posture automatically leaves a machine-readable trail that can be exported.
2. Core information architecture
Primary entities in the UX (mirroring your backend):
-
Organization / Workspace
-
Application / Service
-
Artifact
- Build (commit, tag, CI run)
- Container image
- Binary / package
- SBOM document
-
Scan Result
- Scanner type (SAST, SCA, container, SBOM-only, IaC, runtime)
- Graph snapshot ID
-
Finding
- Vulnerability (CVE, GHSA, etc.)
- Misconfiguration / policy violation
- Supply-chain anomaly
-
Evidence
- Code path(s)
- Dependency path(s)
- SBOM node(s)
- Runtime event(s)
-
VEX Statement
- Status (
affected,not_affected,fixed,under_investigation, etc.) - Justification (standardized + free text)
- Status (
-
Suppression Decision
- “Suppressed by VEX”, “De-prioritized by policy”, “Won’t fix”, etc.
-
Export Job / Proof Bundle
-
Audit Event
- Who, what, when, against which graph snapshot
The UI should surface these without drowning the user in jargon: names can be friendlier but map cleanly to this model.
3. UX spec by primary flows
3.1 Landing: Inventory & posture overview
Screen: “Inventory & Risk Overview”
Purpose: Secure default entry point for security engineers and auditors.
Layout:
-
Header bar
- Org selector
- Global search (by application, artifact, CVE, VEX ID, SBOM component)
- “Exports & Proofs” shortcut
- User menu
-
Left nav (primary)
- Inventory
- Findings
- VEX & Policies
- Exports & Proofs
- Settings
-
Main content: 3 panels
-
Applications list
- Columns: Name, Owner, #Artifacts, Open findings, Suppressed findings, Last build, Risk score.
- Row click → Application view.
-
Top risks
- Cards: “Critical vulns”, “Unsigned artifacts”, “Unknown SBOM coverage”, each showing counts and a “View findings” link (pre-filtered).
-
Compliance viewpoint
- Tabs: “Operational”, “Regulatory”, “Attestations”.
- Simple status indicators per framework (e.g., SLSA level, NIST SSDF coverage) if you support that.
-
Micro-interactions:
- Clicking any numeric count (e.g., “12 suppressed”) opens a pre-filtered Findings list.
- Hover tooltip on risk counts shows breakdown by source (SAST vs SBOM vs runtime).
3.2 Application & artifact detail: evidence-centric view
Screen: “Application detail”
Purpose: Navigate from high level risk to specific artifacts and findings.
Layout:
- Tabs: Overview | Artifacts | Findings | SBOM graph | History
Overview tab:
- Top: Application summary (owners, repos, deployment targets).
- Middle: Tiles for “Latest build”, “Prod artifacts”, “SBOM coverage”.
- Bottom: “Recent decisions” timeline (suppression, VEX updates, exports).
Artifacts tab:
-
Table with:
- Artifact type (image, binary, SBOM-only)
- Identifier (tag/digest, CI job ID)
- Environment (dev, staging, prod)
- Graph snapshot ID
- Findings (open / suppressed chips)
- Last scanned
Selecting a row opens Artifact detail.
3.3 Artifact detail & Finding details drawer
Screen: “Artifact detail”
Layout:
-
Header:
- Artifact identity (name, version/tag, digest)
- Environment badges
- Graph snapshot ID with “Copy” control
- Primary actions: “Download SBOM”, “Export proof bundle”
-
Sub-tabs:
- Findings
- Evidence graph
- SBOM tree
- History
Findings sub-tab
-
Filters on left:
- Severity, status (Open / Suppressed / Only suppressed), source (SAST/SBOM/container/runtime), VEX status, CWE/CVE.
-
Table in center:
- Columns: Severity, Type, ID (CVE-XXXX-XXXX), Component/Code location, Status (Open/Suppressed), VEX status, Last updated.
-
Row click opens a Finding details drawer sliding from the right.
Finding details drawer (core evidence UX)
This is the primary place where “evidence explains itself.”
Structure:
-
Header area
- Title: “CVE-2023-XXXX in
openssl” - Badges: severity, status (Open / Suppressed by VEX), VEX status (
not_affected,fixed, etc.) - Scope indicator: where this finding appears (e.g., “1 artifact (this), 3 environments, 2 images”).
- Title: “CVE-2023-XXXX in
-
Tabs within drawer
-
Evidence (default)
-
Section: “Where this comes from”
- Scanner source, scan timestamp, graph snapshot ID.
-
Section: “Code path” (for SAST)
- A vertical list of steps:
source→propagation→sink. - Clicking a step shows code snippet with line highlighting.
- “Open in Git” and “Open in IDE (deeplink)” actions.
- A vertical list of steps:
-
Section: “Dependency path” (for SCA / SBOM)
- Path view:
app -> module -> transitive dependency -> vulnerable package. - Option to switch between “tree view” and “collapsed chain”.
- Path view:
-
Section: “Runtime signals” (if available)
- Call-site frequency, exploit attempts, telemetry tags.
-
-
Impact & reach
- A small graph panel: how many artifacts, environments, and applications share this finding.
- Link: “View all affected artifacts” → filtered Findings view.
-
VEX & decisions
-
Shows current VEX statements attached:
- Table: Status, Justification (standardized), Source (vendor vs internal), Effective scope (artifact / app / org), Last changed by.
-
Shows local suppression decisions beyond VEX (e.g., “De-prioritized due to compensating controls”).
-
Primary action: “Update status / Add VEX decision”.
-
-
History
-
Timeline of events for this finding:
- Detected
- VEX attached/updated
- Suppression added/edited
- Exported in bundles (with links)
-
Each item shows user, timestamp, and delta.
-
-
Micro-interactions:
- The drawer should support deep-linking: URL reflects
artifactId + findingId + snapshotId. - Keyboard:
Esccloses drawer,←/→cycles findings in the table.
4. Suppression & VEX UX
Goal: one consistent model across all scan types, anchored in VEX semantics.
4.1 “Update status / Add VEX decision” dialog
Entry points:
- From Finding details drawer > “VEX & decisions” tab > primary button.
- Bulk selection from Findings table > “Update status”.
Dialog steps (single modal with progressive disclosure):
-
Select decision type
Radio options:
-
“System is affected”
- Sub-options:
under_investigation,affected_no_fix_available,affected_fix_available.
- Sub-options:
-
“System is not affected”
- Sub-options (justification):
vulnerable_code_not_present,vulnerable_code_not_in_execute_path,vulnerable_configuration_not_present,inline_mitigation_applied,other.
- Sub-options (justification):
-
“Fixed”
- Sub-options:
fixed_in_this_version,fixed_in_downstream,fixed_by_vendor.
- Sub-options:
-
“Won’t fix / accepted risk”
- Sub-options:
business_acceptance,low_likelihood,temporary_exception.
- Sub-options:
-
-
Scope definition
Checkboxes + selectors:
-
Scope:
- This artifact only
- All artifacts of this application
- All artifacts in this org with the same component & version
-
For each, display a short estimate: “This will apply to 3 artifacts (click to preview).”
-
-
Metadata
-
Required:
- Justification category (if not chosen above).
- Free-text “Reason / supporting evidence” (min length e.g., 20 characters).
-
Optional:
- Expiry date (for temporary exceptions).
- Link to ticket / document (URL).
- Attach external VEX file ID or reference (if you’ve ingested vendor VEX).
-
-
Output preview
A read-only JSON-like preview of the VEX statement(s) to be generated, with a friendly label: “These statements will be added to the proof graph for snapshot XYZ.” This makes the model transparent to power users.
On submit:
- Show a small toast: “Status updated · VEX statement anchored to snapshot [ID] · Undo” (undo limited to a short window).
- The Finding row and drawer update immediately (status badges, history timeline).
4.2 Bulk suppression & policy overlay
Screen: “VEX & Policies”
Tabs:
-
VEX statements
- Table: VEX ID, CVE/ID, Status, Scope, Created by, Last updated, Source (vendor/internal).
- Filters: status, scope, target (component, application, artifact).
- Bulk actions: Export VEX (OpenVEX / CycloneDX VEX), disable / supersede.
-
Policies
- Declarative rules like: “Treat
vulnerable_code_not_presentfrom vendor X as authoritative” or “Do not auto-suppress based oninline_mitigation_appliedwithout internal confirmation.” - This expresses how raw VEX translates into “suppressed” vs “needs review” in the UI.
- Declarative rules like: “Treat
UX pattern:
-
Each VEX row includes a small indicator:
S(suppresses findings under current policy) orR(requires review). -
Clicking a row opens a side drawer with:
- Statements content (normalized).
- Affected findings count.
- Policy evaluation result (“This statement currently suppresses 47 findings”).
5. Findings list: global “inbox” for risk
Screen: “Findings”
This is the cross-application queue, similar to Snyk’s project list + GitHub’s security tab, but with VEX semantics.
Layout:
-
Filters on the left:
- Application / artifact
- Severity
- Status (Open / Suppressed / Only suppressed / Needs review)
- VEX status
- Source (SAST, SBOM, container, runtime)
-
Table in center:
- Columns: Severity, ID, Application, Artifact, Status, VEX status, “Decision owner” (user or team), Age.
-
Top bar:
- “Assign to…” for workflow
- “Update status / Add VEX decision” for bulk
- “Export current view” (CSV/JSON)
Micro-interactions:
-
“Status” column clearly distinguishes:
- Open (no VEX)
- Open (VEX says
affected) - Suppressed (VEX says
not_affected/fixed) - Suppressed (policy exception: “Won’t fix”)
-
Hover on “Suppressed” shows a tooltip with the justification and who made the decision.
6. Audit & export / Proof bundles
6.1 Exports list
Screen: “Exports & Proofs”
Purpose: centralized, auditable place for generating and revisiting proofs.
Layout:
-
Top actions:
- “New export / proof bundle”
- Filters: type (CSV, JSON, SBOM, VEX, composite bundle), created by, status.
-
Table:
- Name / description
- Type (e.g., “OpenVEX for app ‘payments’”, “Proof bundle for prod rollout 2025-03-01”)
- Scope (org / app / artifact / snapshot range)
- Includes suppressed? (Yes/No)
- Status (Complete / Failed)
- Created by, Created at
- Download button
6.2 “New export / proof bundle” flow
-
What do you need?
Choices:
- SBOM export (CycloneDX/SPDX)
- VEX export (OpenVEX / CycloneDX VEX)
- Findings export (CSV / JSON)
- Proof bundle (zip containing SBOM + VEX + findings + manifest)
-
Scope
-
Radio:
-
A single artifact (picker)
-
All artifacts of an application (picker)
-
Entire org, limited by:
- Time window (from..to)
- Environments (prod only / all)
-
-
Optional: choose graph snapshot(s) (latest vs explicit ID).
-
-
Options
-
Include suppressed findings:
- Yes, include them, with reasons
- No, only unresolved
-
Mask sensitive fields? (e.g., repository URLs)
-
Include audit log excerpt:
- VEX & suppression decisions
- All user actions
-
-
Review & create
-
Show a summary:
- N artifacts, M findings, K VEX statements.
-
Button: “Create export”.
-
Once complete:
-
Row in the table is updated with a download button.
-
Clicking a row opens an Export detail drawer:
- Manifest preview (JSON-like).
- Link to the associated graph snapshot IDs.
- Embedded notice that “Regulators can verify this bundle by validating manifest signature and graph snapshot hash” (if you sign them).
Micro-interaction:
-
For artifacts and applications, the Artifact detail and Application detail pages should have contextual buttons:
- “Export SBOM”
- “Export VEX”
- “Download proof bundle”
These open the same export dialog pre-populated with the relevant scope.
7. History & audit trail UX
Audit must be first-class, not buried.
Pattern: Timeline component
Used in:
- Application > History
- Artifact > History
- Finding > History
- VEX statement > History
- Export > Details
Timeline item shape:
-
Icon (type of action: scan, decision, export)
-
Title (short, human readable)
-
Metadata:
- User
- Timestamp
- Graph snapshot ID
-
Detail:
- Before/after summary (e.g., “VEX status:
affected→not_affected”)
- Before/after summary (e.g., “VEX status:
Filters:
- By actor (user / system)
- By action type (scan, VEX change, suppression, export, policy change)
- By time range
Long-term: this timeline can become your “forensic report” generator.
8. Role-based slices
You can keep a single UX codebase but offer different “home” experiences per role.
-
Security engineer
- Default landing: “Findings” with open & needs-review filters.
- Emphasis on Evidence & VEX decisions.
- Quick actions: create VEX, adjust policies.
-
Developer
-
Default landing: “My assignments” (subset of Findings where they’re the owner).
-
Simplified VEX dialog:
- Emphasis on “Fixed in commit X” and “Provide more evidence” rather than full-blown VEX authoring.
-
Tight links to repo/IDE.
-
-
Auditor / Compliance
- Default landing: “Exports & Proofs”.
- Views oriented around applications and time windows, not individual findings.
- Read-only access to VEX & policies; can request evidence rather than editing it.
Role behavior is enforced by RBAC, but the UX is guided by ship-ready presets.
9. Implementation checklist for your .NET/Angular team
To make this action-ready:
-
Routes / pages
/inventory/applications/:appId/artifacts/:artifactId/findings/vex/exports/settings
-
Core reusable components
- Graph snapshot badge (with copy & deeplink).
- Findings table (configurable columns, selection).
- Finding details drawer (tabs: Evidence / Impact / VEX & decisions / History).
- VEX status badge.
- Timeline component.
- Export job dialog & list.
-
API contracts to align with UX
GET /artifacts/:id/findings?snapshot=...GET /findings/:id?includeEvidence=truePOST /vex/statements(supports scoped statements).GET /vex/statements?filters...POST /exports+GET /exports/:idGET /audit?scopeType=&scopeId=&range=...
-
Deep-linking
-
URLs should embed at least
snapshotIdfor deterministic views:/artifacts/:artifactId/findings/:findingId?snapshot=:snapshotId
-
-
Telemetry for UX refinement
-
Track frequency of:
- Evidence tab switches (Code vs Dependency vs Runtime).
- VEX edits per finding.
- Export jobs by type.
-
Use this to prioritize which evidence views to optimize first.
-
If you want a next step, I can translate this into:
- A low-fidelity screen map (per route, per component), or
- An example JSON schema for VEX statements + proof bundles that matches the UI’s expectations,
so your backend and frontend teams can converge on a single contract.