54 lines
4.1 KiB
Markdown
54 lines
4.1 KiB
Markdown
# 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`. Дальнейшее развитие механизма защиты предусматривает
|
||
ротацию ключей шифрования.
|