Права доступа
mxApi не заводит собственной модели прав. Запрос выполняется от имени реального пользователя MODX, а доступ проверяется штатным механизмом политик на namespace mxapi. Отсюда главное следствие: интеграция не может получить больше, чем есть у её пользователя.
Два независимых ограничения
Доступ к эндпоинту решают два разных механизма, и пройти нужно оба.
| Что | Кто владеет | Смысл |
|---|---|---|
Право MODX (permission) | администратор сайта через политики | что этому пользователю вообще можно на сайте |
| Scope | тот, кто выпускает токен | что разрешено этому конкретному токену — из того, что пользователю и так можно |
Соответствие «scope → право» берётся из метаданных эндпоинтов, отдельного списка внутри аутентификации нет. Поэтому при выпуске токена запрос scope=orders.read сразу проверяется на право, объявленное эндпоинтом с этим scope: токен шире прав пользователя выдать невозможно.
Scope нужен, чтобы сузить доступ в пределах прав пользователя: одному партнёру — только чтение заказов, другому — ещё и запись, притом что пользователь у них может быть один.
Настройка доступа
- Пользователь и группа. Заведите пользователя интеграции и включите его в группу пользователей.
- Access Controls → Namespace Access: namespace
mxapi, политикаmxapiDefault(создаётся при установке) или своя на базе шаблонаmxapiTemplate. - Authority роли. Если запись доступа выдана с authority 0, а пользователь состоит в группе с ролью меньшего уровня, он получит отказ — и выглядеть это будет как проблема прав mxApi.
Политика группам не назначается автоматически: установка пакета не должна раздавать доступ к API.
Право load обязательно в любой политике mxApi
MODX требует право load при загрузке самого объекта namespace — до проверки права эндпоинта. Без него non-sudo пользователь получает отказ при полностью корректных остальных правах. В mxapiDefault оно есть; при создании своей политики на базе mxapiTemplate его нужно включить самому.
Права пакета
| Право | Что открывает |
|---|---|
load | загрузка namespace mxapi — обязательно для любой проверки |
mxapi_auth_token | выпуск токенов (POST /auth/token) |
mxapi_auth_revoke | отзыв токена (POST /auth/revoke) |
mxapi_meta_read | чтение каталога эндпоинтов и OpenAPI (scope meta.read) |
Эндпоинты из других пакетов приносят свои права mxapi_* — они появляются в шаблоне политики при установке этих пакетов.
Как это проверяется на самом деле
Знание внутренностей полезно при разборе отказов:
- Сессия обязана быть проверяемой.
modAccessibleObject::checkPolicy()выполняет проверку только при инициализированной сессии, а иначе возвращаетtrue— то есть без сессии права молча не проверялись бы вовсе. mxApi поднимает сессию сам и отказывает, если это невозможно (CLI, уже отправленные заголовки). Отказ пишется в лог MODX. - Право должно быть заведено в политике. Для non-sudo пользователя mxApi сначала убеждается, что право вообще существует в шаблоне политики, и лишь потом спрашивает MODX. Право, которого нет в политике, — это опечатка в метаданных эндпоинта или незавершённая установка пакета-провайдера, а не «доступ разрешён».
- Namespace должен иметь хотя бы одну запись доступа. Если
mxapiне выдан ни одной группе, отказ получают все non-sudo пользователи, и в лог уходит соответствующее предупреждение. - sudo проходит проверку MODX как обычно — без требования заведённого права.
Все перечисленные отказы сопровождаются записью в лог ошибок MODX с указанием права и контекста: если в ответе insufficient_permission, а причина неочевидна, смотреть нужно туда.
Контексты MODX
Права процессоров принадлежат контексту: modX::hasPermission() — это проверка политики текущего контекста, и ACL пользователя загружаются под его ключ. Поэтому контекст — часть паспорта эндпоинта, а не деталь реализации.
| Что | Где задаётся |
|---|---|
| Контекст по умолчанию | настройка mxapi.context (по умолчанию mgr) |
| Контекст эндпоинта | modx_context в его метаданных |
| Контекст из запроса | заголовок X-MxApi-Context — только для эндпоинтов, объявивших modx_context = request, и только при mxapi.allow_request_context = 1 |
| Что разрешено клиенту | поле contexts в modx_mxapi_client: пусто — только контекст по умолчанию, * — любой |
Ядро переключает контекст до проверки права эндпоинта: проверять в одном контексте, а выполнять в другом — это дыра.
На мультисайте пустое поле contexts трактуется как «только контекст по умолчанию», а не «любой»: иначе токен интеграции одного сайта работал бы на всех сразу. Контекст вызова пишется в журнал — без него в аудите «кто менял заказ» бессмысленно.
Токены, выпущенные по логину и паролю, allow-list контекстов не имеют: они ограничены правами самого пользователя в этом контексте.
Типовые причины отказов
| Ответ | Что проверить |
|---|---|
insufficient_permission | право load в политике; выдан ли namespace mxapi группе; authority роли участника группы; заведено ли само право в шаблоне политики |
insufficient_scope | scope есть на сайте, но не выдан этому токену: проверьте список scope у клиента |
invalid_scope | scope не объявлен ни одним эндпоинтом сайта — опечатка либо не установлен пакет-провайдер |
user_inactive | пользователь заблокирован или неактивен |
context_not_allowed | контекст не входит в contexts клиента, либо запрошен заголовком при выключенной mxapi.allow_request_context |
unknown_context | такого контекста в MODX нет |
