Watermarking an ID: what actually leaves your device

Before sending a copy of your ID to a letting agency, stamp it: rental file, Agence Martin, 11/07/2026. France ships an official tool for exactly that, filigrane.beta.gouv.fr. It works. It also uploads your document.

It uploads

The site says so, right above the button:

The FiligraneFacile homepage, whose info box states that original files are deleted from their servers after generation

Les fichiers originaux seront effacés de nos serveurs après la génération du fichier filigrané.

“Deleted from our servers” implies they arrive there first. The network confirms it:

POST https://api.filigrane.beta.gouv.fr/api/document/files
content-type: multipart/form-data

The raw file, still unmarked, is processed server-side (Apache PDFBox on Scalingo) and returned by UUID.

The service is legitimate: SecNumCloud-certified, files deleted after download. But the order of operations is wrong. The document you were trying to protect sits on someone else’s machine before it gets the mark that protects it. From there, its safety is a policy, not a property.

The browser can do it

Render each page to a canvas, stamp the text, flatten it into the pixels, reassemble the PDF. None of that needs a server. So I rebuilt the tool that way: filigrane-local.fr (source).

Filigrane Local watermarking a test ID document, 100% local: preview and download button ready

Same document, same result. The network tab during watermarking:

GET /pdfjs/pdf.worker.min.mjs (same origin)
GET blob:... (in-memory preview)

Nothing remote. A connect-src 'self' policy makes an upload impossible even if the code tried one, and the page keeps working offline.

You have no reason to trust my deployment either. It is a static export: bun run build, then serve out/ from wherever you like (source).

Watermark the copy before you send it. Just don’t send it to get it watermarked.