Privacy-First AI NDA Analysis: How We Built NDAShield on Cloudflare and Next.js
Zero-footprint NDA processing, Burn Score prompt engineering, and the EU hosting decisions behind NDAShield — a solo-founder legaltech SaaS on Cloudflare Workers.
Building an AI wrapper is straightforward. Building one that processes confidential, legally binding contracts — while staying GDPR-compliant and running at the edge — is a different problem entirely.
NDAShield scans NDAs for risky clauses, assigns a 0–100 Burn Score, and generates clause-level redlines plus negotiation-ready email snippets. This post is the expanded technical story behind it: the architecture choices, the zero-footprint pipeline, the prompt engineering discipline that makes it accurate, and the production failures that reshaped the stack.
This article is the canonical expanded version of the Dev.to build post. If you came from there, read on — this version goes deeper on the parts that had to survive production.
The constraint that shaped everything
NDAs are confidential by definition. Uploading one to a general-purpose AI chatbot leaks the document to a training pipeline you do not control, from a server jurisdiction you may never verify. For a GDPR-regulated product targeting EU founders, that is not a policy risk — it is a product-ending one.
The design constraint was simple: no raw text from the uploaded document should touch persistent storage. Not a database. Not a cache. Not a log file. The extracted text lives in memory for the duration of the request and nowhere else.
That one constraint dictated the entire architecture.
Stack overview
The production stack is intentionally minimal:
| Layer | Technology | Why |
|---|---|---|
| Framework | Next.js (App Router) | SSR + SSG, edge-compatible via OpenNext |
| Edge infrastructure | Cloudflare Workers + Pages | Global CDN, no cold starts, EU routing |
| Auth | Clerk | Managed sessions, webhook-based provisioning |
| Database | Supabase + Drizzle | Postgres for user records, credits, report metadata only |
| AI primary | Google Gemini | Long context window, speed, EU data toggles |
| AI fallback | OpenAI | Automated failover when Gemini quota hits |
| PDF/DOCX extract | unpdf + mammoth | In-Worker, no Lambda |
No queues, no object storage, no background jobs. The stateless edge model is the privacy model.
Zero-footprint pipeline
When a user uploads a PDF or DOCX, the document goes through this sequence:
- Client preflight — file type and size checked in the browser before upload begins
- Server extract — Worker receives the binary, extracts plain text using unpdf (PDF) or mammoth (DOCX) in-process
- LLM call — extracted text sent to Gemini or OpenAI with data-sharing and training toggles explicitly disabled via API params
- Structured response — AI returns JSON with clause findings, verbatim quotes, risk levels, redlines
- Report persist — only the structured JSON output is stored in Supabase, not the source text
- Memory cleared — the upload binary and extracted text are never written to disk or database
The uploaded document itself never reaches a database column. What Supabase stores is the analysis result: clause classifications, risk scores, redlines — all derivable from and referencing the original, which stays in the user's hands.
For a deeper look at the GDPR architecture, see EU GDPR and NDA Review: What Privacy-First Analysis Actually Means.

Prompt engineering for legal accuracy
Generic LLM prompts produce dangerous summaries. Asking a model to "review this NDA" returns something like: "This is a standard mutual NDA protecting both parties." That statement is almost always wrong, often in legally consequential ways.
NDAShield enforces three structural constraints on every analysis:
1. Verbatim verification. The model is forbidden from classifying a clause as risky unless it can output the exact text from the document that proves it. No paraphrase, no inference. This eliminates hallucinated clause content — one of the most common failure modes in legal AI.
2. Quantified risk matrix. Every clause is scored against a rubric: non-compete scope and duration, IP assignment breadth, survival period, jurisdiction, governing law, indemnity caps. The aggregate produces the Burn Score — a 0–100 integer that correlates with how aggressively the agreement favours the disclosing party.
3. Actionable redlines. The model is required to produce a counter-proposal for every flagged clause — not just a description of the problem. The redline is formatted as a drop-in replacement, plus a negotiation email snippet the recipient can copy and send.
The result is a report that gives you something to do with the risk, not just a list of things to worry about.

For more on how the scoring works, see Burn Score Explained: How NDAShield Rates NDA Risk.
What broke in production
The Cloudflare Workers free tier gives you approximately 10ms of CPU time per request. A full NDA analysis involves: PDF extraction, prompt assembly (several kilobytes of structured instructions), an LLM round trip (excluded from CPU budget, but the response parsing is not), and JSON serialisation.
On the first deploy, the Worker exceeded its CPU budget on documents longer than four pages. The failure mode was silent: Cloudflare returned a 1102 error to the browser, which showed up as a blank page rather than an error message.
Three changes resolved it:
- Bundle guard script — a pre-deploy check that fails the build if any runtime OG image route, server PDF extractor with the wrong env flag, or next/og import appears in the Worker bundle. These are the common additions that re-introduce CPU-intensive work.
- Static OG images — all OpenGraph images are generated at build time and served as static PNGs. No runtime image generation.
- Lazy extraction — the DOCX extractor (mammoth) is only imported in the Worker when the uploaded file is actually a DOCX, not on every request.
The Worker now processes comfortably within budget on typical NDAs. Unusually long agreements (20+ pages) are flagged with a warning to the user before processing begins.
Architecture decisions I would repeat
Edge-first is the right choice for legal documents. When the computation runs in a Cloudflare data centre rather than us-east-1, the EU hosting claim is verifiable — not a marketing statement.
Drizzle over raw SQL. Schema migrations as TypeScript, typed query results, and a build-time check that the DB schema matches the application model. For a solo founder, this prevents the silent data drift that eventually breaks queries at 2am.
Clerk for auth. Managed sessions, social OAuth, email magic links, and MFA in the dashboard — none of which I wrote. The tradeoff is a service dependency; the benefit is not having a session management bug in a legaltech product.
Gemini as primary, OpenAI as fallback. Gemini's context window handles very long NDAs without chunking. OpenAI remains available when Gemini quota limits hit. The failover is automatic.
What I would do differently
Static generation for blog and marketing pages. Most of the marketing shell currently resolves auth on every request even when the output is identical for signed-out users. Extracting those pages to pure SSG would cut edge CPU usage significantly.
Rate limiting at the edge. The current approach uses Supabase-backed credit checks per-request. Cloudflare's rate limiting primitives could enforce request-level throttling before the Worker even processes the body — an improvement queued for the next iteration.
Production result
NDAShield launched on Product Hunt and has been processing NDA reviews since. The zero-footprint claim holds: no user document text appears in Supabase. The Burn Score has proven accurate enough that users treat it as a primary decision signal rather than a novelty.
If you are building AI features on sensitive documents — legal, medical, financial — the constraints described here apply to you too. The in-memory pipeline is not complicated to implement. The hard part is treating it as a non-negotiable constraint from the start, before you build the feature that stores "just the summary" in a database somewhere.
Try the tool at nda-shield.com or read the complete NDA review guide for the clause-level detail behind the Burn Score.
*Not legal advice. NDAShield is an informational tool. Consult qualified counsel for binding legal decisions.*