|
10 | 10 |
|
11 | 11 |
|
12 | 12 | Packages, Advisories and Contacts endpoints are implemented. Blast Radius |
13 | | - is specced separately and not yet built. |
| 13 | + submit (2a) is implemented but the reachability pipeline is not built yet — |
| 14 | + every submitted job currently fails with an ECOSYSTEM_NOT_SUPPORTED error |
| 15 | + once the underlying workflow runs. Poll (2b), the 7-day result cache, and |
| 16 | + the actual analysis are specced separately and not yet built. |
14 | 17 |
|
15 | 18 |
|
16 | 19 | TODO: scopes below (read:packages, read:stewardships) are the existing |
|
45 | 48 | it, the implementation requires read:maintainer-roles (NOT read:packages). |
46 | 49 | The response shape is still under discussion upstream (reportingMethods / |
47 | 50 | reportingGuidelines / integrationHints are reserved and always null today). |
| 51 | + - name: Blast Radius |
| 52 | + description: > |
| 53 | + Advisory reachability analysis — submit (2a) is implemented; poll (2b) is |
| 54 | + not built yet. Submitting kicks off a Temporal workflow which currently |
| 55 | + fails every job with ECOSYSTEM_NOT_SUPPORTED, since the reachability |
| 56 | + pipeline itself hasn't shipped. Rate-limited independently of the other |
| 57 | + akrites-external endpoints (default 5 requests/hour, configurable via |
| 58 | + AKRITES_BLAST_RADIUS_RATE_LIMIT_MAX / _WINDOW_MS). Same interim scope |
| 59 | + note as Advisories applies (read:packages, pending a dedicated |
| 60 | + read:advisories scope). |
48 | 61 |
|
49 | 62 | components: |
50 | 63 | securitySchemes: |
@@ -361,6 +374,63 @@ components: |
361 | 374 | allOf: |
362 | 375 | - $ref: '#/components/schemas/AdvisoryDetail' |
363 | 376 |
|
| 377 | + BlastRadiusJobRequest: |
| 378 | + type: object |
| 379 | + required: [advisoryId, ecosystem] |
| 380 | + properties: |
| 381 | + advisoryId: |
| 382 | + type: string |
| 383 | + pattern: '^(GHSA-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}|CVE-\d{4}-\d{4,})$' |
| 384 | + description: > |
| 385 | + GHSA or CVE identifier. Any other format, including free-text |
| 386 | + strings, is rejected with a 400. |
| 387 | + example: GHSA-jf85-cpcp-j695 |
| 388 | + ecosystem: |
| 389 | + type: string |
| 390 | + enum: [npm] |
| 391 | + description: > |
| 392 | + Required. The reachability pipeline is npm-only today — any other |
| 393 | + value, or a missing ecosystem, is rejected with a 400. |
| 394 | + example: npm |
| 395 | + package: |
| 396 | + type: string |
| 397 | + nullable: true |
| 398 | + description: > |
| 399 | + Optional. Full purl or bare package name. If omitted, the analysis |
| 400 | + is advisory-wide: reachability is evaluated across every package |
| 401 | + the advisory affects, returned as one aggregate result — not one |
| 402 | + job per affected package. |
| 403 | + force: |
| 404 | + type: boolean |
| 405 | + default: false |
| 406 | + description: Bypasses the 7-day cache and always triggers a new run. Use sparingly. |
| 407 | + |
| 408 | + BlastRadiusJobEntry: |
| 409 | + type: object |
| 410 | + required: [analysisId, advisoryId, package, ecosystem, status] |
| 411 | + description: Response body of 2a — one job per request, never wrapped in an array. |
| 412 | + properties: |
| 413 | + analysisId: |
| 414 | + type: string |
| 415 | + description: Opaque identifier for polling via 2b (not yet implemented). |
| 416 | + advisoryId: |
| 417 | + type: string |
| 418 | + package: |
| 419 | + type: string |
| 420 | + nullable: true |
| 421 | + description: Echoes the request's package. Null when the request omitted it. |
| 422 | + ecosystem: |
| 423 | + type: string |
| 424 | + enum: [npm] |
| 425 | + description: Echoes the request's ecosystem. Always present — the request requires it. |
| 426 | + status: |
| 427 | + type: string |
| 428 | + enum: [pending, running, done, failed] |
| 429 | + description: > |
| 430 | + Always pending today — every job starts a Temporal workflow that |
| 431 | + currently fails with ECOSYSTEM_NOT_SUPPORTED once it runs, since |
| 432 | + the reachability pipeline isn't built yet. |
| 433 | +
|
364 | 434 | ContactConfidenceBand: |
365 | 435 | type: string |
366 | 436 | enum: [PRIMARY, SECONDARY, FALLBACK, NONE] |
@@ -806,6 +876,65 @@ paths: |
806 | 876 | schema: |
807 | 877 | $ref: '#/components/schemas/Error' |
808 | 878 |
|
| 879 | + /akrites-external/blast-radius/jobs: |
| 880 | + post: |
| 881 | + operationId: submitBlastRadiusJob |
| 882 | + summary: 2a — Submit a blast-radius analysis job |
| 883 | + description: > |
| 884 | + Always exactly one job per request — no bulk submit. Omit package for |
| 885 | + an advisory-wide analysis; provide it to narrow to a single package. |
| 886 | +
|
| 887 | +
|
| 888 | + Not yet implemented: the 7-day result cache, force-bypass semantics, |
| 889 | + and the actual reachability pipeline. Today every submission starts a |
| 890 | + fresh Temporal workflow that fails with ECOSYSTEM_NOT_SUPPORTED — the |
| 891 | + job is accepted and echoed back as pending, but never completes. |
| 892 | + tags: [Blast Radius] |
| 893 | + security: |
| 894 | + - M2MBearer: |
| 895 | + - read:packages |
| 896 | + requestBody: |
| 897 | + required: true |
| 898 | + content: |
| 899 | + application/json: |
| 900 | + schema: |
| 901 | + $ref: '#/components/schemas/BlastRadiusJobRequest' |
| 902 | + responses: |
| 903 | + '202': |
| 904 | + description: Job accepted. |
| 905 | + content: |
| 906 | + application/json: |
| 907 | + schema: |
| 908 | + $ref: '#/components/schemas/BlastRadiusJobEntry' |
| 909 | + '400': |
| 910 | + description: > |
| 911 | + Validation error (missing/empty advisoryId), or an unsupported |
| 912 | + ecosystem — only npm is supported today, so any other value |
| 913 | + (including a missing ecosystem) is rejected before a workflow |
| 914 | + is started. |
| 915 | + content: |
| 916 | + application/json: |
| 917 | + schema: |
| 918 | + $ref: '#/components/schemas/Error' |
| 919 | + '401': |
| 920 | + description: Missing or invalid bearer token. |
| 921 | + content: |
| 922 | + application/json: |
| 923 | + schema: |
| 924 | + $ref: '#/components/schemas/Error' |
| 925 | + '403': |
| 926 | + description: Token missing read:packages scope. |
| 927 | + content: |
| 928 | + application/json: |
| 929 | + schema: |
| 930 | + $ref: '#/components/schemas/Error' |
| 931 | + '429': |
| 932 | + description: Too many requests — rate-limited independently of the other endpoints. |
| 933 | + content: |
| 934 | + application/json: |
| 935 | + schema: |
| 936 | + $ref: '#/components/schemas/Error' |
| 937 | + |
809 | 938 | /akrites-external/contacts/detail: |
810 | 939 | get: |
811 | 940 | operationId: getContactDetail |
|
0 commit comments