Files
git.stella-ops.org/docs/api/console/workspaces.md
2025-12-24 12:38:14 +02:00

6.2 KiB

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):

{
  "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.

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):

{
  "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).