feat: expose security contacts via api [CM-1297]#4304
Conversation
Signed-off-by: Mouad BANI <mouad-mb@outlook.com>
|
|
There was a problem hiding this comment.
Pull request overview
This PR wires real security-contact data into the public package-detail API (GET /v1/akrites/packages/detail, shared with the deprecated /v1/packages/detail). Previously security.securityContacts and cvd.isPvrEnabled were hard-coded null; now they are sourced from the linked repo's security_contacts pipeline and repos policy columns.
Changes:
- Data-access layer: adds
SecurityContactConfidence/SecurityContactRowtypes, extendsPackageDetailRowandgetPackageDetailByPurlwith repo policy columns plus ajson_aggsubquery returning up to 5 active security contacts, and adds asecurityContactConfidenceBandhelper. - API handler: maps contacts (null until swept, empty array when swept with none), derives
packageConfidencefrom the top score, and exposes asecurityPoliciesblock andcvd.isPvrEnabled. - OpenAPI (
akrites): documents newSecurityContact/SecurityContactConfidenceschemas,packageConfidence, andsecurityPolicies, with null-vs-empty semantics.
Note: the deprecated backend/src/api/public/v1/packages/openapi.yaml still documents the old SecurityContact (name/email) shape and securityContacts: null, so it is now inaccurate for the shared handler — outside this PR's diff, but worth tracking before that spec is removed.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| services/libs/data-access-layer/src/osspckgs/api.ts | New security-contact types, SQL columns + json_agg subquery, and confidence-band helper. |
| backend/src/api/public/v1/packages/getPackage.ts | Maps contacts, computes packageConfidence, exposes securityPolicies and cvd.isPvrEnabled. |
| backend/src/api/public/v1/akrites/openapi.yaml | Adds SecurityContact/SecurityContactConfidence schemas and documents new response fields. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Signed-off-by: Mouad BANI <mouad-mb@outlook.com>
| export function securityContactConfidenceBand(score: number): SecurityContactConfidence { | ||
| if (score >= 0.8) return 'PRIMARY' | ||
| if (score >= 0.55) return 'SECONDARY' | ||
| if (score >= 0.3) return 'FALLBACK' | ||
| return 'NONE' | ||
| } |
There was a problem hiding this comment.
is there a reason why we are rewriting this function ? can we use the existing one ?
There was a problem hiding this comment.
Which existing one are you referring to?
score.ts's confidenceBand is only a wrapper calling securityContactConfidenceBand from the DAL
| return { rows, total } | ||
| } | ||
|
|
||
| export type SecurityContactConfidence = 'PRIMARY' | 'SECONDARY' | 'FALLBACK' | 'NONE' |
Signed-off-by: Mouad BANI <mouad-mb@outlook.com>
Signed-off-by: Mouad BANI <mouad-mb@outlook.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Reviewed by Cursor Bugbot for commit 0b72429. Configure here.
| const securityContacts = | ||
| pkg.contactsLastRefreshed == null | ||
| ? null | ||
| : (pkg.securityContacts ?? []).map((c) => ({ |
There was a problem hiding this comment.
Failed sweep shows empty contacts
Medium Severity
securityContacts is derived only from whether contactsLastRefreshed is set, but the worker also sets that timestamp on failed extractor or repo runs via markRepoAttempted without persisting contacts. Clients then get an empty array, which the OpenAPI text describes as a successful sweep with no contacts, not a failed attempt.
Reviewed by Cursor Bugbot for commit 0b72429. Configure here.


This pull request adds support for returning security contact information and related metadata for packages in the public API. It introduces new data structures for security contacts, exposes them in the API response, and updates the data-access layer to retrieve and process this information from the database.
API Schema and Response Enhancements:
SecurityContactandSecurityContactConfidencetypes to the OpenAPI schema, and updated thesecurityContactsfield to include detailed information and a newpackageConfidencefield. Also added asecurityPoliciesobject with security-related URLs and flags. [1] [2]Backend and Data Layer Updates:
api.ts) to fetch security contacts and related fields from the database, including new fields for security policy URLs and contact refresh times. [1] [2]SecurityContactConfidencetype,SecurityContactRowinterface, and asecurityContactConfidenceBandfunction to map contact scores to confidence bands. [1] [2]getPackage.ts) to process and return security contact details, compute the highest-confidence band, and include the newsecurityPoliciesobject in responses. [1] [2] [3]Note
Medium Risk
Adds a public API contract that exposes contact channels/values (emails, handles, URLs) and changes null vs empty semantics for clients; logic is read-only but disclosure-sensitive.
Overview
Package detail responses now surface security contact data from the linked repo instead of placeholders: up to five scored contacts (channel, value, role, confidence, score), a packageConfidence band from the top score, and securityPolicies URLs plus pvrEnabled. securityContacts is
nulluntil the security-contacts pipeline has swept the repo, and[]when swept with no hits; provenance stays internal.OpenAPI adds
SecurityContact/SecurityContactConfidenceand documents that behavior. The data layer extendsgetPackageDetailByPurlto join repo policy fields and aggregate fromsecurity_contacts;securityContactConfidenceBandis shared with the packages worker scorer (local duplicate removed).Reviewed by Cursor Bugbot for commit 0b72429. Bugbot is set up for automated code reviews on this repo. Configure here.