Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Security model

flootypst executes Typst code supplied by the client. The threat model assumes the template author is untrusted.

What the compiler can and cannot do

CapabilityStatus
Read files inside the request bundleallowed
Read host filesystem (/etc, etc.)denied — virtual World
Import @preview/... packagesdenied — package resolver rejects everything
Network access during compilenone — compiler runs in a sandboxed child without it
Outlive the requestdenied — PR_SET_PDEATHSIG, kill_on_drop, SIGKILL on timeout

The Typst compiler runs in a child process (flootypst worker) so it can be hard-killed on timeout and so a runaway template cannot pin a parent thread.

SSRF protection (URL mode)

The URL-mode endpoint fetches caller-supplied URLs. Defenses:

  1. HTTPS-only by default. Non-HTTPS schemes are rejected at the URL-validation step (require_https=true).
  2. Custom DNS resolver. Resolution happens inside flootypst; any result that is loopback, private, link-local, multicast, broadcast, IPv6 ULA / link-local, the GCE/EC2 metadata IP 169.254.169.254, carrier-grade NAT, or reserved is dropped. If the entire resolution set is unsafe, the request is refused at connect time. This closes the typical DNS-rebinding window.
  3. Optional host allowlist. FLOOTYPST_HOST_ALLOWLIST accepts a comma-separated list of patterns. *.googleapis.com is supported. When set, any URL whose host doesn’t match is rejected before DNS is even attempted.
  4. No redirect following. A 3xx from an allowed host cannot bounce the request to a forbidden one.
  5. Size caps. Fetched bodies are streamed and aborted when they exceed FLOOTYPST_MAX_FETCH_BYTES.

A typical production config locks the allowlist down to your storage host(s):

FLOOTYPST_HOST_ALLOWLIST=storage.googleapis.com

Resource limits

LimitEnv varDefaultWhat happens on hit
Multipart body sizeFLOOTYPST_MAX_BODY_BYTES32 MiB413
Per-URL fetch sizeFLOOTYPST_MAX_FETCH_BYTES32 MiB400 (“too large”)
Output PDF sizeFLOOTYPST_MAX_OUTPUT_BYTES64 MiB413
Compile timeFLOOTYPST_COMPILE_TIMEOUT_SECS10 s408 (worker SIGKILLed)
Fetch timeFLOOTYPST_FETCH_TIMEOUT_SECS15 s408
Upload timeFLOOTYPST_UPLOAD_TIMEOUT_SECS30 s408
Concurrent compilesFLOOTYPST_MAX_CONCURRENT_COMPILEShost CPU count503

What is not included

  • No auth on the API itself. flootypst is meant to sit behind your own gateway / mTLS / API-key layer.
  • No rate limiting beyond the concurrency cap. Rate-limit upstream.
  • No audit log of which templates rendered what. The service is stateless.