Where encryption stops: the limits of our own privacy claim
1 August 2026 · 9 min read · TruMint
Parts 1 and 2 described a system where your financial values are ciphertext everywhere except inside one attested service. That is true, and it is not the whole picture. Encryption at rest answers exactly one question — what does someone get if they steal the storage — and a real system has other doors.
This post is the list of those doors. We wrote it because the version of this series that omits it is the version that gets taken apart in public by the first competent reader.
1. The server sees plaintext while it works for you
This is structural, not a bug. Computing Section 104 pools, matching transfers and answering portfolio questions all require the numbers. The plaintext exists in the memory of an attested enclave, for the duration of a request, and nowhere else — not on disk, not in a backup, not in a log. If you want a product where the server genuinely cannot compute on your data, you want a different category of product, and you should be suspicious of anyone selling you both.
2. Using the AI features sends data to Google
Ask TruMint, P60 extraction and automatic spending categorisation run on Gemini via Vertex AI in the EU. When you use them the relevant data leaves our systems: your question and the figures behind the answer, the document you uploaded, or the merchant text on a transaction.
enclave │ Google Vertex AI (europe-west1)
─────────────────────────────────────────────┼──────────────────────────────
encrypted at rest │
│ decrypt │
▼ │
tool results ── holdings, balances, ──────┼──► model
merchants, tax figures │
your question ───────────────────────── ────┼──►
│
NOT sent: your DEK, other users' data, │ no training on your data
anything you did not ask about │ 30-day abuse-monitoring windowWhat is true: it is EU-resident, covered by data-processing terms, and never used to train models. What we will not claim: zero retention. By default Google keeps prompts and responses for up to 30 days for abuse monitoring. An exemption exists; we have not obtained it yet, so today that 30-day window applies to us. We will change this sentence when the exemption is granted, not when we apply for it.
Two things we fixed while writing this. Bank descriptors sometimes contain the name of the person you paid — a landlord, a friend splitting rent. That third party never agreed to anything, so person-like descriptors on bank rails are now withheld from the model entirely and categorised locally. And the classifier had a fallback to the public Gemini API that would have engaged silently on a misconfiguration; it now refuses to run rather than send your data outside the agreement.
3. An administrator can still take over an account
This is the sharpest item, and the one most likely to be missing from a competitor’s version of this page.
Attestation binds decryption. It does not bind authentication. Holding the administrative credential for our identity provider, one can reset an account’s password, change its email, or remove its second factor — and then sign in as that user. At that point the enclave decrypts and serves the data, exactly as it would for the real person, because as far as the system is concerned it is the real person. Two-factor authentication is now mandatory for new accounts and offered to all, which raises the bar: with a second factor enrolled, a password reset alone is not enough — the factor has to be removed first, and that removal is exactly what we now detect.
| Path | Status |
|---|---|
| Mint a session token directly for any account (silent) | Closed — such sessions are refused in production |
| Reset the password / change the email, then sign in | Possible, and now flagged to you by email within hours (reconciler) |
| Remove an enrolled second factor first | Possible, and detected — an out-of-band factor removal is flagged to you |
| Detect the above from cloud audit logs | Does not work — so we built our own; see below |
The silent path is closed: a token minted with administrative credentials carries a marker that production now rejects outright, at every entry point, and the rejection is part of the attested image — so removing it means shipping a new digest, which is logged and alerted.
The loud path remains. Our planned answer was to enable cloud audit logging and alert on administrative account changes. We tested that assumption and it failed: we enabled the logs, performed the exact administrative mutation, and no audit entry appeared — while unrelated key operations logged normally in the same window. Administrative SDK calls simply do not surface there. So we built application-level reconciliation instead, and it is now live: the app records every account change it legitimately made, a job runs every few hours comparing that against the identity provider’s actual state, and any change with no matching record — a factor removed, an email swapped — is flagged to you by email, not only to us. We proved it end to end by performing the real administrative factor-strip against production and confirming the alert fired. A related change since this post first published: the standing administrative key that used to sit on a developer machine has been deleted; that access is now a short-lived, individually-logged impersonation, so using it leaves a trail even though the identity provider’s own logs do not.
in-app change (you) out-of-band change (operator)
enrol · recover · edit Admin SDK: strip 2FA, swap email
│ │
│ app records it and │ identity-provider state
│ re-baselines — signed │ changes, but writes NO
│ with your key │ cloud audit-log entry
▼ ▼
┌────────────────────────────────────────────────────┐
│ reconciler · every few hours · inside the enclave │
│ diff live auth state vs the recorded baseline │
└───────────────────────┬────────────────────────────┘
│
match ◄──────┴──────► no match
│ │
ok ┌───────────┼────────────┐
▼ ▼ ▼
flag account email YOU alert us4. Structural metadata stays readable
Covered in Part 1, repeated here because it belongs in a list of limits. Identifiers, dates and a few coarse enums are not encrypted, because the database has to filter on them. Someone with the database learns activity shape — how many transactions, in which months, in which broad categories — but not amounts, counterparties, holdings or values.
One subtler consequence: because AES-GCM preserves length and we compress before encrypting, the size of a ciphertext correlates loosely with the size of the plaintext. A seven-figure salary is distinguishable from a four-figure one by length alone. We have not fixed this; padding costs storage on every field and we would rather tell you than pretend.
5. Where the bytes physically sit
Keys are in London. The enclave runs in London. The database is a US multi-region and object storage is US — so ciphertext is stored in the United States, while everything needed to read it stays in the UK. AI inference runs in the EU. We think this is a defensible arrangement and we would rather state it plainly than let “UK keys” imply UK storage.
The scorecard
| Claim | Status |
|---|---|
| A database breach yields no financial values | True |
| Backups and logs contain no financial values | True |
| Our administrator cannot decrypt your data | True — verified against live infrastructure |
| Amounts, names, descriptions and balances are encrypted | True |
| Plaintext metadata does not reveal your financial position | True |
| Our administrator cannot access your account at all | FALSE — a visible, now-detected takeover is possible; prevention is not |
| No third party ever sees your data | FALSE — the AI features send data to Google |
| Zero retention at our AI provider | FALSE today — 30-day abuse-monitoring window applies; exemption not yet obtained |
| You can verify the running image matches our source | Partly — it reports its source commit and every release is hash-chained; independent rebuild is not yet possible |
Why publish this
A trust page that lists only the good news is a liability: every omission is something a reader can discover, and discovering it costs more trust than the original claim ever bought. The three rows above that are not green are the ones we would want to know about if we were choosing where to put our own financial data.
If you find something we have missed, we would genuinely like to hear about it — [email protected]. We do not pursue researchers acting in good faith, and this series exists because we took our own claim apart first.
- Part 1What we can and cannot read
- Part 2The key that refuses to talk to us
- Part 3Where it stops (you are here)
See it for yourself: explore a sample portfolio. No signup, no bank link.
Try the live demo