В нескольких сервисах правила доступа дублируются и постепенно расходятся. Какой архитектурный механизм уме...

В нескольких сервисах правила доступа дублируются и постепенно расходятся. Какой архитектурный механизм уменьшит риск таких расхождений?

Проходите собеседования с ИИ помощником Hintsage

Краткий ответ

Используйте единый пункт принятия решений о доступе — PDP, Policy Decision Point, — к которому сервисы обращаются за решением по политике. Сами сервисы остаются точками применения решения, PEP, но не дублируют его правила.

Это уменьшает риск того, что одинаковый пользователь получит разные права в разных сервисах. Одновременно появляется зависимость от доступности, производительности и корректности центрального компонента, поэтому нужны кэширование с контролем срока действия, отказоустойчивость и безопасное поведение при недоступности PDP.

Исторический контекст

Когда приложение состояло из одного монолита, правила доступа часто хранились рядом с бизнес-логикой. С ростом числа сервисов их начали копировать в разные команды и компоненты, из-за чего политики становились несогласованными и их было трудно централизованно изменять или проверять.

Разделение на PDP и PEP возникло как архитектурный способ отделить принятие решения от его применения. PDP отвечает на вопрос, разрешено ли действие, а PEP не позволяет выполнить операцию без полученного решения.

Постановка проблемы

Если каждый сервис самостоятельно реализует одно и то же правило, между реализациями неизбежно возникают различия: один сервис учитывает владельца ресурса, другой проверяет только роль, третий использует устаревшую версию политики.

Последствие — обход ограничения через менее защищённый сервис. Даже если основной интерфейс корректно запрещает действие, злоумышленник может обратиться к другому компоненту, где проверка неполна или трактует правило иначе.

Подробное решение

В централизованной схеме сервис передаёт PDP контекст запроса: субъект, действие, ресурс и необходимые атрибуты. PDP применяет единую версию политики и возвращает разрешение или отказ, после чего PEP блокирует операцию либо передаёт её бизнес-логике.

Централизация должна касаться именно решения по политике, а не обязательно всего контроля. Сервис всё равно обязан проверять корректность контекста, наличие ресурса и неизменность критичных данных; нельзя безоговорочно доверять параметрам, присланным клиентом.

Главный выигрыш — единообразие правил, единая точка аудита и более контролируемое изменение политик. Изменение можно выполнить один раз и распространить на все сервисы, вместо поиска множества копий логики.

Главный компромисс — дополнительная задержка и новая критичная зависимость. Если PDP недоступен, безопасное действие по умолчанию для чувствительных операций — отказать, а не разрешить; иначе временный сбой превратится в обход авторизации.

Кэширование решений снижает задержку и нагрузку, но создаёт риск использования устаревшего разрешения. Для операций с высокой ценой ошибки нужны короткий срок жизни кэша, привязка к версии политики и возможность немедленно отзывать критичные права.

Сам PDP становится ценным объектом атаки. Его нужно защищать аутентификацией сервисов, минимальными правами, изоляцией, журналированием решений и контролем изменений политик. Централизация уменьшает расхождение правил, но не устраняет необходимость проверять границы доверия в каждом сервисе.

Ситуация из практики

В платформе есть сервисы заказов, возвратов и выплат. Правило гласит: оператор может отменить заказ только в своём подразделении, но сервис выплат проверяет лишь роль оператора. Злоумышленник с доступом к интерфейсу выплат получает возможность отменить чужой заказ через менее защищённый маршрут.

Рассматривались три варианта. Первый — исправить проверку только в сервисе выплат: это быстро, но сохраняет дублирование и риск повторной ошибки. Второй — вынести общую библиотеку авторизации: она уменьшает расхождения, однако разные версии библиотеки и локальные исключения всё равно могут привести к неодинаковому поведению. Третий — использовать общий PDP с обязательным PEP в каждом сервисе.

Выбран третий вариант: политики подразделения и операции хранятся централизованно, а сервисы передают PDP идентификатор субъекта, действие и идентификатор заказа. Для недоступности PDP операции отмены и выплаты настроены на отказ, а решения для малочувствительных операций кэшируются ограниченное время.

В результате правило стало единым для всех маршрутов, а аудит показал, какой субъект, ресурс и версия политики привели к разрешению. При этом локальные проверки существования заказа и его текущего состояния сохранились в самих сервисах.

Что кандидаты часто упускают

  1. Должен ли сервис доверять положительному ответу PDP без дополнительных проверок?

Нет. PDP может подтвердить право субъекта выполнить действие, но не знает всех бизнес-условий текущей транзакции. Сервис должен самостоятельно проверить, что ресурс существует, находится в допустимом состоянии, принадлежит указанному контексту и что переданные атрибуты не были подменены.

Например, решение может быть принято для заказа, который принадлежал подразделению субъекта десять секунд назад, но уже был перемещён. Авторизация и проверка актуального состояния — связанные, но разные обязанности.

  1. Что безопаснее при недоступности PDP: разрешать операции из кэша или полностью запрещать их?

Универсального ответа нет, но для критичных операций безопаснее отказать или разрешить только заранее определённый ограниченный набор действий. Использование кэша допустимо, если известны срок актуальности решения, последствия отзыва права и цена ошибки.

Кэш должен быть ограничен субъектом, действием, ресурсом и версией политики. Для операций с финансовыми последствиями или изменением прав старое разрешение обычно нельзя считать достаточным после истечения короткого срока.

  1. Не становится ли PDP единой точкой отказа и единой целью атаки?

Становится, если его развернуть как один недоступный экземпляр. Поэтому PDP обычно делают отказоустойчивым, защищают взаимной аутентификацией сервисов, ограничивают административный доступ и разделяют плоскости принятия решений и управления политиками.

Однако резервирование устраняет главным образом отказ компонента, а не ошибку политики или компрометацию администратора. Нужны независимый контроль изменений, журналирование, тестирование политик и принцип наименьших привилегий для самих операторов и сервисов.