boxkite
← All posts
Data & Documents

Processing Every Customer's Contracts and Invoices Without Ever Mixing Them

Every file a legal-tech or accounts-payable product processes is a different paying customer's confidential material — a contract with terms nobody else should see, an invoice with vendor pricing, a scanned filing that shouldn't exist outside one company's own records. An agent that reads, OCRs, and extracts structured data from that material is doing genuinely useful work. It's also handling someone else's secrets on every single call.

Every upload is someone else's confidential filing

A document-processing SaaS doesn't get to treat this as an edge case — it's the normal request. One customer's contract terms, another customer's vendor invoice, a third customer's scanned filing, all arriving concurrently, all needing the same extraction pipeline, none of which should be able to see or affect any of the others.

One pod per session, not just logical separation

boxkite gives each processing session its own Kubernetes pod — non-root, every Linux capability dropped, a read-only root filesystem where applicable. Tenant A's contract and tenant B's invoice aren't sharing a container with an authorization check between them; they're physically separate workloads, the same separation Kubernetes already enforces between any two unrelated pods on the cluster.

Three uploads, three isolated pods, one clean result each

Customer Acontract.pdfPod — session for Customer ATesseract OCR · poppler · python-docx/pptx/pdfnetwork-dark by defaultpresent_filesCustomer Binvoice.pdfPod — session for Customer BTesseract OCR · poppler · python-docx/pptx/pdfnetwork-dark by defaultpresent_filesCustomer Cscanned filingPod — session for Customer CTesseract OCR · poppler · python-docx/pptx/pdfnetwork-dark by defaultpresent_filesYour SaaS productclean, extracted resultper customer, never mixed
Each customer's upload gets its own pod with the full document stack pre-installed. Nothing crosses between sessions, and nothing has a path to the open internet unless explicitly configured.

Why network-dark matters for a malicious PDF

Document processing means handling files you didn't create, from customers you can't fully vet, and a scanned filing or crafted PDF is a plausible vector for prompt injection against whatever agent is interpreting the extraction results. With network access denied by default, even a fully successful attempt to manipulate the agent's behavior still can't exfiltrate what it extracted or reach anywhere outside the pod — there's simply no network path out unless one has been explicitly configured for that session.

The stack doing the actual work

The sandbox image ships Tesseract OCR and poppler for scanned and PDF content, plus the python-docx/pptx/pdf stack and pandasfor turning what's extracted into structured data — all pre-installed, with no runtime installs required and none possible anyway under a network-dark default. The SaaS doesn't maintain its own execution image for this; it gets one that already has the document tooling in it.

Handing back a clean result

Once extraction is done, present_fileshands the result back to the calling product directly, rather than leaving output buried in the sandbox's filesystem for a separate retrieval step. The session ends, the pod goes away, and nothing about that customer's contract persists anywhere it shouldn't.

The next security questionnaire

Legal-tech and accounts-payable customers ask pointed questions about tenant isolation, and "every upload is processed in its own pod, non-root, capabilities dropped, no network egress by default" is a structural answer — enforced by Kubernetes, not by application code the SaaS wrote and has to keep proving is correct.