Skip to content

feat: expose project-profiling endpoint on akrites-external [CM-1356] - #4423

Merged
mbani01 merged 6 commits into
mainfrom
feat/project-profiling-endpoint
Aug 3, 2026
Merged

feat: expose project-profiling endpoint on akrites-external [CM-1356]#4423
mbani01 merged 6 commits into
mainfrom
feat/project-profiling-endpoint

Conversation

@mbani01

@mbani01 mbani01 commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

This pull request introduces a new /akrites-external/project-profiling API endpoint that exposes an assembled vulnerability-reporting protocol for a package's best-matched repository. It also updates the OpenAPI contract, data access layer, and related types to support this new endpoint, while removing deprecated or reserved fields from the contact detail response. The changes improve the clarity and separation of security contact information and vulnerability reporting protocols.

New Project Profiling API:

  • Added the getAkritesExternalProjectProfiling handler, route, and associated types to serve the assembled vulnerability-reporting protocol for a package, including reporting methods, guidelines, and provenance (backend/src/api/public/v1/akrites-external/index.ts, backend/src/api/public/v1/packages/getAkritesExternalProjectProfiling.ts, backend/src/api/public/v1/packages/akritesExternalProjectProfiling.ts, services/libs/data-access-layer/src/osspckgs/api.ts) [1] [2] [3] [4] [5].

  • Added OpenAPI documentation for the new /akrites-external/project-profiling endpoint, including schemas for ProjectProfiling, ProjectProfilingMethod, and ProjectProfilingGuidelines (backend/src/api/public/v1/akrites-external/openapi.yaml) [1] [2] [3] [4].

Contract and Schema Cleanup:

  • Removed deprecated/reserved fields (targetOrganizationName, bugBountyProgramFlag, reportingMethods, reportingGuidelines, integrationHints) from the ContactDetail schema, related TypeScript types, and tests, clarifying that reporting protocol information is now only available via the new endpoint (backend/src/api/public/v1/akrites-external/openapi.yaml, backend/src/api/public/v1/packages/akritesExternalContactDetail.ts, backend/src/api/public/v1/packages/akritesExternalContactDetail.test.ts) [1] [2] [3] [4] [5] [6].

Testing and Validation:

  • Added comprehensive tests for the new project profiling mapping logic, ensuring correct normalization and defaulting of values (backend/src/api/public/v1/packages/akritesExternalProjectProfiling.test.ts).

These changes provide a more robust and clearly separated interface for consumers to retrieve vulnerability reporting protocols, aligning the API with upstream requirements and improving maintainability.

Signed-off-by: Mouad BANI <mouad-mb@outlook.com>
@mbani01 mbani01 self-assigned this Aug 3, 2026
Copilot AI review requested due to automatic review settings August 3, 2026 10:58
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@cursor

cursor Bot commented Aug 3, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
New external API surface exposes contact PII via inferred protocol methods, with scope gating aligned to contacts; contact detail is a breaking schema change for consumers that relied on removed placeholder fields.

Overview
Adds GET /akrites-external/project-profiling and POST /project-profiling:batch so Akrites can load the assembled vulnerability-reporting protocol (ordered methods, guidelines, sources, bugBountyUrl, assembledAt) for a package’s best-matched repo. Routes use maintainer scopes (read:akrites-maintainers / read:maintainer-roles), not package scopes, because inferred methods can expose maintainer/committer emails.

The data layer adds getReportingProtocolByPurl / getReportingProtocolsByPurls against repo_reporting_protocols with the same best-repo pick as other package APIs. Responses are mapped via toAkritesExternalProjectProfiling (including ISO normalization for assembledAt).

Contact detail contract cleanup: removes the always-null reserved fields (reportingMethods, reportingGuidelines, integrationHints, etc.) from ContactDetail and the TypeScript mapper; OpenAPI replaces placeholder ReportingMethod / IntegrationHints schemas with real ProjectProfiling types documented on the new endpoints.

Reviewed by Cursor Bugbot for commit a770cb4. Bugbot is set up for automated code reviews on this repo. Configure here.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 91caa4f. Configure here.

Comment thread backend/src/api/public/v1/akrites-external/index.ts

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an Akrites project-profiling endpoint for repository vulnerability-reporting protocols.

Changes:

  • Adds the endpoint, mapper, DAL query, and tests.
  • Documents the new OpenAPI contract.
  • Removes reserved contact-detail fields.

Review note: The title should end with (CM-1356), not [CM-1356].

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
services/libs/data-access-layer/src/osspckgs/api.ts Queries assembled protocols by PURL.
backend/src/api/public/v1/packages/getAkritesExternalProjectProfiling.ts Implements the request handler.
backend/src/api/public/v1/packages/akritesExternalProjectProfiling.ts Maps database results to API responses.
backend/src/api/public/v1/packages/akritesExternalProjectProfiling.test.ts Tests response mapping.
backend/src/api/public/v1/packages/akritesExternalContactDetail.ts Removes reserved response fields.
backend/src/api/public/v1/packages/akritesExternalContactDetail.test.ts Removes obsolete assertions.
backend/src/api/public/v1/akrites-external/openapi.yaml Defines the endpoint and schemas.
backend/src/api/public/v1/akrites-external/index.ts Registers the authenticated route.
Suppressed comments (1)

backend/src/api/public/v1/akrites-external/openapi.yaml:762

  • The ProjectProfiling response does not define integrationHints, so this description incorrectly claims the removed field is available from the new endpoint.
        vulnerability-reporting protocol (methods, guidelines, integration hints)
        is served by GET /akrites-external/project-profiling.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread backend/src/api/public/v1/akrites-external/index.ts Outdated
Comment thread backend/src/api/public/v1/akrites-external/openapi.yaml Outdated
Comment thread backend/src/api/public/v1/akrites-external/openapi.yaml Outdated
Signed-off-by: Mouad BANI <mouad-mb@outlook.com>
Copilot AI review requested due to automatic review settings August 3, 2026 11:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.

Suppressed comments (2)

backend/src/api/public/v1/akrites-external/openapi.yaml:80

  • This tag advertises package scopes, but the route and operation-level security require read:akrites-maintainers or read:maintainer-roles. Generated documentation will therefore tell consumers to request scopes that always receive 403. Keep this description aligned with the actual maintainer-scope requirement.
      guidelines. Same scope set as Packages (read:akrites-packages, or
      read:packages / read:stewardships as a fallback until the cutover
      completes).

services/libs/data-access-layer/src/osspckgs/api.ts:1189

  • The mapper tests never execute this new SQL path, leaving best-repo selection and the package/protocol-missing semantics unverified. Add an integration test analogous to getContactDetailsByPurls.integration.test.ts, including competing repo links and a best repo without a protocol.
export async function getReportingProtocolByPurl(
  qx: QueryExecutor,
  purl: string,
): Promise<ReportingProtocolRow | null> {

@mbani01
mbani01 requested review from joanagmaia and ulemons August 3, 2026 11:28

@joanagmaia joanagmaia left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mbani01 could we also add a :batch endpoint similarly to contacts/detail:batch one for profiling? I think it would also make sense on this endpoint

Comment on lines +78 to +80
guidelines. Same scope set as Packages (read:akrites-packages, or
read:packages / read:stewardships as a fallback until the cutover
completes).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Route scopes are correct 👍, but this tag text says "same as Packages" while the endpoint uses the maintainer scopes. Can we fix the description to match the security: block?

ulemons
ulemons previously approved these changes Aug 3, 2026
Signed-off-by: Mouad BANI <mouad-mb@outlook.com>
Copilot AI review requested due to automatic review settings August 3, 2026 14:44
Signed-off-by: Mouad BANI <mouad-mb@outlook.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.

Suppressed comments (3)

services/libs/data-access-layer/src/osspckgs/api.ts:1215

  • The added mapper tests never execute either new SQL query. Comparable DAL batch lookups have packages-db integration suites (getPackageDetailsByPurls.integration.test.ts and getContactDetailsByPurls.integration.test.ts); add coverage for single/batch matches, missing protocols, and the confidence/declared best-repo selection.
// Batch variant of getReportingProtocolByPurl; unmatched purls are absent from the result.
export async function getReportingProtocolsByPurls(

services/libs/data-access-layer/src/osspckgs/api.ts:1159

  • type and status are widened to arbitrary strings even though the stored protocol model defines closed unions (services/apps/packages_worker/src/security-contacts/protocol/types.ts:1-11). This removes compile-time protection against values that violate the public contract; keep the literal unions here (or move the shared protocol types into a library both layers can import).

This issue also appears on line 1214 of the same file.

  type: string
  status: string

backend/src/api/public/v1/akrites-external/openapi.yaml:686

  • The assembled protocol has a closed six-value method-type union (services/apps/packages_worker/src/security-contacts/protocol/types.ts:1-8), but this schema permits any string. Generated API clients therefore cannot narrow or validate this field; expose the same enum as the source model.
        type:
          type: string
          description: Channel type, e.g. github-pvr, email, web-form, security-txt, bounty-platform, mailing-list.

Copilot AI review requested due to automatic review settings August 3, 2026 14:48

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.

Suppressed comments (3)

services/libs/data-access-layer/src/osspckgs/api.ts:1234

  • The batch lookup repeats the same nondeterministic tie handling as the single lookup. Equal-confidence links with the same declared preference can select an arbitrary repository, making batch and single responses disagree. Apply the stable canonical ordering from BEST_REPO_LINK_JOIN here as well.
      ORDER BY pr2.confidence DESC, (pr2.source = 'declared') DESC

services/libs/data-access-layer/src/osspckgs/api.ts:1204

  • This “best repo” selection is nondeterministic when two links have the same confidence and both are declared (or both are not). package_repos permits that state, so this endpoint can expose a different repository than package detail despite the stated contract. Add a stable final key (for example pr2.id) to the shared BEST_REPO_LINK_JOIN ordering and reuse that canonical selection here.

This issue also appears on line 1234 of the same file.

      ORDER BY pr2.confidence DESC, (pr2.source = 'declared') DESC

services/libs/data-access-layer/src/osspckgs/api.ts:1218

  • The new SQL lookup has only mapper unit coverage; its best-repo join, single-vs-batch behavior, and missing-protocol semantics are untested. Equivalent DAL APIs have packages-db integration suites (getPackageDetailsByPurls.integration.test.ts, getContactDetailsByPurls.integration.test.ts, and getAdvisoriesByPurls.integration.test.ts). Add matching integration coverage for both reporting-protocol functions, including tie selection and packages whose best repo has no protocol.
export async function getReportingProtocolsByPurls(
  qx: QueryExecutor,
  purls: string[],
): Promise<ReportingProtocolRow[]> {

Signed-off-by: Mouad BANI <mouad-mb@outlook.com>
Copilot AI review requested due to automatic review settings August 3, 2026 15:11

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.

Suppressed comments (5)

services/libs/data-access-layer/src/osspckgs/api.ts:1239

  • The batch lookup has the same unstable tie handling: equal-confidence links with the same declared preference can select an arbitrary repo, so batch and single responses may disagree. Reuse the deterministically ordered shared best-repo selection.
      FROM package_repos pr2
      WHERE pr2.package_id = p.id
      ORDER BY pr2.confidence DESC, (pr2.source = 'declared') DESC
      LIMIT 1

backend/src/api/public/v1/akrites-external/openapi.yaml:686

  • The source model defines exactly six method types, while this schema accepts any string. Add the enum so generated clients and validators expose the same closed contract as the stored protocol.
        type:
          type: string
          description: Channel type, e.g. github-pvr, email, web-form, security-txt, bounty-platform, mailing-list.

services/libs/data-access-layer/src/osspckgs/api.ts:1207

  • This best-repo selection is nondeterministic when two links have equal confidence and the same declared preference, a state allowed by package_repos. Since package detail and profiling execute separate queries, they can surface different repos despite the stated contract. Add a stable final key to the shared BEST_REPO_LINK_JOIN ordering and reuse that canonical selection here.

This issue also appears on line 1236 of the same file.

      FROM package_repos pr2
      WHERE pr2.package_id = p.id
      ORDER BY pr2.confidence DESC, (pr2.source = 'declared') DESC
      LIMIT 1

services/libs/data-access-layer/src/osspckgs/api.ts:1221

  • These new SQL paths have only mapper unit coverage. Comparable Akrites DAL lookups have packages-db integration suites (getPackageDetailsByPurls.integration.test.ts, getContactDetailsByPurls.integration.test.ts, and getAdvisoriesByPurls.integration.test.ts). Add analogous coverage for single/batch matches, missing protocols, and competing repo links so the join and not-found semantics are verified.
export async function getReportingProtocolsByPurls(
  qx: QueryExecutor,
  purls: string[],
): Promise<ReportingProtocolRow[]> {

services/libs/data-access-layer/src/osspckgs/api.ts:1159

  • type and status are closed unions in the persisted protocol model, but these widened strings remove compile-time protection and can drift from the OpenAPI enums. Keep the DAL shape aligned with the worker's protocol contract.
  type: string
  status: string

@mbani01
mbani01 merged commit 5bde9cf into main Aug 3, 2026
14 checks passed
@mbani01
mbani01 deleted the feat/project-profiling-endpoint branch August 3, 2026 15:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants