Your CV is the most sensitive document in your inbox. Your hiring plan is the most sensitive document in your company. Two modes ship today: Standard — encrypted at rest with a server-held key, convenient, the default — and Max-Privacy — passphrase-derived DEK that lives only in your browser, server stores ciphertext only. You pick during onboarding; switching costs a re-encrypt of your columns and is reversible.
Sensitive fields are encrypted at rest with AES-256-GCM. Application code paths that touch your data run inside a per-account database role; cross-tenant reads are physically rejected at the SQL layer by row-level security policies.
Messages between candidates and employers ride the same per-account isolation. They're encrypted at rest, accessible only to the conversation participants, and every read is logged. The server brokers delivery and signs the audit trail.
The whole resume-mill industry runs on this. We don't, won't, and the export endpoints physically don't exist in the codebase. It's also written into our privacy policy as an irreversible commitment. You can audit the API surface yourself — we're open about what tools the system exposes.
Plaintext lives in three places in Standard mode: your browser, our server (where it's re-encrypted at rest), and a scoped Claude call. In Max-Privacy mode (described below), the server tier holds ciphertext only — plaintext lives in your browser and the inference call.
Browser → server via TLS 1.3. Authenticated session.
Sensitive columns AES-256-GCM. Master key from AUTH_SECRET.
Per-account row policy. App role can't read other tenants.
Trigger-written log row visible in your account.
No homegrown crypto. Standard library primitives with conservative parameters. What's listed below is the Standard-mode defaults shared by every account — the Max-Privacy section after describes how the same primitives shift from server-keyed to browser-keyed when you opt in.
Sensitive columns (CV text, hunt narratives, snapshot bodies, messages) are encrypted with AES-256-GCM before they hit the database. The master key is derived from a long-lived server-side secret (AUTH_SECRET). Tamper-evident — modified blobs fail to decrypt.
Two database roles: job_seeker (migrations, bypass) and job_seeker_app (the role the live request runs as). Every account-scoped table has a policy account_id = current_account_id(). If the request-bound GUC isn't set, queries return zero rows — by Postgres, not by code.
AES-256-GCM (AEAD)AUTH_SECRET · rotation procedure documentedtest:rlsTLS 1.3 via Cloudflare Tunnel · zero-trust posture in front of Coolify-on-bare-metalcrypto.subtle) · no homegrown ciphersThe default is Standard mode (above) because matching, scoring, and snapshot generation all need plaintext during the inference call — convenient for new users. Max-Privacy mode is the strict-no-server-access path: you set a passphrase during onboarding, your browser derives the DEK, and the server only ever sees ciphertext. There's no admin override — and so no court can compel one. Switching from Standard → Max-Privacy re-encrypts your columns in a single transaction; switching back wipes the canary and restores server-keyed mode.
PBKDF2-SHA256 with 200,000 iterations over passphrase + per-account salt produces a 32-byte DEK in browser memory. We never see the DEK itself. A canary blob proves the unlock succeeded without leaking the DEK. If you forget the passphrase, the 24-character recovery code can re-derive it; if you lose both, the data is unrecoverable — there is no key escrow.
Same AES-256-GCM you'd get in Standard mode — only the key is now in your browser, not on the server. Profiles, hunts, snapshots, and proof-reader traces get sealed before they leave your device. The server stores ciphertext + IV + AAD only. Scoped Claude calls decrypt at request time inside the inference call and discard plaintext after.
Max-Privacy is opt-in for a reason — losing the passphrase means losing access to your encrypted data. We mitigate with a one-time 24-char recovery code shown at enrollment (saved offline by you), and a deliberate type-to-confirm data-wipe path with a 7-day cooldown if you really have lost both. If zero-knowledge is a hard requirement for choosing a hiring tool, pick this mode at onboarding.
You don't have to trust us when we say "we don't read it." You can see every action the system took on your account. Trigger-written from the database, exported on demand.
Every action that touches your account — match scores, snapshot generations, reach-outs, profile edits — produces an audit entry visible in Settings → Security. The log row is written by a Postgres trigger, not by application code, so it can't be skipped.
Exportable as JSON via the right-to-access endpoint. The audit-log-coverage test asserts that every mutation path writes a row — if a developer forgets, CI fails.
No vague "enterprise-grade" claims. Just the current status of each certification, with dates and links where applicable.
US-based operator with EU sub-processors. CCPA / CPRA right-to-know / delete / correct + GDPR Art. 15-22 rights — endpoints live today. Deletion is real (cascades from accounts, not a soft flag). DPA available on request.
Not contracted yet. We'll engage an auditor and publish the window once the company is incorporated and the audit firm is signed. Customers who need an attested report should email [email protected].
Not contracted yet. A scoped external audit of the auth surface, RLS isolation, and the MCP boundary is on the post-launch roadmap; findings will be published when complete.
Backend runs on inspectable infrastructure (Coolify-on-bare-metal behind Cloudflare Tunnel). The MCP tool list is publicly enumerable via the discovery endpoint — no closed-box AI ops.
Discovery endpoint →Got more? Write us — [email protected]. PGP available on request.
In Standard mode (the default), yes — the application has access to the master key, so a determined operator could decrypt your data. We mitigate with per-account row-level isolation and audit logging on every mutation. In Max-Privacy mode, no — the DEK is derived from your passphrase in your browser and never leaves it. Pick during onboarding; switching costs a single re-encrypt and is reversible.
Today: standard Auth.js magic-link recovery via your email provider. Once we ship client-side key derivation, your email becomes the seed for your DEK — and that recovery story changes. We'll surface the trade-off clearly when that lands.
Identical model. Employer accounts get their own per-account row-level policies and audit log. Match-time decrypt happens in the same scoped Claude call structure. Same SOC-2 roadmap posture (not contracted yet).
Inside the scoped match/snapshot call, Anthropic's inference servers process the relevant plaintext slice — that's how the LLM does the work. The call is scoped (just what's needed), short-lived, and logged on our side. Anthropic's enterprise terms apply: no training on user data, retention per the agreement.
In Standard mode: yes — we honor lawful requests with the data we hold. In Max-Privacy mode: we'd hand over ciphertext + the audit log; we don't hold the key. We commit to publishing aggregate transparency reports quarterly once we reach 100+ paying users.
We protect against: cross-tenant leakage (RLS, asserted by tests), drive-by SQL injection (parameterized queries throughout), prompt-injection in scraped content (three-layer sanitization), passive network attackers (TLS), and unauthorized API access (Auth.js sessions + OAuth-issued MCP tokens with audit trails). In Standard mode we do not protect against a compromised hunt.work server reading your data; in Max-Privacy mode we do — the server holds ciphertext only.
External pentest scheduled Q4 2026. Internal: the RLS isolation test (npm run test:rls) is run on every PR — 20-table corpus asserted to return 0 rows under the app role when the account context isn't set, plus cross-tenant UPDATEs are asserted to fail with SQL state 42501.
Informal today — write us at [email protected] and we'll work out a payout for valid findings. A formal program is on the roadmap.

Standard mode is the default — encrypted at rest, isolated by RLS, audited end-to-end. Max-Privacy mode (one click during onboarding, or any time later) shifts the DEK to your browser so the server holds ciphertext only. Both models ship today.