Files
backend/.ai/conventions/security-auth.md
T
ksv741 d698ed9425
Backend verify / commits (pull_request) Successful in 29s
Backend verify / security (pull_request) Successful in 8s
Backend verify / verify (pull_request) Failing after 9m36s
refactor!: simplify runtime coordination #7
Keep financial ownership, atomic publication and refresh CAS.
Failed refresh leaves cookies untouched; logout still clears them.

Remove full-history candle prefetch and special metadata retries.
Use native Pino request context instead of parallel middleware.

BREAKING CHANGE: remove investment stateVersion, queued sync state,
and tbank-sync status progress/resources. Consumers must observe
resources through sync=observe with the updated frontend contract.
2026-10-03 11:38:08 +03:00

4.5 KiB
Raw Permalink Blame History

Security и auth

Читай при изменении session/token/cookie/guard, account access, encryption или sensitive logging; обычный data query без этой границы не требует всего документа.

Выбор владельца

Identity/session — AuthService + strategy/guard; cookie transport — AuthController; account access/connection generation — TbankAccessService; token crypto — TbankTokenService/TbankCrypto. Расширяй существующую boundary, не добавляй второй JWT middleware, decrypt helper или refresh coordinator.

Access проверяется JWT strategy; refresh передаётся httpOnly cookie. Сроки token/session принадлежат auth source и configured HTTP tests. Source code конфигурации cookie — AuthController; изменение flags/path требует проверки browser/HTTP поведения, не только TypeScript.

Refresh rotation атомарна: один победитель, проигравший/superseded token получает 401, но не меняет cookie и сам по себе не отзывает session победителя. Cookie очищает logout; межвкладочная синхронизация не требуется, допустим re-login. Не вводи Web Locks, replay history/grace или иной security contract без текущей задачи. Logout идемпотентен, отзывает сессию и очищает refresh cookie на HTTP-границе.

Trust boundaries

Клиентский интерфейс не является security boundary. DTO runtime validation выполняется server-side; whitelist не заменяет access checks. Environment/secret inputs проверяет existing config owner; реальные credentials не попадают в fixtures.

Verified JWT не доказывает доступ к accountId из URL. Используй user.sub и existing account access policy; не доверяй userId/token из клиента как authority. Cross-user, invalid/expired/superseded token и concurrent requests — обязательные cases для соответствующего изменения.

T-Bank credentials остаются server-side и хранятся encrypted. Используй existing AES-256-GCM boundary с validated 32-byte key; не печатай plaintext, шифротекст, cookie, Authorization или connection generation в logs/errors/API. Успешная замена/deletion меняет connection generation и инвалидирует её кэши; ошибка сохраняет прежнее подключение. Ключ не ротируется автоматически: новый ключ не расшифрует сохранённые credentials. Нужен исходный ключ или повторное сохранение token пользователем; сохраняй ключ отдельно от backup БД.

Не передавай Prisma User/Session целиком наружу; выбирай public DTO. Пароль обрабатывает существующий bcrypt flow. Не копируй требования о нормализации или длине из tutorial: сверяй runtime DTO, tests и feature source.

Предпочитай Prisma query API. Raw SQL допускается только по конкретной нужде с параметризованными значениями; не конкатенируй untrusted input и не передавай его в queryRawUnsafe/executeRawUnsafe. Dynamic identifiers выбирай из закрытого server-owned набора. Проверка user ownership сохраняется и в SQL.

Безопасный путь и проверка

При неясной ownership/crypto/session семантике прочитай exact source до edits. Добавляй проверку на ответственной границе; не скрывай проблему общим catch, фиктивным success или log. Logger allowlist/redaction не делает произвольный message безопасным.

Targeted auth/access/crypto/logging tests + Testing. Cookie/guard/HTTP changes требуют configured HTTP proof. Schema parity не доказывает отсутствие утечки secret.