πŸ’‘ Inspiration

On 27 March, the European Commission confirmed a breach. 350 gigabytes. Confidential documents. Contracts. Cloud infrastructure. The files were on a server. That was enough.

In Switzerland, a data breach doesn't just fine your company. It fines you up to CHF 250,000, personally.

Bounds has no server. Nothing to breach.

πŸ”’ GoCalma's challenge | AI-Powered Privacy Redaction: Own Your Data


Why Bounds

  • Data that stays in bounds β€” nothing crosses the boundary of your device. The whole product promise is that your files never go "out of bounds" to a server.
  • Setting bounds on what's visible β€” redaction is literally drawing a box (a bound) around sensitive information and limiting what can be seen.

What it does

  • ✈️ Fully offline β€” works in airplane mode after first load
  • 🧠 Hybrid AI detection β€” multilingual BERT NER + 40+ regex patterns, all local
  • πŸ” Auto-detects PII β€” names, addresses, IBANs, SSNs, emails, phones, passports, DOB, health data, credit cards
  • 🌍 8 UI + document languages β€” EN, DE, FR, IT, ES, PT, NL, PL
  • πŸ“· OCR for scanned PDFs β€” Tesseract.js with spatial word reconstruction for form layouts
  • πŸ‘€ Face detection β€” universal browser face detection with TinyFaceDetector fallback
  • ⬛ True redaction β€” pages rasterised to image, original text layer removed entirely
  • πŸ—οΈ Reversible encryption β€” AES-256-GCM vault + .key file, restore original values any time
  • πŸ“‹ Audit trail β€” timestamped JSON report, no document content included
  • πŸ“¦ Batch processing β€” drop multiple PDFs, processed sequentially with default options

GenAI Integration

The Problem: Organisations want to use ChatGPT, Claude, or custom LLMs to analyse documents but sending unredacted files violates GDPR/HIPAA and exposes data to training pipelines.

The Solution: Bounds sits upstream of GenAI workflows:

Sensitive PDF β†’ Bounds (local redaction) β†’ Redacted PDF β†’ Safe to send to: β”œβ”€ AI provider for summarisation β”œβ”€ Custom RAG pipelines └─ Your platform

Generative AI components running entirely in the browser:

  • BERT multilingual NER (430MB ONNX) β€” discriminative AI for named entity detection across 104 languages
  • LaMini-Flan-T5-77M (77MB) β€” generative AI produces plain-language privacy risk summaries: "This document contains 3 names, 2 addresses and 1 IBAN. Risk level: High."

πŸ—οΈ How I Built It

The entire pipeline runs in WebAssembly inside the browser. No backend, no server, no environment variables.

Architecture:

  • @xenova/transformers β€” quantised multilingual BERT NER (~430MB ONNX) in Web Worker, cached in IndexedDB after first download
  • tesseract.js β€” OCR for scanned PDFs with spatial row reconstruction to handle two-column form layouts
  • pdfjs-dist β€” text extraction with precise bounding boxes
  • pdf-lib β€” rasterises redacted pages to PNG, rebuilds clean PDF with no text layer
  • Web Crypto API β€” AES-256-GCM reversible encryption vault, no library needed
  • React 18 + Tailwind + Vite β€” 4-step wizard UI
  • Deployed as fully static site on Vercel

Hybrid detection: regex runs in parallel with NER for structured identifiers (IBANs, credit cards, passports, phone numbers) with deduplication between layers. 40+ regex rules with per-pattern confidence thresholds and label-context lookbehind for form-style documents.


🚧 Challenges I Ran Into

  • WASM + SharedArrayBuffer: Requires both Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp headers. Easy to miss, hard to debug when it fails silently.
  • Bounding box alignment: Mapping pdfjs extraction coordinates to pdf-lib render coordinates required careful calibration across different PDF structures.
  • OCR form layout: Two-column forms get read column-by-column by Tesseract, so "Emergency contact:" and "Jean Dubois" end up 20 lines apart in the text stream, breaking label-context regex. Fixed by reconstructing reading order from word bounding box positions.
  • Progressive loading: Fitting a 430MB model into a UX that doesn't feel broken required progressive loading states, a network request transparency panel, and IndexedDB caching so the download only happens once.
  • Face detection cross-browser: Chrome's Shape Detection API requires an experimental flag. Replaced with a universal fallback using TinyFaceDetector via ONNX, so face blurring works in all browsers without flags.

Built With

  • api
  • crypto
  • pdf-lib
  • pdfjs-dist
  • react
  • tailwind
  • tesseract.js
  • vercel
  • vite
  • web
Share this project:

Updates

posted an update —

v2.0 is live at bounds.aqta.ai

Shipped since v1.0:

  • Generative AI risk summaries (LaMini-Flan-T5, fully local)
  • Face detection on scanned documents
  • Reversible redaction vault (AES-256-GCM, restore originals any time)
  • Batch processing, drop multiple PDFs at once
  • Chrome extension
  • 8 languages (EN, DE, FR, ES, IT, PT, NL, PL)
  • Audit trail export (timestamped JSON, no document content)
  • Works fully offline after first load-

Open DevTools β†’ Network tab. Zero outbound requests after initial load. Everything runs in your browser, BERT NER, OCR, crypto, PDF rendering.

Demo: youtu.be/-jConrg1GXo

Log in or sign up for Devpost to join the conversation.

Submission history