Lexicera Request a demo

Security

Including the parts that are not finished.

What follows is what is true today, with a citation on every claim that can be checked. The second half of this page is the part most vendors leave out, and it is the reason to believe the first half.

Documents

Encryption

Every document gets its own encryption key. That key is wrapped by your firm's master key and stored beside the row; the ciphertext goes to your firm's own bucket; the master key sits on disk, root-owned, and is escrowed offline. Compromise of any single one of those stores yields nothing usable.[1]

The checksum of the original file is recorded when it arrives and verified on every download, so alteration is detectable rather than silent.[2] Documents are encrypted before they leave your building, and what reaches storage is ciphertext of exactly the same length as the original — the platform stores no readable copy of a client document.

On your first day you take your own copy of your master key off the server and prove a restore works with it. That is an attestation, and it is the one step on the onboarding list you cannot recover from skipping.

Between firms

Tenancy

Separate storage per firm, row-level security enforced by the database itself, and an explicit firm predicate on every query. Thirteen narrow functions are permitted to cross the tenant boundary and nothing else is — they are counted, not estimated, and each one resolves a credential before any tenant context exists. The test suite asserts that a query with no firm context returns zero rows: not that it should, that it does.[3]

Inside a firm, an ethical wall restricts a matter to a named list, enforced at a single seam every read passes through — so a walled matter is absent from search, briefings, calendars and exports rather than merely hidden on its own page.[4] To someone off the list it answers exactly as a matter that does not exist would.[5]

Accountability

The audit trail, and what cannot be automated

Reads are recorded, not only writes. A database trigger prevents update and delete on that trail — including by the platform operator — and actors are distinguished as person, AI, platform, system or external.[6]

Nothing with legal consequence is auto-approved, and the enforcement is structural. A deadline cannot be calendared without a named confirming attorney; the database rejects the write.[7] A ruleset is confirmed per firm, as an append-only attestation, so one firm's confirmation can never make another firm's dates look verified.[8] An order can propose dates but never enter them, and superseding an order leaves anything an attorney already confirmed untouched.[9]

Access requires a second factor. Sessions without one are refused the application rather than shown a reduced version of it.

The model

What happens to your documents at the AI vendor

There is no training pipeline in this codebase — nothing collects, exports or retains your material for model improvement — and documents go to a commercial API under terms that do not permit training on what is sent. This is the one answer here whose proof is partly a third party's contract rather than a file in our own tree, and it is worth saying that plainly rather than letting it read as a guarantee we can enforce alone.[10]

A document can be marked AI-excluded, after which it is never sent to a model at all, and a walled matter cannot be asked about by anyone off its list.

Read this part

What you should assume is not protected

Four things an assessor would find, stated here instead.

Database rows are not separately encrypted

Documents are. Extracted text, facts, matter titles, party names, filenames and the audit trail are ordinary database rows. Assume a full compromise of the server is a compromise of the searchable record, not only of the metadata.[11]

A decrypted copy exists briefly during extraction

Text extraction writes a decrypted file to a service-account-only scratch directory, deleted on completion. This is precisely why we do not claim the operator cannot read your files. What is true is narrower and worth stating exactly: there is no screen anywhere in this platform that shows the operator a client document.[12]

One storage credential, until the second firm

Buckets are per firm; the credential signing requests to them is not yet. A stolen storage key today would reach every firm's ciphertext rather than one firm's. Per-firm scoped keys are due before a second firm is onboarded. Encryption keys are unaffected — every master key is per firm and none is held in object storage.[13]

The second and third copies are built but not running

An immutable copy at a second vendor and a deep archive at a third are built and their restores verified, but their schedules are deliberately off until the first real client document is uploaded — a gate written into the project's own issue tracker so it cannot quietly slide. Today there is one copy, with the others one command away rather than a build away.[14] If you are reading this and it still says one copy, ask before you send us anything.

One operator

There is a written breach-response runbook, but not yet an incident-response commitment with contractual times in it. There is one person, and you would hear about an incident from him. A continuity commitment — what happens to your files if this platform stops — is on the roadmap and is being written down rather than left to a conversation.

Sources

  1. codesrc/lib/crypto.ts — every document gets its own AES-256-GCM data key, wrapped by the firm's master key and stored beside the row; the ciphertext goes to the firm's bucket; the master key sits on disk root-owned and is escrowed offline. Compromise of any single store yields nothing usable.
  2. codeThe SHA-256 of the original file is recorded at ingestion and checked on every download, so alteration is detectable rather than silent.
  3. constraintSeparate storage per firm, row-level security enforced by the database, and an explicit firm predicate on every query. Thirteen narrow SECURITY DEFINER functions may cross the tenant boundary and nothing else may; the test suite asserts that a query with no firm context returns zero rows — not that it should, that it does.
  4. codesrc/lib/access.ts — canAccessMatter() is the single seam every per-matter read passes through, and wallPredicate() the fragment every cross-matter query carries. Documents, search, the fact ledger, briefings, exports and every AI surface inherit the screen from one place rather than each remembering to apply it. Migration 041.
  5. codeA matter behind a wall returns 404 to someone off its list — the same answer as a matter that does not exist, so the existence of the screened case is not disclosed by the shape of the refusal.
  6. constraintA trigger prevents update and delete on the audit trail, including by the platform operator. Reads are recorded, not only writes, and actors are distinguished as user, AI, platform, system or external.
  7. constraintCONSTRAINT machine_deadlines_need_a_human (migration 014) — a machine-suggested deadline row cannot reach status "confirmed" without a named confirming attorney. The database rejects the write; it is not a setting anyone can turn off, and no amount of clicking gets around it.
  8. migrationMigration 040 — confirming a ruleset is a per-firm attestation, appended and never edited. One firm's confirmation cannot make another firm's dates look verified; a ruleset this firm has not confirmed produces soft, visibly unverified dates.
  9. codesrc/lib/orders.ts, migration 044 — an order produces suggestions only, and the model may choose only from triggers this jurisdiction's loaded rules actually key off. Superseding an order cancels its unconfirmed dates and leaves anything an attorney confirmed untouched.
  10. contractThere is no training pipeline in this codebase — nothing collects, exports or retains your material for model improvement. Documents go to a commercial API under terms that do not permit training on what is sent. This is the one answer whose proof is partly a third party's contract rather than a file in our own tree, and it is worth saying that plainly rather than letting it read as a guarantee we can enforce alone.
  11. policyDocuments are encrypted; database rows are not separately encrypted. Extracted text, facts, matter titles, party names, filenames and the audit trail are ordinary rows. Anyone assessing this should assume a full compromise of the server is a compromise of the searchable record, not only of the metadata.
  12. policyText extraction writes a decrypted copy to a service-account-only scratch directory, deleted on completion and swept by the operating system. This is why we do not claim the operator cannot read your files. What is true is narrower and worth stating exactly: there is no screen anywhere in this platform that shows the operator a client document.
  13. codesrc/lib/storage.ts signs every request with one storage credential today, so that key reaches every firm's ciphertext rather than one firm's. Per-firm scoped keys are due before a second firm is onboarded. Encryption keys are unaffected: every master key is per firm and none is held in object storage.
  14. policyThe immutable second copy and the deep-archive third are built and their round trips verified, but their schedules are deliberately off until the first real client document is uploaded. So today there is one copy, with the others one command away rather than a build away.

Every claim on this page that could be checked, and where to check it. We do this because it is what the product does: an answer that does not carry its source is an answer you have to take on trust.