Privacy You Can Test: How Ahorreo Enforces Zero Network Calls

“Your data never leaves your device” is one of the easiest sentences to write on a landing page and one of the hardest to keep true over years of development. A single analytics snippet, an error reporter added during a late-night debugging session, a font loaded from a CDN — any of them quietly turns the sentence into a lie.

For Ahorreo, where the data is your bank history, we didn’t want privacy to depend on everyone remembering a rule. We wanted it to be enforced by the platform, checked by the test suite, and verifiable by you. This post explains the layers.

Layer 1: There Is No Backend

The strongest guarantee is architectural. Ahorreo is a fully static site: the build output is a folder of HTML, JavaScript and CSS that any static host can serve. There is no API, no database and no server-side code. Statements are parsed in your browser and stored in IndexedDB on your device.

This has a cost we accept openly: if you lose your device and have no backup, there’s nobody to recover your data from. We’ll come back to how Ahorreo deals with that.

Layer 2: The Browser Enforces It

Architecture can drift, so the second layer lives in the HTTP headers. Ahorreo ships with a strict Content Security Policy, and its connect-src directive allows exactly two destinations: the app’s own origin and the European Central Bank’s public data API.

What the CSP means in practice

If someone, someday, adds a fetch to an analytics endpoint, the browser refuses to send it. Scripts can only come from the app itself, fonts are bundled rather than loaded from a CDN, and the page can't be framed by another site. The policy isn't a statement of intent; it's a wall.

Layer 3: The Test Suite Enforces It

A CSP catches problems in the browser, which means in production. We want to catch them before a commit lands. So Ahorreo’s test suite includes a cross-cutting test that scans the source for network calls — fetch, XMLHttpRequest, WebSockets and friends — and fails if one appears outside a short allowlist of authorised modules. The linter applies the same restriction while you type.

It’s a blunt tool, and that’s deliberate. It doesn’t try to judge whether a new network call is “safe”. It simply makes adding one a visible, reviewed decision instead of an accident.

The One Exception, and Why It’s Off

Ahorreo has exactly one kind of outbound request: fetching public tables from the ECB — reference exchange rates and the Euribor series used to review variable-rate mortgages. Nothing about you travels in those requests; they ask for a named statistical series and nothing else.

Even so, it’s off by default. With the setting disabled, no request is possible. With it enabled, every fetch is triggered by a click, never by a timer running in the background. We originally left Euribor as manual entry, and changed our minds once we saw the real cost: someone who has had a variable-rate mortgage for many years would have to type in every past review by hand, or live with a schedule projected at a 0% rate — a false number that looks precise.

Layer 4: You Can Verify It

None of this asks for your trust. Open your browser’s developer tools, switch to the network tab, and import a statement. You’ll see the app’s own files and nothing else. Or put your device in airplane mode and keep using Ahorreo: it’s an installable PWA, and apart from the optional ECB fetch, nothing stops working.

Keeping Data Safe Without a Cloud

Without a server, the main risk isn’t a breach; it’s loss. Ahorreo handles that with files you own:

Less Data, Less Risk

The final layer is the simplest: don’t keep what you don’t need. When Ahorreo reads a payslip PDF, it discards identity data — ID number, address, social security number — at the moment of parsing, and the original PDF is never stored. A test fails if any of it shows up in what’s saved.

Put together, the layers turn a marketing sentence into an engineering property: no server to send data to, a browser that blocks it anyway, a test suite that flags any attempt, and a network tab where you can watch nothing happen. That’s the kind of privacy we think a finance app owes you.

What Ahorreo does with the data it keeps is in Introducing Ahorreo, and why its storage is IndexedDB and not a server is in localStorage or IndexedDB.

This article explains how our software works and the maths behind it. It is not financial, tax or legal advice: for decisions about your own money, check with a qualified professional.