Add durable component license curation: component analyses, policies, and read-only imported components - #6961
Open
canikrichard wants to merge 6 commits into
Open
canikrichard wants to merge 6 commits into
canikrichard wants to merge 6 commits into
Conversation
License corrections must survive BOM re-uploads, carry an audit trail, and be automatable; ad-hoc component edits provide none of that. ADR 029 records the design: identity-keyed component analyses, CEL-driven component policies on top, and read-only imported components with a manual-component escape hatch. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Richard Canik <canik@brightpick.ai>
A component analysis stores a license override and free-text details per component, keyed by the component's identity (purl, falling back to group/name/version) within a project. Component rows are deleted and recreated across BOM uploads, so identity keys are the only way for a curation to survive; the analysis is re-applied at the end of every BOM import, after field synchronization and before policy evaluation, so LICENSE violations always evaluate against the curated license. The BOM-declared license is snapshotted on first override, letting a cleared override restore the uploaded value instantly. Every change appends an audit comment. The migration ships the complete curation schema, including the COMPONENT_POLICY table that analyses reference via POLICY_ID; the policy machinery itself lands in a follow-up commit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Richard Canik <canik@brightpick.ai>
Spec-first v2 endpoints for durable license curation: list the analyses of a project, upsert an analysis by component identity, delete one, and read or append audit-trail comments. Upserting resolves the license (SPDX ID or custom license name, rejected with 400 when unknown), records per-field audit comments, and immediately applies the override to matching components so a correction is visible without waiting for the next upload. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Richard Canik <canik@brightpick.ai>
A component policy is a CEL condition over component and project fields plus a license and details to apply on match. Policies are evaluated at every BOM import in priority order, first match wins, optionally limited to a validity window. A matching policy maintains a component analysis carrying its patch and writes the same per-field audit comments as manual curation, authored as the policy. Manual analyses always win over policies, and when no policy matches anymore the policy-maintained analysis is retracted so the imported license applies again. CRUD lives under /api/v2/component-policies; the CEL condition is compiled server-side and rejected with 400 when invalid. Protos for evaluation are built from the in-flight JDO components so first-upload matching works before the transaction commits. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Richard Canik <canik@brightpick.ai>
Components imported from BOM uploads are managed exclusively by the uploads themselves; ad-hoc REST mutations would be overwritten by the next upload or bypass the curation audit trail. Component update, delete, and property mutations therefore respond 405 unless the component was created manually through the REST API. Manually created components carry a MANUALLY_CREATED flag, stay fully editable, and are never deleted by BOM synchronization. When a BOM component matches a manual component's identity, the BOM takes ownership: the flag clears and the component becomes read-only. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Richard Canik <canik@brightpick.ai>
Upstream bb9d2c9 fixed the analysis join fanning out duplicate rows when a project has more than one analysis for the same vulnerability. This test pins the Dao behaviour directly, including that a sibling component's suppression neither hides nor leaks into another component's findings. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Richard Canik <canik@brightpick.ai>
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 163 |
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
canikrichard
marked this pull request as ready for review
August 12, 2026 10:08
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Adds durable, audited license curation for components. When a BOM declares a component's license incorrectly (or omits it), the only options today are suppressing the resulting policy violation — which hides a finding instead of correcting the data — or editing the component via REST, which the next BOM upload silently reverts. This PR makes the license correction a first-class concept that survives re-uploads:
/component-analyses(+{id},{id}/comments) and/component-policies(+{id}).MANUALLY_CREATEDflag, remain fully editable, and are never deleted by BOM synchronization; if a BOM component later matches a manual component's identity, the BOM takes ownership (the flag clears and the component becomes read-only).Addressed Issue
Closes #251
Additional Details
ImportBomActivitygains a single hook at the end of component processing — deliberately the only touch point in the ingestion path.COMPONENT_ANALYSIS,COMPONENT_ANALYSIS_COMMENT,COMPONENT_POLICYvia migrationV202608121000, plus theMANUALLY_CREATEDcomponent flag).Checklist
This PR fixes a defect, and I have provided tests to verify that the fix is effectivedocs/adr/