4.1 KiB
ADR-003: защита и обновление OAuth-токенов
Статус: Принято
Дата: 2026-07-23
Контекст
Для выполнения REST-запросов приложение хранит access_token и refresh_token.
Битрикс24 возвращает новую пару токенов при каждом обновлении, поэтому
одновременное использование одного refresh-токена несколькими воркерами может
привести к потере актуальной пары.
Решение
До передачи в PostgreSQL access_token и refresh_token шифруются алгоритмом
Fernet. Общий TOKEN_ENCRYPTION_KEY передаётся контейнерам site и bot через
переменные окружения, но не записывается в базу. Бот расшифровывает access-токен
непосредственно перед REST-запросом и не включает OAuth-параметры в тексты
ошибок.
Принятые меры защиты сведены в таблицу.
| Риск | Реализованная мера | Остаточный контроль |
|---|---|---|
| Утечка одноразовой ссылки из БД | Хранение SHA-256-хеша | Короткий TTL и однократное погашение |
| Чтение OAuth-токенов из БД | Fernet-шифрование до INSERT/UPDATE | Секретный ключ вне БД |
| Подмена пользователя | member_id/user_id из OAuth + user.current | Проверка HTTPS endpoint |
| Гонка refresh token | Версия и аренда refresh_locked_until | Повторное чтение до версии N+1 |
| Избыточные права приложений | Разные роли и EXECUTE только на функции | REVOKE для PUBLIC |
| Долгая транзакция | Сетевые запросы выполняются вне транзакции | Короткие контексты Psycopg |
Таблица ADR-003/1. Риски и меры защиты от них
При получении expired_token, invalid_token или no_auth_found клиент
пытается обновить пару токенов. Поле version реализует оптимистическую
проверку, а refresh_locked_until — короткую аренду продолжительностью 30
секунд. Это предотвращает одновременное использование одного refresh-токена
несколькими воркерами.
После успешного обновления токенов воркер освобождает аренду. Если она занята, другой воркер ожидает обновления, после чего повторяет обращение к API с новой парой токенов.
Рисунок ADR-003/1. Диаграмма последовательности обновления OAuth-токена
Последствия
Сетевой запрос к OAuth выполняется вне транзакции PostgreSQL. Версия и аренда
координируют обновление между воркерами, а повторное чтение позволяет продолжить
работу с версией N+1. Дальнейшее развитие механизма защиты предусматривает
ротацию ключей шифрования.
