Draft: Scope tracked ref vulnerability count to open states

What does this MR do and why?

SecurityTrackedRef.vulnerabilitiesCount is described and labelled as a count of open vulnerabilities. It applied no state filter, so it also counted dismissed and resolved findings.

The Security configuration page uses this value for the "N open vulnerabilities" row on each tracked ref. That row therefore disagreed with the vulnerability report for the same ref.

A GitLab.com Ultimate customer reported three different counts for one project. See #628936 for the full report. The counts were:

Surface Value What it actually counted
Security configuration, master row 36 Every finding associated with master, any state
Vulnerability report, Tracked ref = master 2 Associated with master, open states only
Vulnerability report, All tracked refs 37 Open states, no ref predicate

Verified on gitlab-production-sec for that project:

  • 36 findings hold a master ref association.
  • 2 of those are open. 34 are dismissed or resolved.
  • 35 more open findings hold no ref association, because they predate the ref's trackedAt.
  • The true open total is 37.

The two totals share only 2 findings. They land on adjacent integers by coincidence. This made the defect look like an off-by-one error and cost diagnosis time.

What this MR changes

  1. vulnerabilitiesCount now filters to Vulnerability::ACTIVE_STATES, which is detected and confirmed. The value now matches its own description and its UI label.
  2. A new field totalVulnerabilitiesCount counts findings in every state.

The untrack confirmation modal also used vulnerabilitiesCount. It warns the user how many vulnerabilities removal affects. Removal affects every state, not only open ones, so that modal needs the total. An open-only count would understate the data loss.

The frontend does not change in this MR. Danger flags combined GraphQL backend and frontend changes as a rolling-deploy risk, because the frontend can request a field before the backend serves it everywhere. The modal moves to the new field in !255595 (closed), which targets this branch.

Reviewer notes

The diff is 4 files, +83 -11. Two of those files are generated, so the hand-written change is 73 lines:

File Lines Hand-written
ee/app/graphql/types/security/tracked_ref_type.rb 19 yes
ee/spec/graphql/types/security/tracked_ref_type_spec.rb 54 yes
public/-/graphql/introspection_result.json 18 no, rake gitlab:graphql:generate_all_introspection_schemas
doc/api/graphql/reference/_index.md 3 no, rake gitlab:graphql:compile_docs

The /public/ codeowner rule fires only on the generated introspection schema.

Testing

ee/spec/graphql/types/security/tracked_ref_type_spec.rb now covers:

  • vulnerabilitiesCount counts only detected and confirmed findings.
  • It excludes dismissed and resolved findings.
  • It returns zero when every finding on the ref is closed.
  • totalVulnerabilitiesCount counts findings in every state.
  • Both fields exclude other refs and other projects.

The rspec-ee fail-fast job ran that file and reported 11 examples and 0 failures.

How to set up and validate locally

  1. Track a ref on a project that has vulnerabilities.
  2. Dismiss or resolve some of the findings on that ref.
  3. Open Secure > Security configuration > Vulnerability management.
  4. Confirm the ref row counts only the findings that are still open.
  5. Confirm the count agrees with the vulnerability report filtered to the same ref.
  • Closes #628936
  • Follow-up: !255595 (closed) moves the untrack modal to the new field
  • Parent epic: &20474
  • #558135 backfills the missing ref associations. That work is separate. This count was wrong independently of the backfill.
Edited by Gregory Havenga

Merge request reports

Loading
Loading