TenantAtlas/specs/378-management-report-pdf-v1/artifacts/spec378-gotenberg-security-controls.md
ahmido d43ebcb4ee feat(report): implement management report pdf v1 (#449)
Added PDF generation service for management reports as per Spec 378, including Gotenberg integration in docker-compose and configuration updates.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #449
2026-06-14 18:36:07 +00:00

5.4 KiB

Spec 378 Gotenberg Security Controls

Date: 2026-06-14 Decision: Gotenberg 8 Chromium is approved with controls as an internal production PDF rendering service for report-style documents.

These are required future implementation controls. This artifact does not add runtime config and does not claim that Gotenberg is already deployed in the repo.

Required Runtime Boundary

  • Gotenberg runs as a separate internal Docker service.
  • The Laravel app and queue containers do not install or execute Node, Puppeteer, Chrome, Chromium, or a browser binary for production PDF rendering.
  • Laravel accesses the service only through a narrow PdfRenderingGateway / PdfRendererClient.
  • The gateway exposes only server-generated HTML-to-PDF rendering required by report generators.
  • No user-provided URL rendering is allowed in Spec 378 v1.
  • No public port is exposed for the renderer in Sail or Dokploy.
  • The service is reachable only over the internal Docker/Dokploy network.

Required Image And Deployment Controls

  • Use a pinned Gotenberg 8 Chromium image version or immutable digest; never latest.
  • Prefer the Chromium-only Gotenberg 8 image variant for v1 unless office conversion is explicitly approved later.
  • Record the exact image tag/digest in the implementation PR.
  • Add a health check using Gotenberg /health.
  • Configure startup/readiness behavior so unavailable renderer state fails generation before artifact exposure.
  • Configure resource limits appropriate for PDF generation workers.
  • Configure request timeout (API_TIMEOUT) and Chromium startup timeout (CHROMIUM_START_TIMEOUT) explicitly.
  • Configure multipart request size limit (API_BODY_LIMIT) explicitly.
  • Configure Chromium queue/concurrency limits (CHROMIUM_MAX_QUEUE_SIZE, CHROMIUM_MAX_CONCURRENCY) explicitly.
  • Disable unused webhook behavior unless a future spec explicitly approves it.
  • Disable or do not use downloadFrom in v1.

Required Request Controls

  • Send HTML as a server-generated index.html multipart payload.
  • Send only local bundled assets alongside the HTML payload.
  • Reference assets by relative filename only.
  • Do not send signed URLs inside HTML.
  • Do not send access tokens, refresh tokens, client secrets, provider credentials, raw provider payloads, SQL errors, stack traces, serialized job context, or internal MSP-only notes inside HTML.
  • Do not render arbitrary operator-provided HTML.
  • Do not render arbitrary user-provided remote URLs.
  • Apply max HTML payload size, max asset size, and max PDF output size in the Laravel gateway before calling Gotenberg.
  • Add a correlation id / OperationRun id to request metadata, using the configured Gotenberg correlation header.

Required Network And File-Access Controls

  • Keep Gotenberg internal-only with no public listener.
  • No direct user-provided URL rendering in v1.
  • Deny or tightly restrict outbound URL access.
  • For Spec 378, default to no external outbound fetches: use bundled local assets only.
  • Set Chromium outbound restrictions to reject public and private external HTTP destinations unless a later approved asset host allow-list is introduced.
  • Do not enable file access beyond Gotenberg's per-request working directory defaults.
  • Keep Chromium file access from files disabled.
  • Do not mount application storage, secrets, .env, or host paths into the Gotenberg container.
  • If custom fonts are required later, use a dedicated reviewed font image or readonly font mount with no secrets.

Required Error And Audit Controls

  • Renderer unavailable must map to OperationRun failed/blocked with safe reason.
  • Renderer timeout must map to OperationRun failed/blocked with safe reason.
  • Renderer 400/503 responses must map to structured internal error classes.
  • Do not expose raw renderer errors to customers.
  • No ghost report: failed generation must not expose a ready artifact, stale download URL, or partially written PDF.
  • Renderer logs must not contain secrets because request HTML and metadata must be pre-sanitized.
  • Audit generation attempts and successful downloads with safe metadata only.
  • Log correlation id, source review/pack id, operation run id, profile, format, status, and safe renderer outcome.

Required Testing And Validation Controls

  • Unit coverage for renderer client request building and size-limit rejection.
  • Feature coverage for renderer unavailable, timeout, invalid payload, and successful artifact response mapping.
  • Feature coverage proving no ready artifact is exposed on renderer/storage failure.
  • Feature coverage proving denied generation never calls the renderer.
  • Browser/content smoke only after runtime service and generation flow are implemented.
  • Deployment validation must include health check behavior and queue worker failure handling.

Explicit Non-Approval

Gotenberg is approved as shared internal PDF rendering infrastructure for report-style documents.

This approval does not approve legal invoice generation, German B2B e-invoicing, XRechnung, ZUGFeRD/Factur-X, GoBD archival, tax calculation, invoice numbering, or billing compliance.

Source Notes

  • Gotenberg supports Docker and Docker Compose service use, with other services able to reach it on the compose network.
  • Gotenberg exposes a Chromium HTML-to-PDF route accepting index.html plus optional assets.
  • Gotenberg exposes /health for liveness/monitoring.
  • Gotenberg has timeout, body limit, correlation id, Chromium concurrency, queue, file access, and outbound URL filtering settings that must be set deliberately.