182 lines
6.2 KiB
Markdown
182 lines
6.2 KiB
Markdown
# Console Workspaces API
|
|
|
|
## 1. Goals and scope
|
|
|
|
Console workspaces provide tenant-scoped, read-only aggregates for operators and automation:
|
|
|
|
- `/console/vuln/*` surfaces findings annotated with policy verdicts, VEX context, reachability signals, and evidence pointers.
|
|
- `/console/vex/*` streams underlying VEX statements and summaries (optionally via SSE).
|
|
|
|
All endpoints MUST:
|
|
1. Remain deterministic (stable sort keys, ISO-8601 UTC timestamps, stable identifiers).
|
|
2. Enforce tenant isolation for every request.
|
|
3. Be offline-friendly by supporting export flows and fixture-based operation in air-gapped environments.
|
|
|
|
## 2. Shared request/response conventions
|
|
|
|
| Requirement | Description |
|
|
| --- | --- |
|
|
| Auth headers | `Authorization: Bearer <token>` and optional proof headers (e.g., `DPoP: <proof>`) depending on deployment profile. |
|
|
| Tenant header | Required. See `docs/api/gateway/tenant-auth.md`; prefer `X-Stella-Tenant` (legacy alias: `X-StellaOps-Tenant`). |
|
|
| Pagination | Cursor-based via `pageToken`; defaults to 50 items, max 200. Cursors are opaque, base64url, and 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-01-02T03:04:05Z`). |
|
|
| Determinism | Arrays are pre-sorted; no server-generated random 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[] | `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 (example):
|
|
|
|
```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": "Operator triage pending."
|
|
},
|
|
"reachability": {
|
|
"status": "reachable",
|
|
"lastObserved": "2025-01-02T03:04:05Z",
|
|
"signalsVersion": "signals-<version>"
|
|
},
|
|
"evidence": {
|
|
"sbomDigest": "sha256:6c81deadbeef...",
|
|
"policyRunId": "policy-run::<id>",
|
|
"attestationId": "dsse://authority/attest/<id>"
|
|
},
|
|
"timestamps": {
|
|
"firstSeen": "2025-01-01T00:00:00Z",
|
|
"lastSeen": "2025-01-02T03:05:06Z"
|
|
}
|
|
}
|
|
],
|
|
"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 a full finding document, including evidence timeline, policy overlays, and export-ready metadata.
|
|
|
|
### 3.4 `POST /console/vuln/tickets`
|
|
|
|
Create ticket/export payloads in a deterministic, auditable way.
|
|
|
|
```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"
|
|
}
|
|
}
|
|
```
|
|
|
|
## 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-01-02T03:04:05Z",
|
|
"source": {
|
|
"type": "advisory_ai",
|
|
"modelBuild": "aiai-console-<build>",
|
|
"confidence": 0.74
|
|
},
|
|
"links": [
|
|
{ "rel": "finding", "href": "/console/vuln/findings/tenant-default:advisory-ai:sha256:5d1a" }
|
|
]
|
|
}
|
|
],
|
|
"nextPageToken": null
|
|
}
|
|
```
|
|
|
|
### 4.2 SSE streaming
|
|
|
|
Some deployments expose live updates as SSE (`text/event-stream`). When enabled, stream payloads SHOULD be valid NDJSON and remain deterministic for a given event id.
|
|
|
|
## 5. Samples and fixtures
|
|
|
|
Deterministic samples live under `docs/api/console/samples/` and are used by documentation and offline validation:
|
|
- `docs/api/console/samples/vuln-findings-sample.json`
|
|
- `docs/api/console/samples/vex-statement-sse.ndjson`
|
|
- `docs/api/console/samples/console-export-manifest.json`
|
|
- `docs/api/console/samples/exception-schema-sample.json`
|
|
|
|
When contracts change, update the fixtures in lockstep and keep diffs deterministic (stable key ordering, stable timestamps, stable ids).
|