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
5.4 KiB
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
downloadFromin v1.
Required Request Controls
- Send HTML as a server-generated
index.htmlmultipart 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.htmlplus optional assets. - Gotenberg exposes
/healthfor liveness/monitoring. - Gotenberg has timeout, body limit, correlation id, Chromium concurrency, queue, file access, and outbound URL filtering settings that must be set deliberately.