Build proof of concept for Project PDF export of security reports

Goal

This issue tracks building a POC PDF export.

Design issue https://gitlab.com/gitlab-org/gitlab/-/issues/425327+

  1. Determine PDF generator
  2. Generate PDF with components listed below

Initial scope for this proof of concept

  1. Page 1
    1. Severities over time (from security dashboard)
  2. Page 2
    1. Severity counts (from security report)
    2. Vulnerability list (from vulnerability report)

POC Outcomes

  1. Outcomes

    1. Why decided to go with Prawn:
      • Pure Ruby solution - no system dependencies required
      • Production-ready immediately - can be deployed without infrastructure changes
      • Works consistently across all GitLab deployment types (SaaS, self-managed, dedicated)
      • No additional security surface area from system dependencies
      • Learning curve offset by simplified deployment and maintenance
      • POC demonstrates high fidelity to designs using only built-in capabilities
    2. What is required to include Prawn in GitLab?
      • Ruby dependency review
      • Performance review for large PDF generation
      • No infrastructure or system dependency reviews needed
    3. License and Legal considerations:
      • Prawn uses the GPL Prawn::Core and MIT license for Prawn itself
      • Need legal review to confirm compatibility with both SaaS and self-managed
  2. Identified limitations

    • Learning curve for Prawn's DSL (though POC shows it's manageable)
    • Upfront time cost of building PDF components from scratch
    • Need to implement visual regression testing strategy
  3. Other questions

    • Delivery mechanism: Consider both download and email delivery options
    • Performance: Need to test with large vulnerability datasets
    • APIs: Evaluate reusing existing vulnerability export endpoints vs new PDF-specific endpoints
    • Testing: Implement visual diff testing for PDF components
  4. Next steps - definition and refinement Implementation issues for:

    1. Legal review of Prawn licensing (#524059 - closed) • Michael Becker • 18.0 • On track
    2. PDF base implementation (#524055 - closed)
      • Set up Prawn integration
      • Define base PDF components (header, footer, etc)
      • Establish testing strategy
    3. Project level "Vulnerabilities Over Time" module (#524056 - closed)
      • Implement time-series visualization
      • Add severity filtering
    4. Group level "Vulnerabilities Over Time" module (#524057 - closed)
      • Implement count boxes with styling
    5. Update `vulnerability_export` API to accept `re... (#524058 - closed)
      • Implement table
    6. Feature flag implementation

Alternative Solutions Considered

for historical context

notes on alternatives
  1. Headless Browser (e.g., Puppeteer, Grover)

    • Pros:
      • Could reuse existing frontend components
      • Familiar HTML/CSS styling
    • Cons:
      • Requires system-level dependencies (browsers, drivers)
      • Complex deployment across different environments
      • Additional security surface area
      • Performance concerns with browser initialization
      • High operational maintenance
  2. System PDF Tools (e.g., wkhtmltopdf, weasyprint)

    • Pros:
      • Mature tools with broad feature set
      • HTML/CSS based workflow
    • Cons:
      • System-level dependencies
      • Version management across deployments
      • Security updates needed for system tools
      • Installation/configuration varies by platform
  3. Commercial PDF Services (e.g., DocRaptor, PrinceXML)

    • not considered
  4. JavaScript PDF Libraries (e.g., PDFKit)

    • Pros:
      • Pure JavaScript solution
      • Good community support
    • Cons:
      • Would require Node.js service
      • Additional infrastructure complexity
      • Cross-cutting concerns with Ruby backend
Edited by Michael Becker