Update vulnerability_export API to accept report_data
What does this MR do and why?
Context
In a previous MR, we added a jsonb column to the
vulnerability_exports. This field is used to store data
assets from the frontend, to be used in report rendering.
This change introduces the first usage of the jsonb column. In this
instance, we are going to store an SVG that has been computed in the
frontend. Future usages may store json data blobs or some other data.
This change
Here, we are taking an SVG of the project-level "vulnerabilities over time" table, rendered in the web UI, as an asset to be rendered in the PDF report.
References
- thread where we discuss the structure of the parameter's hash
-
thread discussing the
jsonbschema structure - thread more discussion on the schema structure
Doc links
| Before | After |
|---|---|
| https://docs.gitlab.com/api/vulnerability_exports/ | https://docs.gitlab.com/upstream-review-mr-ee-193143/api/vulnerability_exports/ |
How to set up and validate locally
For the request body in this example, I am using a file:
// ./request_body.json
{
"send_email": false,
"export_format": "pdf",
"report_data": {
"project_vulnerabilities_over_time": null,
"not_in_schema": true,
"dashboard_type": "group",
"full_path": ""
}
}
-
Create the export
RESOURCE_ID=24 # some group or project id TOKEN=glpat-your-token curl --request POST \ --header "PRIVATE-TOKEN: $TOKEN" \ -H "Content-Type: application/json" \ -d @request_body.json \ "http://gdk.test:3000/api/v4/security/groups/$RESOURCE_ID/vulnerability_exports" -
You should see a response similiar to this:
{ "id": 73, "created_at": "2025-06-09T18:13:28.074Z", "project_id": null, "group_id": 24, "format": "pdf", "status": "created", "started_at": null, "finished_at": null, "send_email": false, "expires_at": null, "_links": { "self": "http://gdk.test:3000/api/v4/security/vulnerability_exports/73", "download": "http://gdk.test:3000/api/v4/security/vulnerability_exports/73/download" } } -
If you inspect the export record from the rails console, you should see the data that was passed in the request is in the db, but the request data that didn't match the schema was not saved:
export = Vulnerabilities::Export.last {#=> #<Vulnerabilities::Export:0x00007b39a940a6b0 id: 73, created_at: Mon, 09 Jun 2025 18:13:28.074990000 UTC +00:00, updated_at: Mon, 09 Jun 2025 18:13:28.074990000 UTC +00:00, started_at: nil, finished_at: nil, status: "created", file: nil, project_id: nil, author_id: 1, file_store: nil, format: "pdf", group_id: 24, organization_id: 1, expires_at: nil, send_email: false, export_data: {}, report_data: {"full_path"=>"", "dashboard_type"=>"group", "project_security_status"=>[], "group_vulnerabilities_over_time"=>nil, "project_vulnerabilities_over_time"=>nil} } -
Wait a bit then hit the download link from the response
- should be less than 20 seconds, but a busy gdk sidekiq queue has made it take minutes occasionally
- You should be able to download the pdf and get this blank pdf: gitlab-org_vulnerabilities_2025-06-09T1431.pdf
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
epic: Add PDF export of security reports (&16989 - closed)
Related to: #524058 (closed)
Changelog: changed
EE: true