OpenAPI Specification
openapi: 3.0.3
info:
title: CDP → Akrites External Advisories Dashboard 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: Dashboard
description: KPI bar metrics and activity feed.
paths:
/akrites/metrics:
get:
operationId: getAkritesMetrics
summary: Get KPI bar metrics
description: 'Returns aggregate counts that power the global KPI bar on the OSSPREY dashboard (total packages, coverage %, active stewards, unassigned critical, needs-attention, escalated).
'
tags:
- Dashboard
responses:
'200':
description: Metrics snapshot.
content:
application/json:
schema:
$ref: '#/components/schemas/OsspreyMetrics'
'401':
description: Missing or invalid bearer token.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/akrites/activity:
get:
operationId: getAkritesActivity
summary: Get stewardship activity feed
description: 'Returns a paginated, reverse-chronological list of stewardship activity events across all packages (status changes, assignments, escalations, etc.).
'
tags:
- Dashboard
parameters:
- name: page
in: query
schema:
type: integer
minimum: 1
default: 1
- name: pageSize
in: query
schema:
type: integer
minimum: 1
maximum: 100
default: 25
responses:
'200':
description: Paginated activity feed.
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/PaginationMeta'
- type: object
required:
- rows
properties:
rows:
type: array
items:
$ref: '#/components/schemas/ActivityEntry'
'400':
description: Validation error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: Missing or invalid bearer token.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/ossprey/metrics:
get:
operationId: getOsspreyMetrics
summary: Global KPI bar metrics
description: 'Returns the seven aggregate metrics shown in the sticky KPI bar across all four dashboard tabs. Fetch once on page load; refresh after any write action.
'
tags:
- Dashboard
security:
- BearerAuth: []
responses:
'200':
description: KPI metrics.
content:
application/json:
schema:
type: object
required:
- totalPackages
- criticalPackages
- coveragePercent
- activeStewards
- unassignedCritical
- needsAttention
- escalated
properties:
totalPackages:
type: integer
description: Total critical packages (is_critical = true).
example: 1842
criticalPackages:
type: integer
description: Critical packages with at least one critical-severity advisory.
example: 312
coveragePercent:
type: number
format: float
description: 'Percentage of critical packages with status in (assessing, active, needs_attention). One decimal place.
'
example: 33.2
coverageTrend:
type:
- number
- 'null'
description: 'Percentage-point change vs. previous month. Null until snapshot mechanism is implemented.
'
example: null
activeStewards:
type: integer
description: 'COUNT(DISTINCT user_id) from stewardship_stewards where deleted_at IS NULL and stewardship status != inactive.
'
example: 42
unassignedCritical:
type: integer
description: Critical packages with no stewardship row or status = unassigned.
example: 1230
needsAttention:
type: integer
description: Critical packages with status = needs_attention.
example: 47
escalated:
type: integer
description: Critical packages with status = escalated.
example: 8
example:
totalPackages: 1842
criticalPackages: 312
coveragePercent: 33.2
coverageTrend: null
activeStewards: 42
unassignedCritical: 1230
needsAttention: 47
escalated: 8
'401':
description: Missing or invalid bearer token.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/ossprey/activity:
get:
operationId: listStewardshipActivity
summary: Paginated stewardship activity feed
description: 'Returns recent stewardship events across all packages, ordered by most recent first. Used to populate the activity feed on the Overview tab. The frontend groups items by day using `createdAt`.
'
tags:
- Dashboard
security:
- BearerAuth: []
parameters:
- name: page
in: query
schema:
type: integer
minimum: 1
default: 1
- name: pageSize
in: query
schema:
type: integer
minimum: 1
maximum: 100
default: 25
responses:
'200':
description: Paginated activity feed.
content:
application/json:
schema:
type: object
required:
- rows
- total
- page
- pageSize
properties:
rows:
type: array
items:
$ref: '#/components/schemas/ActivityFeedItem'
total:
type: integer
example: 142
page:
type: integer
example: 1
pageSize:
type: integer
example: 25
example:
rows:
- id: '9182736'
stewardshipId: '4501'
packagePurl: pkg:maven/org.slf4j/slf4j-api
packageName: slf4j-api
packageEcosystem: maven
actorUserId: auth0|mock-user-alice
actorType: user
activityType: state_changed
content: Assessment complete, moving to active
metadata:
from: assessing
to: active
stewardshipStatus: active
createdAt: '2026-06-14T10:23:00Z'
total: 11
page: 1
pageSize: 25
'400':
description: Validation error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: Missing or invalid bearer token.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
components:
schemas:
PaginationMeta:
type: object
required:
- total
- page
- pageSize
properties:
total:
type: integer
page:
type: integer
pageSize:
type: integer
ActivityFeedItem:
type: object
required:
- id
- stewardshipId
- packagePurl
- packageName
- packageEcosystem
- actorType
- activityType
- stewardshipStatus
- createdAt
properties:
id:
type: string
example: '9182736'
stewardshipId:
type: string
example: '4501'
packagePurl:
type: string
example: pkg:npm/minimist@1.2.6
packageName:
type: string
example: minimist
packageEcosystem:
type: string
example: npm
actorUserId:
type:
- string
- 'null'
description: Auth0 sub. Null for system events.
example: auth0|abc123
actorName:
type:
- string
- 'null'
description: 'Display name of the actor. Currently returns actorUserId as a placeholder — will be resolved to a display name once the cross-DB users join is implemented.
'
example: auth0|abc123
actorType:
type: string
enum:
- user
- system
activityType:
type: string
enum:
- state_changed
- steward_added
- steward_removed
- escalation
- escalation_resolved
- assessment_started
- assessment_completed
- assessment_flagged
- spot_check
- note_added
example: escalation
content:
type:
- string
- 'null'
example: 'Escalated with resolution path: right_of_first_refusal'
metadata:
type:
- object
- 'null'
additionalProperties: true
stewardshipStatus:
$ref: '#/components/schemas/StewardshipStatus'
createdAt:
type: string
format: date-time
OsspreyMetrics:
type: object
required:
- criticalPackages
- coveragePercent
- coverageTrend
- activeStewards
- unassignedCritical
- needsAttention
- escalated
properties:
criticalPackages:
type: integer
description: Total number of packages marked as critical (is_critical = true).
coveragePercent:
type: number
format: float
description: Percentage of critical packages with an active stewardship (assessing, active, or needs_attention).
coverageTrend:
type: number
format: float
nullable: true
description: Coverage delta vs. previous period. Currently always null (requires snapshot mechanism).
activeStewards:
type: integer
description: Distinct stewards assigned to a non-inactive stewardship.
unassignedCritical:
type: integer
description: Critical packages with no stewardship or status = unassigned.
needsAttention:
type: integer
description: Critical packages whose stewardship status is needs_attention.
escalated:
type: integer
description: Critical packages whose stewardship status is escalated.
Error:
type: object
required:
- error
properties:
error:
type: object
required:
- code
- message
properties:
code:
type: string
example: VALIDATION_ERROR
message:
type: string
example: Invalid query parameter.
ActivityEntry:
type: object
required:
- id
- stewardshipId
- packagePurl
- packageName
- packageEcosystem
- actorUserId
- actorName
- actorType
- activityType
- stewardshipStatus
- createdAt
properties:
id:
type: string
stewardshipId:
type: string
packagePurl:
type: string
packageName:
type: string
packageEcosystem:
type: string
actorUserId:
type: string
nullable: true
actorName:
type: string
nullable: true
description: Display name (currently same as actorUserId; resolution from members table is pending).
actorType:
type: string
example: user
activityType:
type: string
example: status_change
content:
type: string
nullable: true
metadata:
type: object
nullable: true
additionalProperties: true
stewardshipStatus:
$ref: '#/components/schemas/StewardshipStatus'
createdAt:
type: string
format: date-time
StewardshipStatus:
type: string
enum:
- unassigned
- open
- assessing
- active
- needs_attention
- escalated
- blocked
- inactive
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 <token>`; 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)