Безпека

Прозоро про безпеку

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.

Шифрування «at rest»

Зовнішні API-ключі (банки, Resend, Anthropic) і брокерські секрети шифруються AES-256-GCM. Ключ шифрування ніколи не залишає сервер. Per-connection webhook-секрети — 32-байт hex для кожної банківської інтеграції.

Ізоляція даних користувача

Кожна UPDATE/DELETE-операція фільтрується за `userId`. IDOR-захист централізовано в `assertCanAccessAccount/Category` — спроба доступу до чужого рахунку дає 403, не 404. Сімейні рахунки працюють через явні ролі OWNER/MEMBER/VIEWER.

Сесії та revocation

JWT з інкрементним `session_version`. Зміна пароля, блокування користувача чи зміна ролі інвалідують усі активні сесії. Refresh-токени мобільного API ротуються при кожному оновленні.

GDPR і приватність

Hard-delete акаунту видаляє всі транзакції, рахунки, категорії каскадно в одній транзакції. Експорт даних — CSV/XLSX/PDF одним кліком. Cookie consent з двома категоріями (essential / functional), без аналітики й трекерів.

Аудит і спостережуваність

Усі адмін-дії та чутливі користувацькі операції пишуться в `audit_log` з IP, user-agent і source. Логи спроб входу зберігаються 30 днів. Webhook-події Stripe — окремий idempotency-журнал для replay при збоях.

Що ми НЕ робимо

  • Не продаємо і не передаємо дані третім особам. Джерело доходу — Pro-підписка, не реклама.
  • Не запускаємо веб-аналітику й трекери на користувацьких сторінках — немає Google Analytics, Mixpanel, Hotjar.
  • Не зберігаємо паролі у відкритому вигляді — bcrypt з 12 раундами, без backdoor-recovery.
  • Не показуємо баланс чи транзакції на партнерських сайтах — жодного embed-віджета, нічого leak'ати.

Банківська синхронізація — що саме передається

Якщо ви підключаєте Monobank або PSD2-банк через GoCardless, ми отримуємо лише те, що потрібно для синхронізації транзакцій: вихідні платежі, вхідні перекази, баланси рахунків. Жодних персональних даних банку (паспорт, фото, біометрія). API-токен банку зберігається зашифрованим AES-256-GCM; ви можете відкликати доступ в один клік з Налаштування → Банки. GoCardless-згода спливає кожні 90 днів за вимогою PSD2 — ми нагадуємо за 7 днів.

Що ви можете перевірити самі

Усі твердження вище — перевіряємі через код та 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).
  • Відкритий API: https://app.my-fina.com/api/openapi (OpenAPI 3.1).
  • Health endpoint: https://app.my-fina.com/api/health (публічний liveness).

Отримувати сповіщення про безпеку

Підпишіться, щоб дізнаватися про CVE, патчі безпеки та зміни моделі загроз. Жодного маркетингу.

Повідомити, коли Pro стане доступним

Один email. Жодного спаму. Відписатися — в один клік.

GDPR-compliant · обробка даних у ЄСОстаннє оновлення: 3 червня 2026