A privacy product where the architecture is the promise.
Haven is a native desktop application — a Rust workspace wrapped in a Tauri shell with a React dashboard — that connects to your email, cloud storage, and local files, scans them on your own machine, and walks you through cleaning up what it finds. Detection runs in three escalating tiers, two of which never touch the network. The few bytes that do leave are bounded, logged on-device before they're sent, and verifiable by anyone with a packet sniffer.
Five surfaces, one trust boundary.
The whole product is five deployable surfaces. One of them — the desktop agent — holds all user content. The other four are deliberately designed so they couldn't hold it: a static marketing site, a static artifact CDN, a counters-only backoffice, and two GPU services that process bounded payloads in memory and forget them.
- Desktop agent — the product. Everything sensitive happens here: scanning, classification, the encrypted findings store, remediation, undo.
- Signed artifact CDN — three static nginx channels that only ever send: detection rules, ML model bytes, and update manifests, each Ed25519-signed before it leaves CI.
- Tier 3 inference — Haven-controlled GPU running an open-weights model behind an OpenAI-compatible API. Receives bounded excerpts, returns verdicts, retains nothing.
- Image safety — a second, Haven-owned GPU for the explicit-photo detector (on by default; turn it off per connector), built specifically so users' intimate photos are never processed by a third party.
- Backoffice — the operations plane. Accepts aggregate telemetry counters, tester feedback, and scrubbed error reports; serves the team an OTP-gated dashboard.
Boring where it should be, sharp where it counts.
The agent is systems software — Rust end to end, with ML inference embedded in-process. The supporting services are deliberately minimal: static file serving, one small Node app, and two GPU boxes running open-weights models Haven controls outright.
Three tiers. Two never touch the network.
Every message, file, and attachment flows through an escalating pipeline. Tier 1 is deterministic pattern matching. Tier 2 is a transformer running inside the app process. Only when both of those are genuinely uncertain — a low single-digit percentage of items — does a bounded excerpt cross the trust boundary to Tier 3 for a second opinion.
46 detectors, zero guesswork
- API keys & tokens — 35+ provider formats: AWS, GitHub, Stripe, OpenAI, Slack, Google, and more
- Financial — card numbers (Luhn-validated), ABA routing numbers, bank accounts
- Identity — SSNs, plaintext passwords, JWTs
- Tax documents — W-2, 1099, K-1, 1040
- Account takeover — rogue forwarding rules, suspicious mail filters
- Sharing posture — public links, domain-wide and stale external shares
Context, not just patterns
A fine-tuned DistilBERT runs inside the app via ONNX Runtime and reads what regex can't — classifying content into 17 sensitive categories:
Bounded, logged, forgotten
- Only Tier-2-flagged ambiguity ever reaches it — a ≤1,500-character excerpt, never the document
- Verdicts only: confirmed elevates, refuted drops the finding, insufficient changes nothing
- Nothing persisted server-side: no request logs, no caches, no cross-call state
- Never used to train anything, by anyone
- Every call appears in the on-device Network Activity log — excerpt hash, destination, size, latency
What leaves the device — exactly, and nothing else.
Most privacy products ask you to trust a policy. Haven's claim is structural: there is exactly one code path that can reach the network, it only accepts a fixed list of payload shapes, and it writes every outbound request to an on-device log before the bytes leave. A continuous CI lint fails the build if any other crate so much as links an HTTP client.
Raw message bodies & files
The full body or file is never uploaded — only a bounded, redacted excerpt of a flagged item ever crosses (see right).
OAuth tokens
Held in the OS keychain; sent only to the provider that issued them.
The values of your findings
Haven records that a password exists — not the password.
The encrypted findings store
SQLCipher database, key in your OS keychain.
Ask Haven questions
Parsed by an on-device grammar. No ML, no network.
Your inferred context profile
Computed locally to rank findings; stays local.
Aggregate telemetry counters
Daily rollups from a fixed slug vocabulary — free-form strings are unrepresentable in the schema.
Signed-manifest checks
"Is there a new rules pack / model / update?" — version metadata only.
Tier 3 excerpts
≤1,500 characters of a flagged item, one round-trip, discarded after the verdict.
Explicit-photo image checks
On by default (off per connector). Image attachments to Haven's own GPU, scored in memory, never written to disk.
Scrubbed crash reports
Panic events pass a scrubber that strips paths, locals, and anything matching Tier 1 patterns.
Tester feedback
What you typed in the feedback box — after the same scrubber.
One chokepoint, enforced by the compiler and CI
Where it all actually runs.
Five pieces of hardware, each with one job. The interesting choice: both GPU services run open-weights models on machines Haven controls — no third-party AI API ever sees user content, and the explicit-photo detector got its own dedicated box precisely because that content deserves the strongest possible custody.
SQLCipher store · ONNX in-process
Windows shipping · macOS in flight
vLLM · HAProxy · Caddy
zero-retention configuration
ShieldGemma 2 · 4B · FastAPI
bearer-gated · in-memory only
no-cache manifests
previous versions kept for rollback
better-sqlite3 · WAL
OTP-gated dashboard
Everything that changes the agent is signed.
Detection rules, ML models, and the application itself all ship through independent channels — and the agent refuses anything whose Ed25519 signature doesn't verify against keys compiled into the binary. A compromised CDN can't hurt users: a bad signature means the agent silently keeps what it has.
- App updates — the agent checks a signed manifest, downloads only when the SHA-256 matches, and respects a staged rollout percentage so a bad release reaches 5% of the fleet, not 100%.
- Rules packs — new detectors ship weekly without an app release. The pack carries its own minimum-agent-version gate, so old agents never load rules they can't run.
- Model bundles — Tier 2 classifier upgrades arrive the same way: signed manifest, per-file hashes, atomic activation, prior version kept for rollback.
- Everything is opt-out-able — update checking is a user preference, and the Network Activity log shows every check the agent makes.
Seven kinds of sources, one encrypted store.
Each connector is its own Rust crate speaking the provider's native protocol — OAuth 2.0 with PKCE for the cloud sources, direct database reads for iMessage, plain file I/O for local folders. Tokens live in the OS keychain. Sync is incremental, so after the first deep scan Haven only reads what's new.
The local store
Everything Haven learns lands in a single SQLCipher-encrypted SQLite database on the user's disk. The 32-byte key is generated on first launch and held in the OS keychain — Haven's servers couldn't read the store even with a copy of the file.
- Findings & verdicts — what was found, where, and every action taken, with the 30-day undo trail.
- The Network Activity log — the on-device record of every byte that ever left, kept in the same transaction as the send itself.
- Signed artifacts — the active rules pack, model manifests, and update manifests, stored as the exact signed bytes that were verified.
- Schema discipline — 29 additive migrations and counting; upgrades never rewrite or expose prior data.
An ops plane that can't see your data.
The backoffice exists so a small team can run an alpha fleet: watch aggregate health, read tester feedback, issue invites, and stage releases. Its most important property is what it doesn't receive — the telemetry schema is a fixed vocabulary of counter slugs, so message content is not just unsent, it's unrepresentable.
What the team can actually do
- Fleet dashboard — daily aggregate charts: scans run, findings by severity band, remediation counts, version adoption. Counters, not content.
- Alpha lifecycle — invite by email, issue license keys and download tokens, and remotely pause a license (the kill-switch): a paused agent's writes are refused fleet-wide.
- Release intake — CI uploads each signed installer; the backoffice keeps the latest plus recent versions per OS for the download links and the update channel.
- Feedback inbox — every in-app "send feedback" lands here, already scrubbed on the client before it was sent.