# Vuln Explorer API ยท v1 (draft 2025-11-25) openapi: 3.0.3 info: title: StellaOps Vuln Explorer API version: "1.0.0-draft.2025-11-25" description: > Read-only vulnerability exploration surface. All responses are deterministic under identical inputs and include policy version + rationale identifiers. servers: - url: https://{host} variables: host: default: vuln-explorer.local tags: - name: Vulns paths: /vulns: get: summary: List vulnerabilities tags: [Vulns] parameters: - $ref: '#/components/parameters/Tenant' - $ref: '#/components/parameters/PolicyVersion' - $ref: '#/components/parameters/PageSize' - $ref: '#/components/parameters/PageToken' - $ref: '#/components/parameters/Cve' - $ref: '#/components/parameters/Purl' - $ref: '#/components/parameters/Severity' - $ref: '#/components/parameters/Exploitability' - $ref: '#/components/parameters/FixAvailable' responses: '200': description: Paged vulnerabilities ordered by (score desc, id asc). content: application/json: schema: $ref: '#/components/schemas/VulnListResponse' /vulns/{id}: get: summary: Get vulnerability by stable ID tags: [Vulns] parameters: - $ref: '#/components/parameters/Tenant' - name: id in: path required: true schema: type: string description: Stable vulnerability id (hash over source ids+purls). responses: '200': description: Vulnerability detail with evidence/provenance. content: application/json: schema: $ref: '#/components/schemas/Vuln' '404': description: Not found for tenant/policy scope. components: parameters: Tenant: name: x-stella-tenant in: header required: true schema: { type: string } description: Tenant identifier; required for all endpoints. PolicyVersion: name: policyVersion in: query schema: { type: string } description: Policy version/rationale to contextualise scores. PageSize: name: pageSize in: query schema: type: integer minimum: 1 maximum: 200 default: 50 description: Max items per page. PageToken: name: pageToken in: query schema: { type: string } description: Opaque token encoding last (score,id) tuple. Cve: name: cve in: query schema: { type: array, items: { type: string }, minItems: 1 } style: form explode: true description: Filter by CVE ids. Purl: name: purl in: query schema: { type: array, items: { type: string }, minItems: 1 } style: form explode: true description: Filter by PURL(s); matches affected packages. Severity: name: severity in: query schema: type: array items: type: string enum: [CRITICAL, HIGH, MEDIUM, LOW, NONE] style: form explode: true description: Filter by normalized severity band. Exploitability: name: exploitability in: query schema: type: string enum: [known, likely, unknown, none] description: Derived exploitability flag (from KEV + VEX + telemetry). FixAvailable: name: fixAvailable in: query schema: { type: boolean } description: Whether at least one fix is available. schemas: VulnListResponse: type: object properties: items: type: array items: { $ref: '#/components/schemas/Vuln' } nextPageToken: type: string description: Opaque token encoding last (score,id) tuple. required: [items] Vuln: type: object properties: id: { type: string, description: Stable hash id } source: type: object properties: feed: { type: string, description: Original source/feed name } advisoryId: { type: string } cveIds: type: array items: { type: string } ghsaIds: type: array items: { type: string } purls: type: array items: { type: string } severity: { type: string, enum: [CRITICAL, HIGH, MEDIUM, LOW, NONE] } score: { type: number, format: double, minimum: 0, maximum: 10 } kev: { type: boolean } exploitability: { type: string, enum: [known, likely, unknown, none] } fixAvailable: { type: boolean } summary: { type: string } affectedPackages: type: array items: type: object properties: purl: { type: string } versions: { type: array, items: { type: string } } firstSeen: { type: string, format: date-time } lastSeen: { type: string, format: date-time } advisoryRefs: type: array items: type: object properties: url: { type: string, format: uri } title: { type: string } policyVersion: { type: string } rationaleId: { type: string } provenance: type: object properties: ledgerEntryId: { type: string } evidenceBundleId: { type: string } required: - id - severity - score - policyVersion - rationaleId