Jak jest szyfrowane
TLS 1.3 w transmisji (Let's Encrypt). Zewnętrzne klucze API, tokeny bankowe i sekrety brokerów — AES-256-GCM z unikalnym IV na rekord. Hasła — bcrypt (12 rund). Klucz szyfrujący żyje w env, a nie w bazie.
Bezpieczeństwo
MyFina to domowa księgowość. Dane finansowe są wyjątkowe — pokazujemy, jak są chronione, bez marketingowej waty.
Trzy krótkie odpowiedzi na najważniejsze pytania
TLS 1.3 w transmisji (Let's Encrypt). Zewnętrzne klucze API, tokeny bankowe i sekrety brokerów — AES-256-GCM z unikalnym IV na rekord. Hasła — bcrypt (12 rund). Klucz szyfrujący żyje w env, a nie w bazie.
PostgreSQL 16 w zarządzanej instancji w Hetzner (Niemcy, UE). Izolowana sieć Docker, brak zewnętrznych połączeń do bazy. Kopie zapasowe — codzienne, szyfrowane przed wysyłką, retencja 30 dni.
Hard-delete konta w jednym kroku: kaskadowo usuwane są transakcje, konta, kategorie, waluty, tokeny. Bez tabel soft-delete, bez archiwum „na wszelki wypadek”. Leady marketingowe z tego samego e-maila — osobny erase-hook (GDPR Art. 17).
Sześć filarów obrony
NextAuth.js v5 na JWT, hasła hashowane bcryptem. Throttling logowania — 5 prób / 15 min na identyfikator i 20 / 15 min na IP. OAuth Google opcjonalnie. Reset hasła — 32-bajtowy token, w bazie tylko jego SHA-256.
Zewnętrzne klucze API (banki, Resend, Anthropic) i sekrety brokerów są szyfrowane AES-256-GCM. Klucz nigdy nie opuszcza serwera. Per-connection sekrety webhooków — 32-bajtowe hex dla każdej integracji bankowej.
Każda operacja UPDATE/DELETE filtruje po `userId`. Ochrona IDOR jest scentralizowana w `assertCanAccessAccount/Category` — próba dostępu do cudzego konta zwraca 403, nie 404. Wspólne konta rodzinne działają na jawnych rolach OWNER/MEMBER/VIEWER.
JWT z inkrementującym się `session_version`. Zmiana hasła, blokada konta lub zmiana roli unieważniają wszystkie aktywne sesje. Refresh-tokeny mobilnego API są rotowane przy każdym odświeżeniu.
Hard-delete konta usuwa wszystkie transakcje, konta i kategorie kaskadowo w jednej transakcji. Eksport danych — CSV/XLSX/PDF jednym kliknięciem. Cookie consent z dwiema kategoriami (essential / functional), bez analityki i trackerów.
Wszystkie akcje administratora i wrażliwe operacje użytkownika trafiają do `audit_log` z IP, user-agentem i source. Logi prób logowania są przechowywane 30 dni. Zdarzenia webhooków Stripe — osobny dziennik idempotency dla bezpiecznego replay przy awariach.
Czego NIE robimy
Jeśli podłączysz Monobank lub bank PSD2 przez GoCardless, otrzymujemy tylko to, co jest potrzebne do synchronizacji transakcji: płatności wychodzące, przelewy przychodzące, salda kont. Żadnych danych osobowych po stronie banku (paszport, zdjęcie, biometria). Token API banku jest przechowywany zaszyfrowany AES-256-GCM; możesz cofnąć dostęp jednym kliknięciem w Ustawienia → Banki. Zgoda GoCardless wygasa co 90 dni zgodnie z PSD2 — przypominamy 7 dni wcześniej.
Głębsze szczegóły
Pełna lista usług zewnętrznych przetwarzających Twoje dane: Hetzner (hosting), Stripe (rozliczenia), Resend (e-mail), Anthropic (AI, DRAFT), GoCardless (PSD2), Monobank API, FCM.
Otwórz listęMacierz per-feature: co jest przechowywane, jak długo, jak jest usuwane. Przepływ GDPR Art. 15/17/20 i okna retencji dla każdej encji.
Otwórz macierzCo możesz sprawdzić samodzielnie
Każde stwierdzenie powyżej jest audytowalne w kodzie i API.
src/lib/crypto.ts (AES-256-GCM, randomBytes IV, auth tag).src/auth.ts, src/lib/auth/rate-limit.ts.src/lib/auth/ownership.ts (assertCanAccessAccount).https://app.my-fina.com/api/openapi (OpenAPI 3.1).https://app.my-fina.com/api/health (publiczny liveness).Zapisz się, aby dowiadywać się o CVE, łatkach bezpieczeństwa i zmianach modelu zagrożeń. Bez marketingu.