Изоляция компаний
Tenant определяется только из проверенной сессии или API-ключа. Клиент запроса не может выбрать чужую компанию через body или query.
Безопасность
Компания, касса и клиентский кабинет используют разные права доступа. Сервер проверяет их при каждом запросе, а финансовые операции сохраняются в журнале.
Эти свойства уже являются частью архитектуры и проверяются интеграционными тестами.
Tenant определяется только из проверенной сессии или API-ключа. Клиент запроса не может выбрать чужую компанию через body или query.
Пароли защищены scrypt; API-ключи, OTP и portal-сессии сохраняются как необратимые digest. Payload уведомлений и webhook-секреты шифруются.
Начисление, списание и продажа требуют Idempotency-Key. Повтор с тем же содержимым возвращает прежний результат, а подмена payload отклоняется.
Ключи получают только нужные scopes, имеют срок действия и могут быть отозваны или ротированы без смены данных компании.
Авторизация, OTP и платные уведомления ограничены устойчивыми multi-instance счётчиками с Retry-After.
Браузер не видит BFF-секрет и FastAPI session token. Сессия находится в HttpOnly-cookie; мутации проверяют Origin, Fetch Metadata и JSON content type.
Минимум доверия
Nuxt выступает backend-for-frontend. Только серверный слой знает отдельный BFF credential и передаёт opaque-сессию FastAPI.
Честный статус
Аудит не нашёл открытых Critical в проверенном коде, но production-безопасность нельзя доказать только unit-тестами репозитория.
Публичная формулировка «дыр нет» была бы недостоверной. Безопасность — это проверяемый процесс: код, инфраструктура, люди, мониторинг и регулярные повторные аудиты.