Version 2026-10-26 · last updated 26 October 2026
Penny & Quill (“the app”, previously called Personal Ledger) is a personal, non-commercial project run by Piotr Puczyłowski, Poland (“we”, “us”). We are the controller of the personal data described here. Contact for anything about your data: piotr.puczylowski@gmail.com.
The app is invitation-only. It can also run without accounts (a local lock on one device) — then almost nothing in this policy beyond section 04 applies.
| Data | Why | Legal basis (GDPR) | Where it's kept |
|---|---|---|---|
| Account: email, password (stored only as a one-way hash by the sign-in service), Google sign-in if you use it, date you joined, status (active / paused), admin role, acceptance of these documents | To give you an account, sign you in, and let the owner invite or pause users | Contract (Art. 6(1)(b)) | Netlify Identity |
| Sign-in activity: date and time of sign-ins and unlocks, how (password, Google, offline unlock…), device and browser type, “Home Screen app”, approximate city and country; last time you used the app | Security of accounts and spotting misuse; lets the owner see who uses the app | Legitimate interest (Art. 6(1)(f)) | Netlify Blobs — last 20 events per person. No IP address is stored. |
| Usage counts: receipt scans and calorie estimates this month, last seen | Fair-use limit (by default 300 scans a month) and cost control | Legitimate interest | Netlify Blobs |
| Your ledger (transactions, items, categories, rules, budgets, supplier groups, tags, notes) | The app itself | Contract | Your device. With Sync with your account: also on the server, end-to-end encrypted (section 05) |
| Receipt photos; meal notes | To read a receipt; to estimate calories (optional feature) | Contract | Not stored — passed to the reading service and discarded (section 06) |
| Bank transactions via bank sync (optional, only if you set it up) | To bring transactions from your bank into the app | Contract | Not stored by us — passed through to your device (section 08) |
| Google Drive connection (optional) | Drive sync, encrypted backups, watched folders | Contract / your choice | Your own Google Drive (section 09) |
We don't use your data for advertising, profiling or automated decisions, and we don't sell or rent it to anyone.
Accounts are run by Netlify Identity. When you sign in with a password, the password goes to Netlify's sign-in service, which stores only a one-way hash of it; we never see it. If you sign in with Google, Google tells the sign-in service your email address and name.
Each time you sign in or unlock the app, the app records the event for the owner's user list: date and time, the way you got in, your device and browser type (worked out from your browser's identification string), whether you used the Home Screen app, and your approximate city and country (provided by our hosting provider from the connection; we keep only the place name, never the IP address). While you use the app, the time you were last active is updated at most every 15 minutes. Only the last 20 events are kept per person.
The owner (admin) of the app can see, for each user: email, date joined, status, last active time and device, the sign-in list above, and this month's scan and calorie-estimate counts. The owner cannot see anyone's ledger.
On your device the app keeps a sign-in token and a salted, slowly hashed check of your account password (PBKDF2), so the app can be unlocked without internet. The password itself is never stored.
Transactions, budgets, categories, rules and settings are stored in your browser's storage (IndexedDB and local storage) on each device. Bank statement files you import are read in your browser and are never uploaded. Clearing the browser's site data, or Settings → Erase all data, deletes the copy on that device.
Without accounts, the app's password is only a lock for this device: the username and a salted hash of the password are stored on the device and nothing is sent anywhere.
If you turn it on, your ledger is compressed and encrypted on your device with AES-256-GCM before it's sent. The encryption key is locked with your sync passphrase and, separately, with your recovery code (PBKDF2-SHA256, 310,000 rounds). The passphrase and recovery code never leave your device. Nobody else — not us, not the hosting provider — can read the synced data.
What the server can see: your account identifier, the size of the encrypted data, when it was saved, and the type of device that saved it (e.g. “Windows · Edge”). If you keep several ledgers in one account, each is encrypted with its own key and stored separately; the server then also sees how many there are and which account owns each — never their names or contents.
Sharing a ledger. So that others can share a ledger with you, your account has a key pair: the private key stays inside your encrypted ledger on your devices; the public key and your e-mail address are stored on the server. When an owner shares a ledger, its key is sealed separately for each member with that member's public key, so only their devices can open it. To do this, the server keeps who is a member of which ledger and their role (owner, can edit, view only); the owner sees the members' e-mail addresses and members see the owner's. A ledger's name and contents stay unreadable to the server. When someone is removed, the ledger gets a new key; what they downloaded before stays on their devices.
The encrypted data is stored either in Netlify Blobs or on the operator's own computer (a “home server”) reached through Tailscale, which carries the encrypted connection. You can delete it at any time with Settings → Sync with your account → Delete synced data. If you lose both the passphrase and the recovery code, the synced copy can't be opened by anyone; your devices keep their own copies.
When you scan a receipt, the photo is sent through our server code (a Netlify function) to a reading service and the result comes back. By default this is Anthropic (the Claude AI model). If you pick another engine in Settings, it's Google Cloud Vision or Tabscanner; if none is available, the photo is read entirely on your device. Our server code doesn't store or log the photo. A photo taken without internet is kept on your device until it can be read.
Meal calories (optional, off by default): only the note you wrote (e.g. “pizza margherita, cola”) or the dish lines of a restaurant receipt are sent to Anthropic to estimate calories. Bank descriptions are never sent.
These services process the content on our behalf under their own terms for business customers; Anthropic's commercial terms don't allow it to use this content to train its models.
Statement files (.xls, .xlsx, .csv) are read in your browser. They are never uploaded. From each row the app keeps the date, amount, description, the other party's name and — when the file includes it — the other party's account number, which is used only to recognise money paid back by someone you chose (a "pay-back" sender). These details stay with your transactions, like everything else in your ledger.
Bank sync works only if you set it up with your own account at open-banking.io, a licensed account-information provider that you have a separate agreement with. Your bank transactions then pass, decrypted, through our server code on their way to your browser. They are not stored on our side. The sync token you enter is kept on your device and only sent to our server code to fetch your transactions.
With accounts on, Google Drive is optional and off unless you choose “Use Google Drive as well”. If you connect it, you sign in on Google's own screen; the app asks only for access to files it creates or that you pick (drive.file) and your email address (to show which account is connected).
You can disconnect in Settings or revoke access at myaccount.google.com/permissions.
The app is hosted by Netlify, whose servers, like any web host, see your IP address when your browser loads the page and may keep it briefly in technical logs. Your browser also loads fonts from Google Fonts and open-source code libraries from cdnjs (Cloudflare) and jsDelivr; these providers also see your IP address when the files are loaded. Google's sign-in and Drive libraries are loaded only if you use Google Drive.
Exchange rates: when a statement row or receipt is in another currency than your ledger, the app asks the Frankfurter service (api.frankfurter.app, which publishes the European Central Bank's reference rates) for the rate on that day. Only the two currency codes and the date are sent — no amounts, descriptions or anything about you. Like any website, the service sees your IP address. Rates are kept on your device so the same day isn't asked twice.
The app uses no tracking or advertising cookies and no analytics. It stores what it needs to work on your device (your ledger, settings, sign-in token, the offline password check) in browser storage. This storage is strictly necessary for the service you asked for, so no consent banner is needed for it.
Some of these providers process data outside the European Economic Area, including in the United States. Such transfers rely on the safeguards the GDPR requires, such as the EU–US Data Privacy Framework or the European Commission's standard contractual clauses.
Under the GDPR you can ask for access to your data, correction, deletion, restriction of processing, a copy in a portable format, and you can object to processing based on legitimate interest. Write to piotr.puczylowski@gmail.com; we'll answer within one month. You can also do a lot yourself: export your ledger (Settings → Your data → Export), delete it from a device (Erase all data), delete the synced copy (Sync with your account → Delete synced data), and change your password.
You have the right to complain to the Polish data protection authority, the President of the Personal Data Protection Office (Prezes Urzędu Ochrony Danych Osobowych, uodo.gov.pl), or to the authority in your own EU country.
The app is meant for adults managing their own money. It's not intended for anyone under 18, and we don't knowingly create accounts for them.
Connections are encrypted (HTTPS). Synced ledgers are end-to-end encrypted, server code checks your sign-in on every request, and admin functions are limited to the owner. No system is perfectly secure: keep your password, sync passphrase and recovery code to yourself, and keep a backup.
When this policy changes in a meaningful way, its version and date above change and the app asks you to read and accept the new version the next time you sign in.
Wersja 2026-10-26 · ostatnia aktualizacja 26 października 2026
Penny & Quill („aplikacja”, wcześniej Personal Ledger) to osobisty, niekomercyjny projekt prowadzony przez Piotra Puczyłowskiego (Polska) („my”). Jesteśmy administratorem danych osobowych opisanych w tym dokumencie. Kontakt we wszystkich sprawach dotyczących danych: piotr.puczylowski@gmail.com.
Dostęp do aplikacji jest tylko na zaproszenie. Aplikacja może też działać bez kont (lokalna blokada na jednym urządzeniu) — wtedy z tej polityki dotyczy Cię właściwie tylko punkt 04.
| Dane | Cel | Podstawa prawna (RODO) | Gdzie są przechowywane |
|---|---|---|---|
| Konto: e-mail, hasło (przechowywane wyłącznie jako jednokierunkowy skrót przez usługę logowania), logowanie przez Google, jeśli z niego korzystasz, data dołączenia, status (aktywne / wstrzymane), rola administratora, akceptacja tych dokumentów | Założenie i obsługa konta, logowanie, zapraszanie i wstrzymywanie użytkowników przez właściciela | Umowa (art. 6 ust. 1 lit. b) | Netlify Identity |
| Aktywność logowania: data i godzina logowań i odblokowań, sposób (hasło, Google, odblokowanie offline…), rodzaj urządzenia i przeglądarki, „aplikacja z ekranu głównego”, przybliżone miasto i kraj; czas ostatniego korzystania | Bezpieczeństwo kont i wykrywanie nadużyć; wgląd właściciela w to, kto korzysta z aplikacji | Prawnie uzasadniony interes (art. 6 ust. 1 lit. f) | Netlify Blobs — ostatnie 20 zdarzeń na osobę. Adres IP nie jest zapisywany. |
| Liczniki użycia: skany paragonów i szacunki kalorii w tym miesiącu, ostatnia wizyta | Limit uczciwego korzystania (domyślnie 300 skanów miesięcznie) i kontrola kosztów | Prawnie uzasadniony interes | Netlify Blobs |
| Twoje dane w aplikacji (transakcje, pozycje, kategorie, reguły, budżety, grupy dostawców, tagi, notatki) | Działanie aplikacji | Umowa | Twoje urządzenie. Przy synchronizacji z kontem także serwer, zaszyfrowane end-to-end (punkt 05) |
| Zdjęcia paragonów; notatki o posiłkach | Odczyt paragonu; oszacowanie kalorii (funkcja opcjonalna) | Umowa | Nie są przechowywane — trafiają do usługi odczytu i są odrzucane (punkt 06) |
| Transakcje bankowe z synchronizacji z bankiem (opcjonalnie, tylko jeśli ją skonfigurujesz) | Pobieranie transakcji z banku do aplikacji | Umowa | Nie przechowujemy ich — są przekazywane na Twoje urządzenie (punkt 08) |
| Połączenie z Dyskiem Google (opcjonalnie) | Synchronizacja przez Dysk, szyfrowane kopie, obserwowane foldery | Umowa / Twój wybór | Twój własny Dysk Google (punkt 09) |
Nie wykorzystujemy Twoich danych do reklam, profilowania ani zautomatyzowanego podejmowania decyzji i nikomu ich nie sprzedajemy ani nie wynajmujemy.
Konta obsługuje Netlify Identity. Przy logowaniu hasłem hasło trafia do usługi logowania Netlify, która przechowuje wyłącznie jego jednokierunkowy skrót; my go nigdy nie widzimy. Przy logowaniu przez Google, Google przekazuje usłudze logowania Twój adres e-mail i imię.
Przy każdym zalogowaniu lub odblokowaniu aplikacja zapisuje to zdarzenie na liście użytkowników właściciela: datę i godzinę, sposób wejścia, rodzaj urządzenia i przeglądarki (ustalany na podstawie identyfikatora przeglądarki), czy użyto aplikacji z ekranu głównego oraz przybliżone miasto i kraj (podawane przez naszego dostawcę hostingu na podstawie połączenia; zapisujemy tylko nazwę miejsca, nigdy adres IP). Podczas korzystania z aplikacji czas ostatniej aktywności jest aktualizowany najwyżej co 15 minut. Przechowywane jest tylko 20 ostatnich zdarzeń na osobę.
Właściciel (administrator) aplikacji widzi dla każdego użytkownika: e-mail, datę dołączenia, status, czas i urządzenie ostatniej aktywności, powyższą listę logowań oraz liczbę skanów i szacunków kalorii w bieżącym miesiącu. Właściciel nie widzi niczyich danych finansowych.
Na Twoim urządzeniu aplikacja przechowuje token logowania oraz zabezpieczony solą, wolno liczony skrót hasła do konta (PBKDF2), aby można było odblokować aplikację bez internetu. Samo hasło nigdy nie jest zapisywane.
Transakcje, budżety, kategorie, reguły i ustawienia są przechowywane w pamięci przeglądarki (IndexedDB i local storage) na każdym urządzeniu. Importowane pliki wyciągów są odczytywane w przeglądarce i nigdy nie są wysyłane. Wyczyszczenie danych witryny w przeglądarce albo Ustawienia → Usuń wszystkie dane usuwa kopię z danego urządzenia.
Bez kont hasło aplikacji jest tylko blokadą tego urządzenia: nazwa użytkownika i skrót hasła z solą są zapisane na urządzeniu i nic nie jest nigdzie wysyłane.
Jeśli ją włączysz, Twoje dane są kompresowane i szyfrowane na Twoim urządzeniu algorytmem AES-256-GCM, zanim zostaną wysłane. Klucz szyfrujący jest zabezpieczony Twoim hasłem synchronizacji oraz, osobno, kodem odzyskiwania (PBKDF2-SHA256, 310 000 rund). Hasło synchronizacji i kod odzyskiwania nigdy nie opuszczają Twojego urządzenia. Nikt inny — ani my, ani dostawca hostingu — nie może odczytać zsynchronizowanych danych.
Serwer widzi: identyfikator konta, rozmiar zaszyfrowanych danych, czas zapisu i rodzaj urządzenia, które je zapisało (np. „Windows · Edge”). Jeśli prowadzisz kilka ksiąg na jednym koncie, każda jest szyfrowana własnym kluczem i przechowywana osobno; serwer widzi wtedy także, ile ich jest i do którego konta należy każda — nigdy ich nazw ani zawartości.
Udostępnianie księgi. Aby inni mogli udostępnić Ci księgę, Twoje konto ma parę kluczy: klucz prywatny zostaje w Twojej zaszyfrowanej księdze na Twoich urządzeniach; klucz publiczny i Twój adres e-mail są przechowywane na serwerze. Gdy właściciel udostępnia księgę, jej klucz jest zabezpieczany osobno dla każdej osoby jej kluczem publicznym, więc otworzyć go mogą tylko jej urządzenia. W tym celu serwer przechowuje, kto należy do której księgi i z jaką rolą (właściciel, może edytować, tylko podgląd); właściciel widzi adresy e-mail osób w księdze, a one — adres właściciela. Nazwa i zawartość księgi pozostają dla serwera nieczytelne. Po usunięciu osoby księga dostaje nowy klucz; to, co ta osoba pobrała wcześniej, zostaje na jej urządzeniach.
Zaszyfrowane dane są przechowywane w Netlify Blobs albo na własnym komputerze operatora („serwer domowy”), do którego połączenie zapewnia Tailscale, przenosząc zaszyfrowany ruch. Możesz je w każdej chwili usunąć: Ustawienia → Synchronizacja z kontem → Usuń zsynchronizowane dane. Jeśli utracisz zarówno hasło synchronizacji, jak i kod odzyskiwania, zsynchronizowanej kopii nie otworzy nikt; Twoje urządzenia zachowują własne kopie.
Przy skanowaniu paragonu zdjęcie jest przesyłane przez nasz kod serwerowy (funkcję Netlify) do usługi odczytu, a wynik wraca do aplikacji. Domyślnie jest to Anthropic (model AI Claude). Jeśli w Ustawieniach wybierzesz inny silnik, jest to Google Cloud Vision lub Tabscanner; jeśli żaden nie jest dostępny, zdjęcie jest odczytywane w całości na Twoim urządzeniu. Nasz kod serwerowy nie przechowuje ani nie zapisuje zdjęcia w logach. Zdjęcie zrobione bez internetu czeka na Twoim urządzeniu, aż będzie mogło zostać odczytane.
Kalorie posiłków (opcjonalnie, domyślnie wyłączone): do oszacowania kalorii do Anthropic wysyłana jest tylko napisana przez Ciebie notatka (np. „pizza margherita, cola”) albo pozycje dań z paragonu z restauracji. Opisy z banku nigdy nie są wysyłane.
Usługi te przetwarzają treści w naszym imieniu na podstawie własnych warunków dla klientów biznesowych; warunki komercyjne Anthropic nie pozwalają na wykorzystywanie tych treści do trenowania modeli.
Pliki wyciągów (.xls, .xlsx, .csv) są odczytywane w przeglądarce. Nigdy nie są wysyłane. Z każdego wiersza aplikacja zachowuje datę, kwotę, opis, nazwę drugiej strony oraz — jeśli plik ją zawiera — numer rachunku drugiej strony, używany wyłącznie do rozpoznawania zwrotów od wybranych przez Ciebie osób. Te dane są przechowywane razem z Twoimi transakcjami, jak wszystko inne w Twojej księdze.
Synchronizacja z bankiem działa tylko wtedy, gdy skonfigurujesz ją z własnym kontem w open-banking.io — licencjonowanym dostawcy usługi dostępu do informacji o rachunku, z którym masz odrębną umowę. Twoje transakcje przechodzą wtedy, w postaci odszyfrowanej, przez nasz kod serwerowy w drodze do Twojej przeglądarki. Nie są przez nas przechowywane. Wpisany token synchronizacji jest przechowywany na Twoim urządzeniu i wysyłany tylko do naszego kodu serwerowego w celu pobrania transakcji.
Przy włączonych kontach Dysk Google jest opcjonalny i nieużywany, dopóki nie wybierzesz „Używaj też Dysku Google”. Jeśli go połączysz, logujesz się na ekranie Google; aplikacja prosi wyłącznie o dostęp do plików, które sama tworzy lub które wskażesz (drive.file) oraz o adres e-mail (aby pokazać, które konto jest połączone).
Możesz rozłączyć Dysk w Ustawieniach albo cofnąć dostęp na stronie myaccount.google.com/permissions.
Aplikacja jest hostowana przez Netlify, którego serwery — jak każdy hosting — widzą Twój adres IP przy wczytywaniu strony i mogą krótko przechowywać go w logach technicznych. Przeglądarka wczytuje też czcionki z Google Fonts oraz biblioteki open source z cdnjs (Cloudflare) i jsDelivr; ci dostawcy również widzą Twój adres IP przy pobieraniu plików. Biblioteki logowania Google i Dysku są wczytywane tylko wtedy, gdy korzystasz z Dysku Google.
Kursy walut: gdy transakcja z wyciągu lub paragon jest w innej walucie niż Twoja księga, aplikacja pyta usługę Frankfurter (api.frankfurter.app, publikującą kursy referencyjne Europejskiego Banku Centralnego) o kurs z danego dnia. Wysyłane są tylko dwa kody walut i data — bez kwot, opisów ani niczego o Tobie. Jak każda strona internetowa, usługa widzi Twój adres IP. Kursy są zapisywane na Twoim urządzeniu, żeby nie pytać dwa razy o ten sam dzień.
Aplikacja nie używa plików cookie śledzących ani reklamowych i nie korzysta z analityki. Na Twoim urządzeniu zapisuje to, co jest potrzebne do działania (Twoje dane, ustawienia, token logowania, skrót hasła do odblokowania offline), w pamięci przeglądarki. Jest to niezbędne do świadczenia usługi, o którą prosisz, więc nie wymaga zgody w osobnym banerze.
Część tych dostawców przetwarza dane poza Europejskim Obszarem Gospodarczym, w tym w Stanach Zjednoczonych. Takie przekazanie opiera się na zabezpieczeniach wymaganych przez RODO, takich jak ramy ochrony danych UE–USA (Data Privacy Framework) lub standardowe klauzule umowne Komisji Europejskiej.
Zgodnie z RODO możesz żądać dostępu do swoich danych, ich sprostowania, usunięcia, ograniczenia przetwarzania, kopii w formacie umożliwiającym przeniesienie oraz wnieść sprzeciw wobec przetwarzania opartego na prawnie uzasadnionym interesie. Napisz na piotr.puczylowski@gmail.com; odpowiemy w ciągu miesiąca. Wiele możesz zrobić samodzielnie: wyeksportować dane (Ustawienia → Twoje dane → Eksportuj), usunąć je z urządzenia (Usuń wszystkie dane), usunąć zsynchronizowaną kopię (Synchronizacja z kontem → Usuń zsynchronizowane dane) i zmienić hasło.
Masz prawo wnieść skargę do Prezesa Urzędu Ochrony Danych Osobowych (uodo.gov.pl) albo do organu nadzorczego w swoim kraju UE.
Aplikacja jest przeznaczona dla dorosłych zarządzających własnymi finansami. Nie jest przeznaczona dla osób poniżej 18 lat i świadomie nie zakładamy dla nich kont.
Połączenia są szyfrowane (HTTPS). Zsynchronizowane dane są szyfrowane end-to-end, kod serwerowy sprawdza Twoje zalogowanie przy każdym żądaniu, a funkcje administracyjne są dostępne tylko dla właściciela. Żaden system nie jest w pełni bezpieczny: nie udostępniaj nikomu hasła, hasła synchronizacji ani kodu odzyskiwania i miej kopię zapasową.
Gdy polityka zmieni się w istotny sposób, zmienią się jej wersja i data powyżej, a aplikacja przy następnym logowaniu poprosi Cię o zapoznanie się z nową wersją i jej akceptację.