SECURITY CHECKLISTUPDATED 20.08.2026

Service-to-service API authentication в betting-инфраструктуре

Service-to-service API нужен собственный контур доверия: явная identity, ограниченный scope, управляемая ротация credential и понятный отказ без утечки секретов в логи.

CONTROL CHECK
  • identity is explicit
  • scope is minimal
  • secret lifecycle exists
  • failure is observable
  • evidence survives review
Ноутбук с Linux-консолью — рабочая среда для проверки инфраструктурных настроек
Фото: VectorVoyager / Wikimedia Commons, CC BY-SA 4.0; кадрирование для обложки.

Внутренний API в betting-платформе нередко получает больше доверия, чем внешний, хотя именно service-to-service вызовы проходят через самые чувствительные контуры: ingest, pricing, trading state, wallet-adjacent сервисы, операционные консоли. Надёжная схема начинается с явной идентичности вызывающего сервиса и заканчивается проверяемым отказом, когда эта идентичность неверна или просрочена.

«Находится в нашей сети» — не идентичность

IP allowlist и private network могут быть дополнительным ограничением, но сами по себе плохо отвечают на вопрос, кто делает запрос. Для критичного API полезно иметь отдельную service identity, ограниченный audience и минимальный scope. Тогда компрометация одного consumer не автоматически открывает соседние методы и сервисы.

Конкретный механизм зависит от инфраструктуры: короткоживущие токены, mutual TLS, workload identity или их комбинация. Важнее свойства: credential нельзя бездумно переиспользовать в другом контуре, его можно отозвать/ротировать, а сервер проверяет не только подпись, но и ожидаемого получателя и срок действия.

Ротация проверяется до инцидента

Документ «ключи ротируются» мало ценен, пока никто не проверил сам переход. Нормальный тест включает период overlap, появление нового credential, прекращение использования старого и наблюдаемость отказов. Если consumer продолжает неделями ходить со старым ключом, это должно быть видно до момента принудительного отключения.

Особенно опасны секреты, зашитые в image, mobile bundle, конфигурацию, которую копируют между окружениями, или URL query. Credential lifecycle должен быть частью deployment path, а не ручным действием отдельного человека.

Fail-closed не означает «положить весь live-path»

На ошибке аутентификации сервер не должен угадывать намерение и пропускать запрос. Но клиентский контур обязан понимать, как безопасно деградировать: прекратить изменение состояния, сохранить диагностический сигнал, не уйти в бесконечный retry storm и не подменить security failure обычным timeout.

Для операций чтения и изменения могут существовать разные режимы деградации. Например, read-only витрина способна продолжить показывать уже подтверждённый snapshot с явным freshness marker, тогда как mutation требует жёсткого отказа. Это продуктово-архитектурное решение, а не свойство протокола авторизации.

Какие события нужны в observability

  • идентификатор вызывающей service identity без вывода самого секрета;
  • target service и метод/operation class;
  • тип отказа: expired, wrong audience, unknown key, policy deny;
  • correlation/trace identifier для связи с соседними сервисами;
  • результат ротации и использование старых credential после cutover.

Логировать полный токен ради удобства расследования нельзя: это превращает observability pipeline в новый credential store. Для диагностики достаточно безопасных идентификаторов и проверяемого результата.

Проверка перед production

Полезный security test — намеренно отправить корректно подписанный запрос с неправильным audience, просроченным credential и credential другого сервиса. Если все три проходят, система фактически проверяет криптографическую оболочку, но не авторизацию контекста. Если же отказ невозможно отличить от сетевой ошибки, дежурной команде будет трудно быстро найти причину.

Отдельно проверить machine-to-machine authorization

Аутентифицированный сервис не обязательно имеет право выполнять любое действие. Policy должна учитывать operation и scope, а deny — логироваться как самостоятельное событие. Особенно полезен negative test, где валидная identity пытается обратиться к соседнему competition/provider scope: именно он показывает, существует ли реальная граница авторизации.

Кэши credential и clock skew проверяются как часть отказа

Короткоживущий credential полезен только тогда, когда сервисы согласованно понимают его срок. Разница часов, агрессивный cache публичных ключей или запоздалая policy update способны создать серии отказов сразу после rotation. Это не повод расширять допустимое окно до бесконечности. Лучше наблюдать skew, версию key set и время последнего refresh, а в тесте специально воспроизводить пограничный момент до и после истечения срока. Тогда отказ становится диагностируемым, а не выглядит как случайный сетевой flake.

Для partner API отдельно учитывается граница между технической идентичностью интеграции и правами конкретного бизнеса/tenant. Один успешно проверенный client credential не должен автоматически открывать данные или операции другого scope.

Identity и право на операцию проверяются раздельно

Успешный mutual TLS или валидный token отвечает на вопрос «кто вызывает сервис», но не обязательно «что этому caller разрешено». Для чувствительных методов полезен negative test: валидная service identity запрашивает соседний tenant, provider или operation scope и должна получить предсказуемый deny. Связь с least privilege и separation of duties здесь прямая: принцип минимальных полномочий должен работать одинаково для людей и machine identities, а отказ — оставлять диагностируемый audit signal без утечки credential.

ДАЛЬШЕ ПО ТЕМЕSecurity checklistАутентификация service-to-service APIProtocol explainerПодпись входящего webhookОпорный материалSecurity & Compliance