Files
git.stella-ops.org/docs/api/console/workspaces.md
master 536f6249a6
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Add SBOM, symbols, traces, and VEX files for CVE-2022-21661 SQLi case
- Created CycloneDX and SPDX SBOM files for both reachable and unreachable images.
- Added symbols.json detailing function entry and sink points in the WordPress code.
- Included runtime traces for function calls in both reachable and unreachable scenarios.
- Developed OpenVEX files indicating vulnerability status and justification for both cases.
- Updated README for evaluator harness to guide integration with scanner output.
2025-11-08 20:53:45 +02:00

312 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Console Workspaces API
_Tracking: CONSOLE-VULN-29-001, CONSOLE-VEX-30-001, DOCS-AIAI-31-004_
## 1. Goals & Scope
The console workspaces provide read-only aggregates for Advisory AI operators:
- `/console/vuln/*` surfaces tenant-scoped findings annotated with policy verdicts, VEX justifications, Scheduler reachability signals, and Advisory AI rationale.
- `/console/vex/*` streams the underlying VEX statements, conflicts, and justification summaries (with SSE support for live updates).
All endpoints MUST:
1. Remain deterministic offline (stable sort keys, ISO-8601 UTC timestamps, hashed assets).
2. Operate with Authority-issued DPoP or mTLS client credentials that include `console:read` and either `vuln:read` or `vex:read`.
3. Respect tenant isolation every request carries `X-StellaOps-Tenant`.
## 2. Shared Request/Response Conventions
| Requirement | Description |
| --- | --- |
| Headers | `Authorization: DPoP <token>`, `DPoP: <proof>`, `X-StellaOps-Tenant: <tenantId>`, `Accept: application/json` (or `text/event-stream` for SSE). |
| Pagination | Cursor-based via `pageToken`; defaults to 50 items, max 200. Cursors are opaque, base64url, signed. |
| Sorting | Findings sorted by `(severity desc, exploitScore desc, findingId asc)`. Statements sorted by `(lastUpdated desc, statementId asc)`. |
| Dates | RFC 3339 / ISO-8601 UTC (e.g., `2025-11-08T12:02:11Z`). |
| Determinism | All arrays must be pre-sorted; no server-generated uuids in responses. |
## 3. Vulnerability Workspace (`/console/vuln/*`)
### 3.1 `GET /console/vuln/findings`
Query parameters:
| Parameter | Type | Notes |
| --- | --- | --- |
| `pageToken` | string | Optional cursor from previous response. |
| `pageSize` | int | 1-200, default 50. |
| `severity` | string[] | Accepts `critical`, `high`, `medium`, `low`, `info`. |
| `product` | string[] | SBOM `purl` or image digest anchors. |
| `policyBadge` | string[] | `pass`, `warn`, `fail`, `waived`. |
| `vexState` | string[] | `not_affected`, `fixed`, `under_investigation`, etc. |
| `reachability` | string[] | `reachable`, `unreachable`, `unknown`. |
| `search` | string | Substring match on CVE/GHSA/KEV ID (case-insensitive). |
Response body:
```jsonc
{
"items": [
{
"findingId": "tenant-default:advisory-ai:sha256:5d1a",
"coordinates": {
"advisoryId": "CVE-2024-12345",
"package": "pkg:npm/jsonwebtoken@9.0.2",
"component": "jwt-auth-service",
"image": "registry.local/ops/auth:2025.10.0"
},
"summary": "jsonwebtoken <10.0.0 allows algorithm downgrade.",
"severity": "high",
"cvss": 8.1,
"kev": true,
"policyBadge": "fail",
"vex": {
"statementId": "vex:tenant-default:jwt-auth:5d1a",
"state": "under_investigation",
"justification": "Advisory AI flagged reachable path via Scheduler run 42."
},
"reachability": {
"status": "reachable",
"lastObserved": "2025-11-07T23:11:04Z",
"signalsVersion": "signals-2025.310.1"
},
"evidence": {
"sbomDigest": "sha256:6c81…",
"policyRunId": "policy-run::2025-11-07::ca9f",
"attestationId": "dsse://authority/attest/84a2"
},
"timestamps": {
"firstSeen": "2025-10-31T04:22:18Z",
"lastSeen": "2025-11-07T23:16:51Z"
}
}
],
"facets": {
"severity": [
{ "value": "critical", "count": 2 },
{ "value": "high", "count": 7 }
],
"policyBadge": [
{ "value": "fail", "count": 6 },
{ "value": "warn", "count": 3 },
{ "value": "waived", "count": 1 }
],
"reachability": [
{ "value": "reachable", "count": 5 },
{ "value": "unreachable", "count": 2 },
{ "value": "unknown", "count": 1 }
]
},
"nextPageToken": "eyJjdXJzb3IiOiJmZjg0NiJ9"
}
```
### 3.2 `GET /console/vuln/facets`
Returns the full facet catalog (counts by severity, product, policy badge, VEX state, reachability, KEV flag). Designed for sidebar filters without paging; identical parameter surface as `/findings`.
### 3.3 `GET /console/vuln/{findingId}`
Returns the full finding document, including evidence timeline, policy overlays, and export-ready metadata:
```jsonc
{
"findingId": "tenant-default:advisory-ai:sha256:5d1a",
"details": {
"description": "jsonwebtoken <10.0.0 allows algorithm downgrade.",
"references": [
"https://nvd.nist.gov/vuln/detail/CVE-2024-12345",
"https://github.com/auth0/node-jsonwebtoken/security/advisories/GHSA-45mw-4jw3-g2wg"
],
"exploitAvailability": "known_exploit"
},
"policyBadges": [
{
"policyId": "policy://tenant-default/runtime-hardening",
"verdict": "fail",
"explainUrl": "https://console.local/policy/runs/policy-run::2025-11-07::ca9f"
}
],
"vex": {
"statementId": "vex:tenant-default:jwt-auth:5d1a",
"state": "under_investigation",
"justification": "Runtime telemetry confirmed exploitation path.",
"impactStatement": "Token exchange service remains exposed until patch 2025.11.2.",
"remediations": [
{
"type": "patch",
"description": "Upgrade jwt-auth-service to 2025.11.2.",
"deadline": "2025-11-12T00:00:00Z"
}
]
},
"reachability": {
"status": "reachable",
"callPathSamples": [
"api-gateway -> jwt-auth-service -> jsonwebtoken.verify"
],
"lastUpdated": "2025-11-07T23:11:04Z"
},
"evidence": {
"sbom": {
"digest": "sha256:6c81…",
"componentPath": [
"/src/jwt-auth/package.json",
"/src/jwt-auth/node_modules/jsonwebtoken"
]
},
"attestations": [
{
"type": "scan-report",
"attestationId": "dsse://authority/attest/84a2",
"signer": "attestor@stella-ops.org",
"bundleDigest": "sha256:e2bb…"
}
]
},
"timestamps": {
"firstSeen": "2025-10-31T04:22:18Z",
"lastSeen": "2025-11-07T23:16:51Z",
"vexLastUpdated": "2025-11-07T23:10:09Z"
}
}
```
### 3.4 `POST /console/vuln/tickets`
```jsonc
POST /console/vuln/tickets
{
"tenant": "tenant-default",
"selection": [
"tenant-default:advisory-ai:sha256:5d1a",
"tenant-default:advisory-ai:sha256:9bf4"
],
"targetSystem": "servicenow",
"metadata": {
"assignmentGroup": "runtime-security",
"priority": "P1"
}
}
```
Response:
```jsonc
{
"ticketId": "console-ticket::tenant-default::2025-11-08::00018",
"payload": {
"version": "2025-11-01",
"tenant": "tenant-default",
"findings": [
{ "findingId": "tenant-default:advisory-ai:sha256:5d1a", "severity": "high" },
{ "findingId": "tenant-default:advisory-ai:sha256:9bf4", "severity": "critical" }
],
"policyBadge": "fail",
"vexSummary": "2 reachable findings pending patch.",
"attachments": [
{
"type": "json",
"name": "console-ticket-20251108.json",
"digest": "sha256:1fdd…",
"contentType": "application/json",
"expiresAt": "2025-11-15T00:00:00Z"
}
]
},
"auditEventId": "console.ticket.export::2025-11-08::00018"
}
```
Requests emit `console.ticket.export` audit events (tenant, user, selection counts, target system).
## 4. VEX Workspace (`/console/vex/*`)
### 4.1 `GET /console/vex/statements`
Parameters mirror `/console/vuln/findings` plus:
| Parameter | Type | Notes |
| --- | --- | --- |
| `advisoryId` | string[] | CVE/GHSA/OVAL identifiers. |
| `justification` | string[] | `exploit_observed`, `component_not_present`, etc. |
| `statementType` | string[] | `vex`, `openvex`, `custom`, `advisory_ai`. |
| `prefer` | string | `prefer=stream` enables chunked streaming (NDJSON). |
Response (paged JSON):
```jsonc
{
"items": [
{
"statementId": "vex:tenant-default:jwt-auth:5d1a",
"advisoryId": "CVE-2024-12345",
"product": "registry.local/ops/auth:2025.10.0",
"status": "under_investigation",
"justification": "exploit_observed",
"lastUpdated": "2025-11-07T23:10:09Z",
"source": {
"type": "advisory_ai",
"modelBuild": "aiai-console-2025-10-28",
"confidence": 0.74
},
"links": [
{
"rel": "finding",
"href": "/console/vuln/findings/tenant-default:advisory-ai:sha256:5d1a"
}
]
}
],
"nextPageToken": null
}
```
When `Accept: text/event-stream`, the endpoint emits events (see §4.3) instead of paged JSON.
### 4.2 `GET /console/vex/statements/{statementId}`
Returns the canonical statement plus provenance extracts. SSE clients can call this endpoint when they need full bodies after receiving a summary event.
### 4.3 `GET /console/vex/events` (SSE)
Streams live updates for VEX statements affecting the tenant:
- Event types: `statement.created`, `statement.updated`, `statement.deleted`, `statement.conflict`.
- Fields: `id`, `advisoryId`, `product`, `vexState`, `severityHint`, `policyBadge`, `conflictSummary`, `sequence`.
- Replay: Clients include `Last-Event-ID`; server resumes from sequence.
- Heartbeats every 15 seconds (`event: keepalive`, `data: {}`).
Example event payload:
```jsonc
event: statement.updated
data: {
"statementId": "vex:tenant-default:jwt-auth:5d1a",
"advisoryId": "CVE-2024-12345",
"product": "registry.local/ops/auth:2025.10.0",
"state": "fixed",
"justification": "solution_available",
"sequence": 4182,
"updatedAt": "2025-11-08T11:44:32Z"
}
```
## 5. Signals & Scheduler Integration
- Reachability data is materialized by Scheduler delta jobs (`SCHED-CONSOLE-23-001`). `/console/vuln/findings` should cache the most recent job ID and expose `signalsVersion`.
- VEX justification fields reference Excititor statement IDs; ensure the gateway checks Excititor availability and degrades gracefully (returns `state: unavailable` plus telemetry).
- Scheduler must publish `console.vuln.refresh` events whenever advisory/VEX deltas warrant workspace refresh; console SSE endpoint may piggyback on the same Redis/NATS channel.
## 6. Determinism & Offline Notes
1. All responses are compressible JSON; no CDN fonts/assets referenced.
2. SSE endpoints must tolerate sealed mode by operating on loopback addresses only.
3. `authority-sealed-ci.json` (see DEVOPS-AIRGAP-57-002) is the evidence Authority consumes before enabling these APIs for sealed tenants; console responses echo `sealed: true/false` flags for UI badges.
## 7. Sample Payloads for Docs
- `docs/api/console/samples/vuln-findings-sample.json` exported via `scripts/generate-console-samples.ts` (placeholder script to be added when backend lands).
- `docs/api/console/samples/vex-statement-sse.ndjson` contains 5 chronological SSE events for screenshot reproduction.
> Until backend implementations ship, use the examples above to unblock DOCS-AIAI-31-004; replace them with live captures once the gateway endpoints are available in staging.