Bufin

Privacy Policy. What Bufin Stores and What It Cannot See

Last updated 2026-08-18

Bufin is committed to protecting your personal information. This Privacy Policy explains what we collect, what we don't, where your data lives, and what access we have to it. Bufin's architecture is built so that we can honestly say: we don't have a copy of your private financial data.

1. The big picture

Your private financial data: transactions, budgets, recurring items, sinks, preferences, lives as JSON files in a hidden "Application Data" folder inside YOUR Google Drive. Bufin never stores a copy on our servers. We literally cannot read your data. If you revoke Bufin's Drive permission from your Google account, we lose all access to your data: including for support requests.

Public/community data: roadmap proposals, votes, public notices, transparency ledger, household budgets you explicitly share with others, is stored in our database (Cloudflare D1) because it has to be shared across users. This is a small fraction of your overall app data and never includes personal financial details.

There is no sign-in method that puts your personal budget on our servers. Google and Microsoft both store it in an app folder of your own cloud; without an account it stays in your browser. Bufin has no database table for anybody's transactions, so there is no configuration, mistake or policy change that could quietly move your budget onto our infrastructure. The exceptions: shared household budgets and view-only share links, are listed separately below, and both require you to start them.

2. Personal information we collect

When you use Bufin, the following lives on OUR servers (Cloudflare D1): (a) account identifiers, your Google subject ID, email address, display name, and profile picture URL from Google; (b) a legacy access-tier field, retained from when Bufin was a paid app and no longer used for anything (the app is free, so nothing is gated); (c) any roadmap proposals or votes you create; (d) any household budgets, members, transactions, or invites you participate in; (e) any view-only share links you generate; (f) historical billing-event metadata from when Bufin was sold (amount, currency, payer email, processor reference), no new payment data is created, because nothing is sold and donations are processed entirely by an external platform that we receive no webhook from; (g) brief rate-limit counters; (h) for rate-limiting and abuse prevention, a salted one-way HASH of your IP address. We store the hash, never the address itself, so the raw IP cannot be recovered from our database; (i) optional admin-visible bug reports if you submit one. (Raw IPs still appear transiently in our hosting provider's own operational logs: see below, which is standard and outside a database we query.)

The following lives ONLY in your Google Drive, not on our servers: your transactions, your budget goals, your recurring entries, your sinks (envelopes), your sink movements, your preferences, your CSV import category rules. We see none of it.

We use Google Analytics 4 for audience measurement, and ONLY with your consent: it does not load, set a cookie, or send anything until you accept it in the cookie banner, and you can withdraw that at any time in Settings, Privacy. Advertising features are switched off in our configuration (no Google Signals, no ad personalisation, no ad storage), so it is used to count visits and page popularity, not to build an advertising profile of you. We use no advertising networks, no marketing pixels, no session recording and no heatmaps. We do not record your screen or your keystrokes. There is no advertising in Bufin and we have no plans to add any.

We do not sell, rent, share, or trade your personal information: to anyone, for any purpose, ever. Bufin has no business model that involves your data: the app is free, and it is funded by voluntary donations and by clearly-marked referral links in the tools section. Neither of those requires knowing anything about you, which is the point.

Usage analytics: exactly what we collect, and why. The only product analytics we run is our own, served from our own API; no third-party analytics service is involved. We collect two things: (i) page views. That a given page path was opened, and in which of the two languages; and (ii) interaction counts. That a given labelled control was clicked, and on which page. A control's label can only ever be a name written into the app by us (an attribute, an aria-label or a title); it is NEVER read from an element's text content, precisely because in this app that text is a merchant name or an amount. So a click on "add transaction" is counted as add_transaction, and a click on a row showing your grocery bill is counted as "button" and nothing more.

How it is stored: every event is folded on arrival into a counter keyed by (date, page path, event name, label), one row per combination per day, incremented. There is no user id, no session id, no cookie, no device identifier, no IP address kept, and no timestamp finer than the calendar day. Page paths have long opaque segments (share tokens, invite tokens, ids) replaced with a placeholder before they are stored, in the browser and again on the server. There is nothing in this data that can be traced to a person, including by us, and nothing from your finances: no amounts, categories, descriptions, balances or merchant names.

Your controls: analytics can be switched off entirely for a browser in Settings → Privacy, in which case that browser sends nothing at all. We also honour Global Privacy Control and Do Not Track without you having to find that setting. Blocking our endpoint with a content blocker works too, and the app behaves identically either way: nothing depends on analytics running.

Why we run it: to find out which features are actually used, where new users drop off during onboarding, whether pages load quickly, and which bugs are hitting real people. In other words, to make the product better, not to make money from you. We never use this data for advertising, never sell or share it, never connect it to your financial data (which we cannot read anyway), and never use it to identify you. If you block it with a content blocker, Bufin works identically; nothing in the app depends on analytics running.

In addition to product analytics, our hosting and API providers (Cloudflare Workers, Pages, D1) generate operational logs: request paths, response codes, timestamps, and short-lived IP addresses, which are used solely to keep the service running, prevent abuse, and debug errors. These logs are retained for a short period under Cloudflare's standard retention and are not used for marketing or sold.

A note on AI-assisted development

In the interest of full transparency: parts of Bufin's code are written with the help of AI development tools, the way a builder uses any modern programming tool. This is strictly a development-time practice, the AI tooling works on Bufin's own source code, and on nothing else. No user data of any kind: financial, personal, or otherwise, is ever sent to, shared with, or accessible by any AI system. There is no AI running inside the app, nothing analyses what you do, and your data is never used to train anything. Your data path is completely unchanged by this: it stays in your own cloud (or, for email accounts, in our encrypted database), exactly as described above.

Being honest about AI also means being honest about its downside. Everything this policy and the rest of the site describe is what Bufin is genuinely built and intended to do, but code written with AI assistance introduces bugs, sometimes ones that are hard to spot in review. Features can behave incorrectly, numbers can display wrong, and a release can break something that worked yesterday. We do not treat that as acceptable: it is why every change is reviewed and tested before it ships, why bug reports go straight to the person who builds Bufin (Roadmap → Report a bug), and why fixes are prioritised over new features. If you ever see Bufin doing something it says it does not do, please tell us. That is a bug to be fixed, not a policy to be reinterpreted.

3. Purposes

We collect personal information solely to: (a) create and secure your account; (b) display your name and avatar in shared community features (roadmap, households); (c) verify your premium tier status server-side so it can't be spoofed; (d) prevent fraud, abuse, and security incidents; (e) comply with legal obligations. We do not sell, rent, or trade personal information.

4. Google user data: access, use, storage, sharing

Bufin uses Google Sign-In and Google Drive. When you sign in, Bufin requests exactly these Google OAuth scopes, and no others: openid, email, profile, and https://www.googleapis.com/auth/drive.appdata.

What Google data we access: (a) from your Google Account, your Google user identifier (the "sub" claim), email address, display name, and profile-picture URL; (b) from Google Drive. ONLY a single hidden, per-application "Application Data" folder (the drive.appdata scope) that Bufin creates. This scope does NOT give Bufin access to any of your other Google Drive files, photos, or documents, and that folder is invisible in your normal Drive view.

How we use it: your Google account identifier, email, name, and picture are used solely to create and secure your account, display your name/avatar in shared community features you opt into (roadmap, households), and verify your supporter tier server-side. The Drive Application Data folder is used solely to store and read YOUR own budget data (transactions, budgets, preferences, etc.) as files in your Drive. We use Google user data only to provide and improve these user-facing features of Bufin.

How we store it: your Google account metadata (sub, email, name, picture URL) is stored in our shared database (Cloudflare D1). Your financial data lives only in your own Google Drive Application Data folder. Bufin keeps no copy on its servers and cannot read it. The Google OAuth access token stays in your browser to talk to Drive directly; it is sent once to our server at sign-in solely to verify your identity with Google, and is not persisted server-side.

How we share it: we do NOT sell, rent, or share your Google user data, and we serve no advertising. No human reads your Drive data. We transfer Google user data only as necessary to provide or secure the service, to comply with applicable law or enforceable governmental requests, or as part of a merger or acquisition with continued protection and notice.

Retention & revocation: Google account metadata is deleted within 30 days of account deletion. Your Drive data is under your control, delete it anytime in Google Drive. You can revoke Bufin's access to your Google Account and Drive at any time at https://myaccount.google.com/permissions; once revoked, Bufin permanently loses all ability to access that data.

Limited Use: Bufin's use and transfer to any other app of information received from Google APIs will adhere to the Google API Services User Data Policy, including the Limited Use requirements. In particular: we only use this data to provide or improve user-facing features that are prominent in Bufin; we do not transfer or sell it for personalized advertising, credit, or other unrelated purposes; we do not allow humans to read it except with your explicit consent, for security or to comply with law, or in aggregated/anonymized form for operations; and any other transfer is limited to the narrow cases above.

5. End-to-end encryption (optional)

Bufin offers an optional encryption mode ("Ghost Mode") where the descriptions of transactions are encrypted with a passphrase derived only in your browser. When enabled, even Google: who stores the Drive files, cannot read the encrypted descriptions. Amounts, categories, and dates remain plaintext because encrypting those would break sums and filtering. If you forget the passphrase, the encrypted data is unrecoverable.

6. Storage and security

Our shared data lives in Cloudflare D1, an edge SQLite database. Communications use TLS in transit. Sessions are signed JWTs with short lifetimes (one hour). Rate limits and bot checks block automated abuse. Worker secrets (the Google client secret, the session signing key, the admin PIN hash) are stored in Cloudflare's encrypted secret store, never in source code.

Sign-in is protected against automated abuse by Cloudflare Turnstile and per-account rate limiting, and the whole service sits behind Cloudflare's network for DDoS protection. There is no password to steal or reset: authentication is delegated entirely to Google or Microsoft, so Bufin never receives, stores or verifies a password.

7. Honest note about administrative access

We control the Cloudflare account and could query the shared D1 database: including who is in what household, who voted for which proposal, who donated. This access exists for legitimate operational purposes (debugging, abuse investigations, lawful requests) and is not used for curiosity browsing. However, we cannot access your private financial data because it never reaches our servers. It lives in your Drive.

8. Your rights

You can: (a) access your personal data directly in the app (your shared data) or via Google Drive (your private data); (b) export everything as JSON from Settings; (c) delete your account, which deletes all shared records within 30 days; (d) revoke Drive access from your Google account at any time. Depending on your location, you may have rights under GDPR, PIPEDA, Quebec's Law 25, or similar regimes. Email [email protected]: we aim to reply within 30 days.

9. Cookies and local storage

Bufin uses essential local storage to remember your language, theme, authentication session, and dismissed in-app notices. That storage is strictly necessary and needs no consent. Separately, Google Analytics sets cookies (_ga and _ga_*) and is NOT strictly necessary, so it is asked for and only runs if you accept. No advertising cookies are set either way.

10. Third-party processors

We rely on: (a) Google LLC, Google sign-in + Drive storage, and, for visitors who consent, Google Analytics 4 for audience measurement; (b) Cloudflare Inc. Hosting (Pages), API (Workers), shared database (D1), KV cache, and abuse/DDoS protection (Turnstile); (c) Microsoft. OneDrive sign-in and, for OneDrive users, your own OneDrive app folder. There is no payment provider and we receive no payment webhooks, because nothing is sold; if you donate, that happens entirely on the donation platform's own site under its own privacy policy, and we are told nothing about it. Each of the above is bound by its own privacy policy.

11. Data location

Cloudflare D1 replicates data across multiple regions. Google Drive stores data per Google's regional configuration for your account. We use providers with strong data-protection standards.

12. How long we keep things

The rule is simple: personal information is kept only as long as it is needed for the purpose it was collected, and then it is deleted. The part that matters is that this is not a promise on a page. Every window below is enforced by a job that runs daily against our database, and the schedule it runs from is published, unchanged, right here. If the two ever disagree, the page is the one that is wrong and we want to hear about it.

The retention schedule:

• Single-use two-factor and step-up tokens: deleted the moment they expire (minutes).

• Rate-limit counters, keyed by a hashed IP address: deleted the moment the window closes (hours).

• Expired read-only share links: deleted on expiry.

• Expired household invitations: deleted on expiry.

• Unsubscribed newsletter addresses: 30 days, so an accidental unsubscribe can be undone, then removed entirely. We do not keep a permanent suppression list, because that means permanently keeping the address of everyone who asked us to stop.

• Uncategorised quick drafts: 180 days.

• In-app messages you have read: 365 days.

• Bug reports, after they are marked fixed or dismissed: 365 days.

• Shared-account change history inside a household: 730 days (2 years).

• Aggregate page-view counters: 400 days (13 months), enough for one year-over-year comparison and no more. These rows carry no identifier of any kind.

• Aggregate click counters: 400 days, same window and same reasoning. A click is recorded only against a label we wrote ourselves, never against anything you typed.

• Households nobody is left in: 30 days after the last member leaves.

Google Analytics is the exception to all of the above, because the data is held by Google rather than by us: its retention is governed by the retention setting in our Google Analytics property and by Google's own policies, not by the schedule above. It only ever holds data for visitors who accepted it. Withdrawing consent in Settings, Privacy stops collection immediately and deletes its cookies from your device.

Two things are deliberately NOT on that list. Your account is not auto-expired for inactivity: it is the key to any household records you share with other people, and quietly deleting it would destroy their data to enforce a rule about yours. And your budget is not on the list because it has never been in our database at all. Transactions, balances, bills and holdings live in your own Google Drive, your own OneDrive, or your own browser. There is nothing here for us to expire.

When you delete your account, we do not wait out a retention window. The deletion runs immediately: account record, roadmap proposals and votes, drafts, bug reports, in-app messages, share links, household memberships and every active session on every device, gone in the same request. Households you own are deleted with you. Any historical donation record is kept but stripped of your identity, because accounting records have to exist and do not have to have your name on them.

You can see the machine-readable version of this schedule at bufin.app/api/retention. It is generated from the same code that does the deleting, so it cannot drift away from what actually happens.

13. Automated decisions and profiling

Bufin does not make automated decisions about you, and does not profile you. There is no algorithm scoring your creditworthiness, no model predicting your behaviour, no segmentation, no risk rating, and nothing that decides anything about you without a human. This is stated plainly because Quebec's Law 25 requires us to tell you when a decision is made exclusively by automated processing, and the honest answer is that we make none.

The app does do arithmetic on your numbers: it projects a recurring bill onto a calendar, works out a debt payoff order, and estimates what a paycheque has to cover. That is a calculator running on your device, on figures you typed, showing you a result. It decides nothing about you, it is not used to judge you, and none of it leaves your device or reaches us.

We also do not use your information to train any machine-learning model, ours or anyone else's, and we never will. Your budget is not training data.

14. Security incidents

If personal information under our control is lost, accessed without authorisation, or disclosed, we treat it as a privacy incident from the moment we become aware of it, whether or not it turns out to be serious.

What we commit to: (a) we keep a register of every privacy incident, including the ones we assess as low risk and do not report, and we keep those records for at least 24 months, as PIPEDA and Law 25 require; (b) where an incident creates a real risk of significant harm, we notify the Office of the Privacy Commissioner of Canada and the Commission d'accès à l'information du Québec, and we notify affected users, promptly and without waiting to have a complete picture; (c) for users covered by the GDPR we notify the relevant supervisory authority within 72 hours of becoming aware, and notify affected individuals directly where the risk to them is high; (d) our notice to you will say what happened, what information was involved, what we have done, and what you can do, in plain language and without minimising it; (e) where it is safe and useful to do so, we publish a post-mortem.

It is worth being precise about what could actually be in such an incident, because it is not your budget. Our database holds account records (name, email, profile picture), household records people have chosen to share with each other, roadmap votes, bug reports and aggregate counters. Your financial data is in your own cloud account under your own credentials, so a breach of our systems does not expose it. A breach of your Google or Microsoft account is a different matter, which is why two-factor authentication on that account is the single most useful thing you can do.

15. Children

Bufin is not directed to children under 14. Contact [email protected] if you believe a child under 14 has registered.

16. Changes to this policy

If we make an important change to how we handle your data, we'll show you a clear message inside the app at least 15 days before it takes effect, so you're never caught off guard. Small wording tidy-ups that don't change what we do with your data may happen without notice, but anything that actually affects your privacy gets the 15-day heads-up.

17. Who is accountable, and how to reach them

One person is accountable for the protection of personal information at Bufin, and that person can be reached directly: Privacy Officer, Bufin, [email protected]. Every privacy request, question, complaint and incident report goes to that address and is read by the person responsible, not by a queue.

Bufin is run by one independent developer rather than a company, which is why this page names a role and an address instead of a department. It also means there is nobody to escalate past: if you are not satisfied with how a request was handled, the next step is not another desk here, it is the regulator.

You always have the right to complain to a regulator, and you do not need our permission or our involvement to do it. In Canada: the Office of the Privacy Commissioner of Canada (priv.gc.ca). In Quebec: the Commission d'accès à l'information du Québec (cai.gouv.qc.ca). In the EU or UK: your national data protection authority.