Як шифрується
TLS 1.3 in transit (Let's Encrypt). Зовнішні API-ключі, банківські токени та брокерські секрети — AES-256-GCM з унікальним IV на запис. Паролі — bcrypt (12 раундів). Ключ шифрування живе в env, не в БД.
Безпека
MyFina — домашня бухгалтерія. Фінансові дані у нас на особливому рахунку: показуємо як вони захищені без маркетингу.
Три короткі відповіді на головні запитання
TLS 1.3 in transit (Let's Encrypt). Зовнішні API-ключі, банківські токени та брокерські секрети — AES-256-GCM з унікальним IV на запис. Паролі — bcrypt (12 раундів). Ключ шифрування живе в env, не в БД.
PostgreSQL 16 у керованому інстансі в Hetzner (Німеччина, ЄС). Ізольована Docker-мережа, жодних зовнішніх підключень до БД. Резервні копії — щоденні, шифруються перед завантаженням, retention 30 днів.
Hard-delete акаунта в одному кадрі: каскадно видаляються транзакції, рахунки, категорії, валюти, токени. Без soft-delete-таблиць, без архіву «на всяк випадок». Маркетинг-ліди за тим самим email — окремий erase-hook (GDPR Art. 17).
Шість стовпів захисту
NextAuth.js v5 на JWT, пароль хешується bcrypt. Логін-тротлінг 5 спроб / 15 хв на ідентифікатор та 20 / 15 хв на IP. OAuth Google за вибором. Скидання пароля — 32-байтний токен, у БД лише SHA-256.
Зовнішні API-ключі (банки, Resend, Anthropic) і брокерські секрети шифруються AES-256-GCM. Ключ шифрування ніколи не залишає сервер. Per-connection webhook-секрети — 32-байт hex для кожної банківської інтеграції.
Кожна UPDATE/DELETE-операція фільтрується за `userId`. IDOR-захист централізовано в `assertCanAccessAccount/Category` — спроба доступу до чужого рахунку дає 403, не 404. Сімейні рахунки працюють через явні ролі OWNER/MEMBER/VIEWER.
JWT з інкрементним `session_version`. Зміна пароля, блокування користувача чи зміна ролі інвалідують усі активні сесії. Refresh-токени мобільного API ротуються при кожному оновленні.
Hard-delete акаунту видаляє всі транзакції, рахунки, категорії каскадно в одній транзакції. Експорт даних — CSV/XLSX/PDF одним кліком. Cookie consent з двома категоріями (essential / functional), без аналітики й трекерів.
Усі адмін-дії та чутливі користувацькі операції пишуться в `audit_log` з IP, user-agent і source. Логи спроб входу зберігаються 30 днів. Webhook-події Stripe — окремий idempotency-журнал для replay при збоях.
Що ми НЕ робимо
Якщо ви підключаєте Monobank або PSD2-банк через GoCardless, ми отримуємо лише те, що потрібно для синхронізації транзакцій: вихідні платежі, вхідні перекази, баланси рахунків. Жодних персональних даних банку (паспорт, фото, біометрія). API-токен банку зберігається зашифрованим AES-256-GCM; ви можете відкликати доступ в один клік з Налаштування → Банки. GoCardless-згода спливає кожні 90 днів за вимогою PSD2 — ми нагадуємо за 7 днів.
Глибше в деталі
Повний список сторонніх сервісів, що обробляють ваші дані: Hetzner (хостинг), Stripe (білінг), Resend (email), Anthropic (AI, DRAFT), GoCardless (PSD2), Monobank API, FCM.
Відкрити списокPer-feature матриця: що зберігається, як довго, як видаляється. GDPR Art. 15/17/20 запити й retention-вікна по кожній сутності.
Відкрити матрицюЩо ви можете перевірити самі
Усі твердження вище — перевіряємі через код та 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 (публічний liveness).Підпишіться, щоб дізнаватися про CVE, патчі безпеки та зміни моделі загроз. Жодного маркетингу.