Extend GraphQL's vulnerabilities query
What we have today
The groupthreat insights owns 4 Dashboards. The Project Level Security Dashboard, the Group Level Security Dashboard, the Security Center and the Pipeline Security Dashboard. Each of these dashboards display a list of vulnerabilities which can be fetched using GraphQL. Below is a table that demonstrates which query is used to fetch the vulnerabilities for the related dashboard:
| Dashboard | Query Name |
|---|---|
| Security Center | vulnerabilities |
| Group Level Security Dashboard | group.vulnerabilities |
| Project Level Security Dashboard | project.vulnerabilities |
| Pipeline Security Dashboard | project.pipeline.securityReportFindings |
Problem
This creates an additional complexity in the frontend while fetching the vulnerabilities / findings. Technically speaking, we re-use the ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_list.vue component in order to display the vulnerabilities/findings for each dashboard and we have a wrapper component which creates the query for the related dashboard.
Proposal
I'm going to suggest to deprecate all these queries except the vulnerabilities query and extend it by allowing it to receive the following arguments:
| argument | type | default value | description |
|---|---|---|---|
projectId |
[ID!] |
[] |
An array of project ids. |
groupId or groupFullPath
|
[ID!] |
[] |
An array of group ids or full paths depending on which one we want use. Our UI is not designed to display multiple groups at the same time, but API-wise it could be beneficial for the user. |
isSecurityCenter |
Boolean |
false |
Whether we're fetching the vulnerabilities for the security center (user level security dashboard) |
pipelineId |
[ID!] |
[] |
Similar to groupId, we do not display vulnerabilities for multiple pipelines at the same time, but this could still be beneficial for the user. |
So this is what the query would look like to fetch the vulnerabilities:
#import "~/graphql_shared/fragments/pageInfoCursorsOnly.fragment.graphql"
#import "../fragments/vulnerability.fragment.graphql"
query vulnerabilities(
$after: String
$first: Int
$projectId: [ID!]
$severity: [VulnerabilitySeverity!]
$reportType: [VulnerabilityReportType!]
$scanner: [String!]
$scannerId: [VulnerabilitiesScannerID!]
$state: [VulnerabilityState!]
$sort: VulnerabilitySort
$hasIssues: Boolean
$hasResolution: Boolean
$groupId: [!ID]
$projectId: [!ID]
$pipelineId: [!ID]
$isSecurityCenter: Boolean
) {
vulnerabilities(
after: $after
first: $first
severity: $severity
reportType: $reportType
state: $state
projectId: $projectId
scanner: $scanner
scannerId: $scannerId
sort: $sort
hasIssues: $hasIssues
hasResolution: $hasResolution
groupId: $groupId # part of the proposal
projectId: $projectId # part of the proposal
pipelineId: $pipelineId # part of the proposal
isSecurityCenter: $isSecurityCenter # part of the proposal
) {
nodes {
...Vulnerability
}
pageInfo {
...PageInfo
}
}
}
So for instance providing the $projectId: ["/root/security-reports"] argument would return the vulnerabilities for this project, but omitting the $projectId and providing isSecurityCenter: true would return the security center vulnerabilities.
The only unknown in this proposal is whether we can provide the findings in the same query or not. A Finding and a Vulnerability are different entities in the backend even though for the end-user and the frontend they are very similar. If we can provide the findings in the same query, it would then remove many complexities in the frontend as we would be able to treat them alike. If this is technically not possible, or hard to implement, we can always reiterate on this proposal and start from providing a single query for the 3 dashboards.