Expose `has_ai_resolution` filter via GraphQL
What does this MR do and why?
Context
We need to be able to filter vulnerabilities on whether they have the "Resolve with Duo" button enabled.
This button is enabled if a finding's CWE value is included in this
hard-coded list of CWE values.
In previous MRs we:
- Added a new column to support this filter 1
- Began populating this column for new rows 2
- Added a batched background migration to backfill the new column 3
This MR
The database work isn't done yet as the backfill is still running and the indexes are not built yet 4.
However, we can expose graphql fields with FFs according to the docs:
This will unblock the frontend team from building and testing their code, as well as help us solidify the API contract.
SQL
Group level query
SELECT
"vulnerability_reads"."id",
"vulnerability_reads"."vulnerability_id",
"vulnerability_reads"."project_id",
"vulnerability_reads"."scanner_id",
"vulnerability_reads"."report_type",
"vulnerability_reads"."severity",
"vulnerability_reads"."state",
"vulnerability_reads"."has_issues",
"vulnerability_reads"."resolved_on_default_branch",
"vulnerability_reads"."uuid",
"vulnerability_reads"."location_image",
"vulnerability_reads"."cluster_agent_id",
"vulnerability_reads"."casted_cluster_agent_id",
"vulnerability_reads"."dismissal_reason",
"vulnerability_reads"."has_merge_request",
"vulnerability_reads"."has_remediations",
"vulnerability_reads"."owasp_top_10",
"vulnerability_reads"."traversal_ids",
"vulnerability_reads"."archived",
"vulnerability_reads"."identifier_names",
"vulnerability_reads"."has_vulnerability_resolution"
FROM
"vulnerability_reads"
WHERE
"vulnerability_reads"."traversal_ids" >= '{9970}'
AND "vulnerability_reads"."traversal_ids" < '{9971}'
AND "vulnerability_reads"."archived" = FALSE
AND "vulnerability_reads"."report_type" IN (6, 2, 5, 3, 1, 0, 4, 99)
AND "vulnerability_reads"."severity" IN (1, 2, 4, 5, 6, 7)
AND "vulnerability_reads"."state" IN (1, 4)
AND "vulnerability_reads"."resolved_on_default_branch" = FALSE
AND "vulnerability_reads"."has_vulnerability_resolution" = TRUE
ORDER BY
"vulnerability_reads"."severity" DESC,
"vulnerability_reads"."traversal_ids" DESC,
"vulnerability_reads"."vulnerability_id" DESC
LIMIT 21
- without new index: https://console.postgres.ai/gitlab/gitlab-production-main/sessions/31762/commands/98341|
- with new index: https://postgres.ai/console/gitlab/gitlab-production-main/sessions/31762/commands/98377
Project level query
SELECT
"vulnerability_reads"."id",
"vulnerability_reads"."vulnerability_id",
"vulnerability_reads"."project_id",
"vulnerability_reads"."scanner_id",
"vulnerability_reads"."report_type",
"vulnerability_reads"."severity",
"vulnerability_reads"."state",
"vulnerability_reads"."has_issues",
"vulnerability_reads"."resolved_on_default_branch",
"vulnerability_reads"."uuid",
"vulnerability_reads"."location_image",
"vulnerability_reads"."cluster_agent_id",
"vulnerability_reads"."casted_cluster_agent_id",
"vulnerability_reads"."dismissal_reason",
"vulnerability_reads"."has_merge_request",
"vulnerability_reads"."has_remediations",
"vulnerability_reads"."owasp_top_10",
"vulnerability_reads"."traversal_ids",
"vulnerability_reads"."archived",
"vulnerability_reads"."identifier_names",
"vulnerability_reads"."has_vulnerability_resolution"
FROM
"vulnerability_reads"
WHERE
"vulnerability_reads"."project_id" = 278964
AND "vulnerability_reads"."report_type" IN (6, 2, 5, 3, 1, 0, 4, 99)
AND "vulnerability_reads"."state" IN (1, 4)
AND "vulnerability_reads"."resolved_on_default_branch" = FALSE
AND "vulnerability_reads"."has_vulnerability_resolution" = TRUE
ORDER BY
"vulnerability_reads"."severity" DESC,
"vulnerability_reads"."vulnerability_id" DESC
LIMIT 21
- without new index: https://postgres.ai/console/gitlab/gitlab-production-main/sessions/31762/commands/98357
- with new index: https://postgres.ai/console/gitlab/gitlab-production-main/sessions/31762/commands/98372
MR acceptance checklist
Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
How to set up and validate locally
You can query graphql locally using http://gdk.test:3000//-/graphql-explorer
example query
query groupVulnerabilities($fullPath: ID!, $before: String, $after: String, $first: Int = 20, $last: Int, $projectId: [ID!], $severity: [VulnerabilitySeverity!], $reportType: [VulnerabilityReportType!], $scanner: [String!], $scannerId: [VulnerabilitiesScannerID!], $state: [VulnerabilityState!], $dismissalReason: [VulnerabilityDismissalReason!], $sort: VulnerabilitySort, $hasIssues: Boolean, $hasResolution: Boolean, $hasMergeRequest: Boolean, $hasRemediations: Boolean, $vetEnabled: Boolean = false, $clusterAgentId: [ClustersAgentID!], $owaspTopTen: [VulnerabilityOwaspTop10!]) {
group(fullPath: $fullPath) {
id
vulnerabilities(
before: $before
after: $after
first: $first
last: $last
severity: $severity
reportType: $reportType
scanner: $scanner
scannerId: $scannerId
state: $state
dismissalReason: $dismissalReason
projectId: $projectId
sort: $sort
hasIssues: $hasIssues
hasAiResolution: false
hasResolution: $hasResolution
hasMergeRequest: $hasMergeRequest
hasRemediations: $hasRemediations
clusterAgentId: $clusterAgentId
owaspTopTen: $owaspTopTen
) {
nodes {
...VulnerabilityFragment
__typename
}
pageInfo {
...PageInfo
__typename
}
__typename
}
__typename
}
}
fragment VulnerabilityFragment on Vulnerability {
id
title
state
severity
detectedAt
dismissalReason
vulnerabilityPath
resolvedOnDefaultBranch
userNotesCount
falsePositive @include(if: $vetEnabled)
hasRemediations
mergeRequest {
id
webUrl
state
iid
__typename
}
identifiers {
externalType
name
}
project {
id
nameWithNamespace
__typename
}
reportType
scanner {
id
vendor
__typename
}
__typename
}
fragment PageInfo on PageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
__typename
}
variables:
{
"dismissalReason": [],
"first": 20,
"fullPath": "gitlab-org",
"hasResolution": false,
"last": null,
"reportType": [
"API_FUZZING",
"CONTAINER_SCANNING",
"COVERAGE_FUZZING",
"DAST",
"DEPENDENCY_SCANNING",
"SAST",
"SECRET_DETECTION",
"GENERIC"
],
"sort": "severity_desc",
"state": [
"DETECTED",
"CONFIRMED"
],
"vetEnabled": true
}
Changelog: Added
EE: true
Resolves: #490323 (closed)
Epic: &15036 (closed)
-
Add `has_vulnerability_resolution` column to `v... (!165548 - merged) • Michael Becker • 17.5 ↩
-
Begin populating the `has_vulnerability_resolut... (!165952 - merged) • Michael Becker • 17.5 ↩
-
Backfill for `vulnerability_reads.has_vulnerabi... (!166110 - merged) • Michael Becker • 17.5 ↩
-
The index addition was being pushed off due to the difficulty of testing an index in database lab until the backfill is complete. This thread has more discussion. We ended up adding an index migration to this MR after the discussion in this thread ↩