Security

What Zilda holds, what it cannot see, and the one place that stops being true.

Your receipts stay in your own cloud account — unless you ask otherwise.

Zilda is built to hold as little of your material as possible. Here is exactly what that means, including where it stops being true.

Your storage, your keys

Connect Dropbox and the access key is stored on your device, in your browser's own storage. It is never sent to Zilda, which cannot list, open or delete anything in your account.

Unless you choose hosted storage

One option where this is not true. Choose hosted storage and Zilda keeps your receipts instead, in Sydney. Each is encrypted in your browser first, so the storage service holds sealed bytes and nothing readable — but by default Zilda holds the key that opens them, so Zilda can read them. Turning on end-to-end encryption, below, is what stops that.

Why it is offered, and how to take the key back

It is offered because connecting a cloud account is a real obstacle for some people. The key sits in a different database at a different company, but it is held. End-to-end encryption stops that being true: the key is stored wrapped, only a passkey on your own device, your passphrase or your recovery key opens it, and there is nobody to ask if you lose all three. Dropbox is still the default, and switching between the two moves nothing: each keeps what it already has.

End-to-end encryption, switched on from Storage

Turn it on and the key to your receipts and expenses is made on your device and never leaves it. What Zilda holds from then on is that key encrypted — useless without a passkey on a device of yours, a passphrase, or the recovery key issued when you turn it on. A stolen database, a subpoena served on a storage provider and an administrator who goes looking all stop working, because there is no longer anything on this side that opens them.

A passkey, a passphrase, and why there is no reset

A passkey is the one most people should use: the fingerprint, face or PIN your device already asks for unlocks the key, and there is no second password to invent or remember. The thirty-two bytes it derives are held inside the authenticator, which will not hand them to this page or to anything else. A passphrase does the same job for a browser or device without one, and can be added alongside. Either way a recovery key is issued once, and it is the only way back if every device is lost — nobody at Zilda can reset it, produce it or work around it, and that refusal is what the encryption is made of rather than a policy applied on top of it.

Your own spending is held the same way

The personal section is not a lighter class of record. A receipt filed into a folder you named is encrypted in your browser exactly as a work claim is, goes to the storage you chose exactly as a work claim does, and is covered by end-to-end encryption if you have turned it on.

The one thing a folder name does differently

What a folder is called is used as the name of the folder your receipt files are saved under, so that opening Dropbox in three years shows "Garden renovation" rather than a heap of filenames. That means the name itself sits in your storage account in readable form, where a receipt inside it does not — it is a label on a drawer rather than something inside one. Everything else about a personal receipt is handled exactly as every other receipt is, which is the point: a section for the things nobody is paying back is not a reason to protect them less.

No overnight jobs

Everything happens while the app is open. There is no server quietly reaching into your files at 2am, because there is nothing on Zilda's side that could. Your monthly export is a file you download, not mail on a schedule.

What Zilda does hold

Your email address, your expense records if you are signed in, the history of what you have done to them, your category corrections and your form template mapping — all sealed in your browser before they are sent, so what the database holds is ciphertext. Plus the receipt files themselves, for anyone on hosted storage. And the key that opens all of it, because by default Zilda holds that too.

What end-to-end encryption changes, and what Dropbox changes

The key is on that list because leaving it off is exactly how it would stop being obvious. Turning on end-to-end encryption takes it off: what is held then is the key wrapped in a passkey on your device or a passphrase only you know. What stays on the list either way is everything around a receipt rather than inside it — that one exists, roughly how big it is and when it arrived — because a sealed file still has to be stored and found. On Dropbox the expense records can leave entirely, into the same account as the receipts.

What end-to-end encryption cannot do

It stops anybody who has the database from reading your expenses — a stolen copy, a subpoena served on the company hosting it, an administrator who goes looking. Those are real and it genuinely stops them. What it cannot stop is this website.

Why this website is the limit

The encryption happens in code Zilda sends to your browser, so a future version of that code could take the key at the moment your browser unwraps it. Every product that encrypts in a browser has this property, including the ones that do not mention it — an app you install from a store is signed and the same copy is checked by everybody, while a page is fetched fresh every visit. It is not a reason to leave the encryption off. It is a reason not to believe a claim stronger than this one, here or anywhere else.

Where this stops

Reading a receipt needs a model too large to run in a browser, so by default the photograph passes through Zilda’s server on its way to it. It is held in memory for the few seconds that takes, never written to disk, and not logged.

Training, and reading on your own device

The reading service does not use it to train its models. If that trade is not one you want, Advanced options on the Storage page has a setting that reads receipts on your own device instead and uploads nothing — it reads fewer of them correctly, and says so where you turn it on.

How that is enforced, and not just promised

One endpoint sees a document

POST /api/extract takes bytes, returns fields, and keeps nothing. There is no database call on that path, no file written, and the error handler deliberately discards the caught error rather than logging it — because an HTTP client’s error object can carry the request body, and the request body is your receipt.

The key cannot be on your device

Reading a receipt needs a model Zilda pays for, and an API key cannot sit in an app somebody can unpack. That is the whole reason a backend exists here. It is also why the extraction client lives in a server-only module: the boundary is enforced by the build, not by remembering.

Your password is not Zilda’s to lose

Signing in is handled by Clerk, a company whose whole job that is. Zilda never sees your password, never stores a hash of one, and has no session table to steal — it keeps only which workspace you are in. The reset link, the verification mail and two-factor are theirs too, which is the point: those are the parts that are easy to get subtly wrong.

Storage tokens are on a different side of the wall

Nothing in the backend can reach your cloud account, because nothing in the backend has ever been given a way to. The consequence is the honest one: no overnight jobs, no scheduled export email, and reconnecting storage if you lose a device.