openapi: 3.0.3 info: title: CDP → Akrites External Advisories API version: 0.1.0 description: 'Read-only external API exposing CDP package security data to the Akrites service. Authenticated via Auth0 M2M client-credentials — CDP only verifies the resulting access token; the assertion exchange happens entirely between Akrites and Auth0. Packages, Advisories and Contacts endpoints are implemented. Blast Radius is specced separately and not yet built. TODO: scopes below (read:packages, read:stewardships) are the existing internal CDP UI scopes, reused here for now. Swap for a dedicated cdp:packages:read scope once Akrites gets its own Auth0 M2M scopes per the akrites-external draft contract. ' servers: - url: https://cm.lfx.dev/api/v1 description: Production security: - M2MBearer: - read:packages - read:stewardships tags: - name: Advisories description: 'Security advisories for a package, split out of package detail. The draft contract gates these behind a dedicated read:advisories scope; until Auth0 issues it, the implementation reuses read:packages (advisories need no stewardship read). Confirm the final scope name (read:advisories vs cdp:advisories:read) with Akrites/product. ' paths: /akrites-external/advisories/detail: get: operationId: getAdvisoryDetail summary: Get advisories for a package by PURL tags: - Advisories security: - M2MBearer: - read:packages parameters: - name: purl in: query required: true schema: type: string example: pkg:npm/%40angular/core responses: '200': description: Advisories for the package (empty array when the package has none). content: application/json: schema: $ref: '#/components/schemas/AdvisoryDetail' '400': description: Malformed purl. content: application/json: schema: $ref: '#/components/schemas/Error' '401': description: Missing or invalid bearer token. content: application/json: schema: $ref: '#/components/schemas/Error' '403': description: Token missing read:packages scope. content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Package not found. content: application/json: schema: $ref: '#/components/schemas/Error' /akrites-external/advisories/detail:batch: post: operationId: getAdvisoryDetailBatch summary: Bulk advisory lookup tags: - Advisories security: - M2MBearer: - read:packages requestBody: required: true content: application/json: schema: type: object required: - purls properties: purls: type: array minItems: 1 maxItems: 100 items: type: string page: type: integer minimum: 1 default: 1 pageSize: type: integer minimum: 1 maximum: 100 default: 20 responses: '200': description: One page of results, in request order. content: application/json: schema: type: object required: - page - pageSize - total - results properties: page: type: integer pageSize: type: integer total: type: integer description: Total number of requested purls, across all pages. results: type: array items: $ref: '#/components/schemas/AdvisoryDetailBulkEntry' '400': description: Validation error (empty array, >100 items, malformed purl). content: application/json: schema: $ref: '#/components/schemas/Error' '401': description: Missing or invalid bearer token. content: application/json: schema: $ref: '#/components/schemas/Error' '403': description: Token missing read:packages scope. content: application/json: schema: $ref: '#/components/schemas/Error' components: schemas: Advisory: type: object required: - osvId - severity - resolution - isCritical properties: osvId: type: string example: GHSA-xxxx-xxxx-xxxx severity: type: string enum: - critical - high - moderate - low - null nullable: true description: 'Lowercased advisory severity. Any stored value outside this enum is returned as null rather than echoed verbatim. ' resolution: type: string enum: - open - patched - null nullable: true description: 'Whether the package''s latest version is still affected. Null when it can''t be determined (no latest version, or no affected ranges recorded). ' isCritical: type: boolean nullable: true description: cvss >= 7.0. Null when the advisory has no CVSS score. Error: type: object required: - error properties: error: type: object required: - code - message properties: code: type: string example: BAD_REQUEST message: type: string AdvisoryDetailBulkEntry: type: object required: - requestedPurl - found - advisories properties: requestedPurl: type: string found: type: boolean advisories: type: object nullable: true allOf: - $ref: '#/components/schemas/AdvisoryDetail' AdvisoryDetail: type: object required: - purl - advisories properties: purl: type: string advisories: type: array items: $ref: '#/components/schemas/Advisory' securitySchemes: M2MBearer: type: oauth2 description: 'Auth0 machine-to-machine client-credentials flow. Akrites exchanges its client ID/secret with Auth0 for a JWT and sends it as `Authorization: Bearer `; CDP only verifies the resulting token. ' flows: clientCredentials: tokenUrl: https://linuxfoundation.auth0.com/oauth/token scopes: read:packages: Read package detail read:stewardships: Read package stewardship data read:maintainer-roles: Read security contacts (interim scope for Contacts; see the Contacts tag)