Как шифруется
TLS 1.3 в transit (Let's Encrypt). Внешние API-ключи, банковские токены и брокерские секреты — AES-256-GCM с уникальным IV на запись. Пароли — bcrypt (12 раундов). Ключ шифрования живёт в env, не в БД.
Безопасность
MyFina — домашняя бухгалтерия. Финансовые данные у нас на особом счету: показываем как они защищены без маркетинговой воды.
Три кратких ответа на главные вопросы
TLS 1.3 в transit (Let's Encrypt). Внешние API-ключи, банковские токены и брокерские секреты — AES-256-GCM с уникальным IV на запись. Пароли — bcrypt (12 раундов). Ключ шифрования живёт в env, не в БД.
PostgreSQL 16 в managed-инстансе в Хетцнере (Германия, ЕС). Изолированный Docker-network, никаких внешних подключений к БД. Бэкапы — ежедневные, шифруются перед загрузкой, retention 30 дней.
Hard-delete аккаунта в одном кадре: каскадно удаляются транзакции, счета, категории, валюты, токены. Без soft-delete-таблиц, без архива «на всякий случай». Маркетинг-лиды по тому же email — отдельный erase-hook (GDPR Art. 17).
Шесть столпов защиты
NextAuth.js v5 на JWT, пароль хешируется bcrypt. Логин-троттлинг 5 попыток / 15 мин на identifier и 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, мы получаем только то, что необходимо для синхронизации транзакций: outbound-payments, входящие переводы, балансы счетов. Никаких персональных данных банка (паспорт, фото, биометрия). API-токен banks хранится зашифрованным 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, патчах безопасности и расширениях угроз. Никакого маркетинга.