Build-id index export API

GET /api/vulnerabilities/v1/binaries/build-id-index streams the Vulnerabilities owner’s current build-id index as application/x-ndjson, with attachment name index.ndjson. The route requires the existing advisory:read policy. It calls the owner export service; no database work occurs in the route handler.

The first line is # stellaops-build-id-index: v1. Remaining rows come from committed binary identities and package maps with a build ID and package URL. Rows contain build_id, purl, optional version and distro, confidence and indexed_at. The exporter orders the rows and groups identical associations. An empty corpus returns the version declaration with no data rows. CVE applicability and backport conclusions remain separate owner queries.

Anonymous and insufficient-scope requests return 401 and 403. An unavailable owner connection or missing export schema detected before streaming returns 503 with problem title build_id_index_export_unavailable. An export failure after the response starts terminates the stream; consumers must treat incomplete transfer as failure. The API does not sign, receive private keys or establish consumer trust.

The gateway has an exact HTTP ReverseProxy exception for this export, preserving the caller’s bearer and the complete owner path. Its bare destination is http://vulnerabilities.stella-ops.local:8080. The message dispatcher buffers complete bodies, so this unbounded artifact uses the same transport exception as corpus export. Neighboring binary/symbol APIs retain their published routing.

Operators use the CLI export and enrollment workflow to download the bytes, sign a digest/length descriptor with their configured purpose key and publish a new directory atomically. Public key enrollment into a consumer is a separate operator action.

Scanner binds its index settings under Scanner:Worker:NativeAnalyzers:BuildIdIndex. With RequireSignature=true (the default), the sidecar is the index path with extension .dsse.json. Its exact payload type is application/vnd.stellaops.build-id-index.manifest.v1+json; the signed descriptor names the format version, byte length and SHA-256 digest. The signature is verified through Stella Ops cryptography using the independently configured public JWKS file at Crypto:SignatureTrust:JwksFiles:binary-build-id-index. The consumer hashes the same stream it parses and installs the index only after its length and digest match. Missing trust, invalid signatures, unsupported formats and modified content produce Refused with no loaded associations. The exported JWKS is enrollment material and is never a trust source merely because it sits beside the index.

The binary-plane rehearsal exercises this path from actual Worker ingestion through HTTP export and native Scanner matching.