Files
git.stella-ops.org/docs/modules/excititor/vex_linksets_api.md
StellaOps Bot 150b3730ef
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Mirror Thin Bundle Sign & Verify / mirror-sign (push) Has been cancelled
api-governance / spectral-lint (push) Has been cancelled
up
2025-11-24 07:52:25 +02:00

4.5 KiB

Excititor VEX linkset APIs (observations + linksets)

Draft examples for Sprint 119 (EXCITITOR-LNM-21-203). Aligns with WebService endpoints implemented in src/Excititor/StellaOps.Excititor.WebService/Program.cs.

/v1/vex/observations

List

GET /v1/vex/observations?vulnerabilityId=CVE-2024-0001&productKey=pkg:maven/org.demo/app@1.2.3&providerId=ubuntu-csaf&status=affected&limit=2
Headers:
  Authorization: Bearer <token>
  X-Tenant: default
Response 200 (application/json):
{
  "items": [
    {
      "tenant": "default",
      "observationId": "vex:obs:sha256:...",
      "providerId": "ubuntu-csaf",
      "document": {
        "digest": "sha256:...",
        "uri": "https://example.com/csaf/1.json",
        "signature": null
      },
      "scope": {
        "vulnerabilityId": "CVE-2024-0001",
        "productKey": "pkg:maven/org.demo/app@1.2.3"
      },
      "statements": [
        {
          "vulnerabilityId": "CVE-2024-0001",
          "productKey": "pkg:maven/org.demo/app@1.2.3",
          "status": "affected",
          "justification": {
            "type": "component_not_present",
            "reason": "Not shipped in base profile"
          },
          "signals": { "severity": { "score": 7.5 } },
          "provenance": {
            "providerId": "ubuntu-csaf",
            "sourceId": "USN-9999-1",
            "fieldMasks": ["statements"]
          }
        }
      ],
      "linkset": {
        "aliases": ["USN-9999-1"],
        "purls": ["pkg:maven/org.demo/app"],
        "cpes": [],
        "references": [{"type": "advisory", "url": "https://..."}],
        "disagreements": []
      },
      "createdAt": "2025-11-18T12:34:56Z"
    }
  ],
  "nextCursor": "eyJ2dWxuZXJhYmlsaXR5SWQiOiJDVkUtMjAyNC0wMDAxIiwiY3JlYXRlZEF0IjoiMjAyNS0xMS0xOFQxMjozNDo1NloifQ=="
}

Get by key

GET /v1/vex/observations/CVE-2024-0001/pkg:maven/org.demo/app@1.2.3
Headers: Authorization + X-Tenant
Response 200: same projection shape as list items (single object).

/v1/vex/linksets

GET /v1/vex/linksets?vulnerabilityId=CVE-2024-0001&productKey=pkg:maven/org.demo/app@1.2.3&status=affected&limit=2
Headers: Authorization + X-Tenant
Response 200:
{
  "items": [
    {
      "linksetId": "CVE-2024-0001:pkg:maven/org.demo/app@1.2.3",
      "tenant": "default",
      "vulnerabilityId": "CVE-2024-0001",
      "productKey": "pkg:maven/org.demo/app@1.2.3",
      "providers": ["ubuntu-csaf", "suse-csaf"],
      "statuses": ["affected", "fixed"],
      "aliases": ["USN-9999-1"],
      "purls": ["pkg:maven/org.demo/app"],
      "cpes": [],
      "references": [{"type": "advisory", "url": "https://..."}],
      "disagreements": [{"providerId": "suse-csaf", "status": "fixed", "justification": null, "confidence": null}],
      "observations": [
        {"observationId": "vex:obs:...", "providerId": "ubuntu-csaf", "status": "affected", "severity": 7.5},
        {"observationId": "vex:obs:...", "providerId": "suse-csaf", "status": "fixed", "severity": null}
      ],
      "createdAt": "2025-11-18T12:34:56Z"
    }
  ],
  "nextCursor": null
}

Notes

  • Pagination: limit (default 200, max 500) + cursor (opaque base64 of vulnerabilityId + createdAt).
  • Filters: vulnerabilityId, productKey, providerId, status; multiple query values allowed.
  • Headers: Excititor-Results-Count, Excititor-Results-Cursor (observations) and Excititor-Results-Total / Excititor-Results-Truncated (chunks) already implemented.
  • Determinism: responses sorted by vulnerabilityId, then productKey; arrays sorted lexicographically.

SDK generation

  • Source of truth for EXCITITOR-LNM-21-203 SDK samples (TypeScript/Go/Python) and OpenAPI snippets.
  • Suggested generation inputs:
    • Schema: this doc + docs/modules/excititor/vex_observations.md for field semantics.
    • Auth: bearer token + X-Stella-Tenant header (required).
    • Pagination: cursor (opaque) + limit (default 200, max 500).
  • Minimal client example (TypeScript, fetch):
const resp = await fetch(
  `${baseUrl}/v1/vex/observations?` + new URLSearchParams({
    vulnerabilityId: "CVE-2024-0001",
    productKey: "pkg:maven/org.demo/app@1.2.3",
    limit: "100"
  }),
  {
    headers: {
      Authorization: `Bearer ${token}`,
      "X-Stella-Tenant": "default"
    }
  }
);
const body = await resp.json();
  • Determinism requirements for SDKs:
    • Preserve server ordering; do not resort items client-side.
    • Treat cursor as opaque; echo it back for next page.
    • Keep enums case-sensitive as returned by API.