Work · Secure AI

Document pipeline with anonymization for LLMs

PDF→Markdown tooling that strips sensitive data before cloud AI processing, so document-heavy workflows can use LLMs without treating privacy as an afterthought.

My role Designed and built the pre-cloud anonymization gate and conversion toolchain; set the rule that raw operational PDFs never hit the cloud LLM boundary.

Stack Python · Document / Tool / Pipeline · PyMuPDF · marker-pdf · AES-GCM vault · MCP tool descriptors

Context
Operations and delivery teams needed AI support on document-heavy work (specs, runbooks, vendor packs), but sending raw operational documents to cloud LLMs created unacceptable privacy exposure. Constraint: useful LLM output was allowed only after sensitive fields were removed. Stakeholders: IT/PMO, anyone handling documents with personal or operational secrets.
Intervention

Built pdfmd so CLI, GUI, and MCP descriptors share one pipeline: a Document in, a Document out, with anonymization as a tool in that pipeline.

Phase 1 — One document type

Core types are framework-free: Document (content, metadata, artifacts), Tool, Pipeline, Registry, Settings. Engines are tools — PyMuPDF, a hybrid OCR path, and marker-pdf — plus converters for EML, DOCX, PPTX, XLSX, EPUB, HTML, and images.

Phase 2 — Reversible anonymization

scan_pii and anonymize run before any cloud call. The vault is AES-GCM with scrypt, so redaction can be reversed locally. deanonymize is a separate tool. Pipeline.plan() is data; Pipeline.run() executes, and the GUI shows the plan first.

Phase 3 — Same pipeline, three fronts

CLI (pdfmd convert, anonymize, scan), a PySide6 drag-and-drop GUI, and MCP tool descriptors over the same Settings. Marker and the GUI are optional extras so the CLI still runs lean.

Risks & how they were handled
  • Missed PII → conservative patterns + human spot-checks on samples.
  • Over-redaction hurting usefulness → iterate patterns with real document classes.
  • Bypass temptation → make the gated path the easiest path (default tooling).
What I'd do differently
  • Add structured redaction reports (what was removed) as a first-class artifact earlier.
  • Separate “internal-only” vs “cloud-ok” document classes more explicitly in UX.
Outcome
Before: privacy risk blocked useful AI adoption on operational documents—no safe path meant LLM help was effectively offline for those files. After: a PDF→Markdown pipeline anonymizes sensitive fields before any cloud LLM step (typically a scripted pass of seconds to a couple of minutes per document once configured, est.), so document workflows can use LLMs with a clear pre-cloud privacy gate instead of a blanket ban.

System map

Source PDF

Anonymize first

PII / secrets out

Reversible vault

AES-GCM

Pipeline

Markdown out

PyMuPDF · marker

Cloud LLM last

after gate

What it does

Strips sensitive fields before any cloud call

Keeps a reversible vault when needed

Hands clean Markdown to the LLM

Privacy gate before the model — anonymize, then convert, then call the cloud.

What shipped

  • PDF→Markdown toolchain Turns source PDFs into clean Markdown for downstream AI — shared Tool/Pipeline for CLI, GUI, and MCP.
  • Pre-cloud anonymization PII and secrets leave the document before any cloud LLM step.
  • Reversible AES-GCM vault Sensitive values can be restored when the workflow needs them.

Stack Python PyMuPDF marker-pdf AES-GCM MCP

← FinOps reconciliation Next: Privacy-first kids apps →