Безопасность
Пароли
- bcrypt, cost 12 — единственный принятый способ хеширования паролей клиентов.
- Timing-safe вход — фиктивное сравнение bcrypt выполняется даже когда email не существует, поэтому путь входа занимает одинаковое время, существует ли пользователь. Это предотвращает перебор пользователей и timing-атаки.
API-ключи
- HMAC-SHA256 — сервер хранит
HMAC-SHA256(secret), никогда не сам секрет. - Ротация двух секретов —
API_KEY_SERVER_SECRETиAPI_KEY_SERVER_SECRET_PREVпозволяют плавно ротировать секрет на сервере, не инвалидируя живые ключи. - Сравнение за постоянное время — подписи ключей и вебхуков сравниваются через
crypto.timingSafeEqual. - Raw-ключ показывается один раз — исходное значение возвращается только при создании и не может быть восстановлено.
Сессии
- Cookie
runne_session:HttpOnly,SameSite=Lax,Secureв production,Max-Age24ч. - Отзыв по jti — logout пишет
jtiсессии в denylist Redis с оставшимся сроком жизни токена; каждый запрос перепроверяет его. - JWT-claims валидируются, а claim
isAdminне используется для авторизации — admin-проверки читают строку клиента из базы.
CSRF (fail-closed)
Небезопасные методы (POST, PUT, PATCH, DELETE) защищены allowlist-ом Origin:
Originприсутствует, но не разрешён →403.Originотсутствует, но есть cookie сессии →403(fail-closed).Originотсутствует и cookie нет → разрешено (вебхуки,x-api-key, server-to-server).
Allowlist выводится из FRONTEND_URL (через запятую).
Rate limiting
- По API-ключу — скользящее окно (Redis Lua; in-memory fallback) на chat completions.
- По IP — auth rate limiting на login (10/мин) и register (5/мин) против перебора учётных данных.
Изоляция воркспейсов
- Каждый запрос в разрезе воркспейса проверяет владение (
workspace.customer_id == session.customer_id); несовпадение возвращает403/404. - Приостановленные клиенты и воркспейсы отклоняются шлюзом до обработки.
Финансовая безопасность
- Атомарные операции: обновление баланса + вставка в реестр в одной транзакции.
- Условные
UPDATE … WHEREпредотвращают перерасход и двойное зачисление. - Идемпотентность вебхука (проверка статуса + условное обновление + уникальный индекс) предотвращает двойное зачисление.
- Отправка чека идемпотентна и best-effort (повторяется cron-ом, никогда не роняет вебхук).
Известные ограничения (beta)
- Скоуп
models:readпока не применяется (каталог моделей публичный). - Поля квоты, кроме
tokens_per_month, заявлены, но не применяются. - Подпись вебхука опирается на
YOOKASSA_WEBHOOK_SECRET; ротируйте его вместе с серверными секретами.
Связанное
- Аутентификация — детали ключей и сессий.
- Принципы — гранты возможностей.
- Лимиты и квоты — применение.