7.7. Ролевая модель доступа (RBAC) #

7.7.1. Основные положения #

Управление доступом в PPEM реализуется моделью RBAC (Role Based Access Control), которая определяет правила разграничения доступа с помощью ролей и прав. Модель устанавливает следующие базовые соглашения:

  • Объект — ресурс, к которому должен быть предоставлен или ограничен доступ.

  • Субъект — человек (пользователь) или автоматизированный агент.

  • Право — разрешение на выполнение операции над объектом.

  • Роль — рабочая функция или название, которое определяется на уровне авторизации.

Базовые соглашения определяют расширенные соглашения:

  • Правило доступа — совокупность роли, прав и связей между ними.

  • Сеанс — соответствие между субъектом и ролью.

  • Один субъект может иметь несколько ролей.

  • Одну роль можно назначить нескольким субъектам.

  • Одна роль может иметь несколько прав.

  • Одно право можно выдать нескольким ролям.

Примечание

Права не назначаются субъектам напрямую, а приобретаются субъектами через роли.

7.7.2. RBAC в PPEM #

Базовые утверждения:

  • Функциональность PPEM состоит из плагинов.

  • Каждый плагин позволяет управлять конкретным ресурсом.

  • Управление ресурсом включает в себя базовые CRUD-операции: создание, просмотр, редактирование, удаление.

  • Дополнительно управление ресурсом может включать в себя различные RPC-операции, их имена зависят от операции по управлению ресурсом.

  • Права предоставляют субъектам доступ к различным операциям. Управление любым ресурсом также осуществляется через права (базовый минимум):

    • РЕСУРС\_create

    • РЕСУРС\_view

    • РЕСУРС\_edit

    • РЕСУРС\_delete

  • Права включаются в роли.

  • Роли могут назначаться субъекту как в момент создания субъекта, так и позже.

  • При получении от субъекта запроса на выполнение операции плагин проверяет право субъекта на доступ к запрошенной операции.

  • Субъекты (пользователи) могут создавать собственные роли (при наличии прав) и назначать эти роли другим субъектам (пользователям).

  • Права и роли могут быть объектно-привязанными. Это означает, что можно указать роль и право, разрешающее доступ к ограниченному набору объектов.

  • Привязка к объекту может осуществляться на уровне роли (все субъекты с этой ролью имеют доступ к объекту) или на уровне пользователя (доступ к объекту имеет только один пользователь).

7.7.2.1. Субъекты #

Субъектами могут выступать:

  • Пользователи. Роли назначаются пользователям в момент создания. Если роли не указаны явно, может быть назначена роль по умолчанию.

  • Агенты. Эта роль назначается при создании или регистрации агента.

7.7.2.2. Объекты #

Объектами могут выступать как ресурсы, так и представления ресурсов в репозитории, например серверы, агенты, экземпляры, пользователи и группы пользователей.

7.7.2.3. Настройка прав и ролей #

При первом запуске PPEM выполняется инициализация репозитория, при которой заполняются служебные таблицы (права и роли).

При инициализации для каждого плагина устанавливается свой набор прав, ролей и отношений «роль-право». Например, для плагина accounts создаются свои права и роли для управления доступом к объектам этого плагина. Для других плагинов также создаются свои наборы прав и ролей для управления доступом к объектам этих плагинов.

При наличии необходимых прав пользователи могут создавать пользовательские роли, указывать наборы прав, связывать роли с объектами и назначать пользовательские роли субъектам.

7.7.3. Реализация #

Права доступа реализованы следующим набором таблиц, которые принадлежат плагину accounts:

  • privileges: права с указанием класса объектов, к которым они регулируют доступ.

  • roles: роли с указанием класса объектов, на которые нацелена роль.

  • role_privileges: отношение типа «роль-право», устанавливающее связь между ролями и входящими в них правами.

  • users: пользователи системы (субъекты).

  • user_roles: отношение типа «пользователь-роль», устанавливающее связь между пользователями и назначенными им ролями.

  • user_privileges: представление (view), отображающее связи «пользователь-право».

  • groups: группы системы.

  • group_roles: отношение типа «группа - роль», устанавливающее связь между группами и назначенными им ролями.

  • group_users: отношение типа «группа-пользователь», устанавливающее связь между группами и входящими в них пользователями.

7.7.3.1. Таблица privileges #

Таблица имеет следующие поля:

  • id: уникальный идентификатор права.

  • name: уникальное имя права.

  • title: описание права.

  • class: класс объектов, для доступа к которым используется право.

  • source: имя плагина, который устанавливает право и в дальнейшем осуществляет проверку доступа.

Таблица заполняется менеджером с помощью миграций. Каждый плагин определяет собственный набор прав.

Для проверки прав используется HTTP middleware-обработчик. Создание, изменение и удаление прав пользователем не предусмотрено, так как проверка прав реализуется в коде менеджера.

7.7.3.2. Таблица roles #

Таблица имеет следующие поля:

  • id: уникальный идентификатор роли.

  • name: уникальное имя роли.

  • title: описание роли.

  • class: определяет класс объектов, для доступа к которым используется это право. Значение поля используется в пользовательском интерфейсе как подсказка, чтобы получить права соответствующего класса и список объектов этого класса.

  • source: имя плагина, который устанавливает роль. В случае пользовательских ролей устанавливается значение user.

Роли создаются менеджером с помощью миграций. Базовый набор ролей устанавливается для плагина accounts.

Пользователь через API менеджера может создавать, изменять и удалять пользовательские роли, но не может изменять или удалять роли, установленные менеджером (системные роли).

7.7.3.3. Таблица role_privileges #

Таблица устанавливает связи между ролями и правами и имеет следующие поля:

  • id: уникальный идентификатор связи.

  • role: идентификатор роли.

  • privilege: идентификатор права.

  • parametric: указывает, используется ли привязка к объекту.

  • object: уникальный идентификатор объекта произвольного класса.

Класс объекта определяется по значению поля privileges.class. Объявленный здесь идентификатор объекта ограничивает действие права, указанного в role_privileges.privilege, одним объектом и разрешает доступ к объекту только участникам одной роли, указанной в role_privileges.role (доступ разрешён пользователям в user_roles.user, у которых user_roles.role = role_privileges.role).

Комбинация role, privilege и object является уникальным ключом с условием object IS NOT NULL.

Примечание

Параметризованное объектно-привязанное отношение «роль-право» определяет доступ только к одному объекту (через указание object). Если требуется выдать доступ к N объектам, будет создано N записей в role_privileges.

7.7.3.4. Таблица users #

Таблица не имеет полей, имеющих отношение к RBAC. При создании пользователя через API менеджера можно указать список идентификаторов ролей, которые будут назначены пользователю.

7.7.3.5. Таблица user_roles #

Таблица устанавливает связи между пользователем и ролями и имеет следующие поля:

  • id: уникальный идентификатор связи.

  • user: идентификатор пользователя.

  • role: идентификатор роли.

  • object: уникальный идентификатор объекта произвольного класса.

Класс объекта определяется по значению поля privileges.class. Объявленный здесь идентификатор объекта ограничивает действие права, указанной в role_privileges.privilege, одним объектом и разрешает доступ к объекту пользователю, указанному в user_roles.user.

Примечание

Параметризованное объектно-привязанное отношение «роль-право» определяет доступ только к одному объекту (через указание object). Если требуется выдать доступ к N объектам, будет создано N записей в role_privileges.

7.7.3.6. Представление user_privileges #

Это представление показывает пользователей с ролями и правами и позволяет проверять права конкретного субъекта:

  • user: user_roles.user

  • role: user_roles.role

  • privilege: privilege.name

  • object: user_roles.objects или role_privileges.object

7.7.3.7. Таблица groups #

Таблица не имеет полей, имеющих отношение к RBAC.

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

7.7.3.8. Таблица group_roles #

Таблица устанавливает связи между группами и ролями и имеет следующие поля:

  • group_id: идентификатор группы.

  • role_id: идентификатор роли.

  • object: уникальный идентификатор объекта произвольного класса.

Класс объекта определяется по значению поля privileges.class. Объявленный здесь идентификатор объекта ограничивает действие права, указанного в role_privileges.privilege, одним объектом и разрешает доступ к объекту пользователю, указанному в group_roles.role_id.

Примечание

Параметризованное объектно-привязанное отношение «группа-роль» определяет доступ только к одному объекту (через указание object). При необходимости выдать доступ на N объектов будет создано N записей в group_roles.

7.7.3.9. Таблица group_users #

Таблица устанавливает связи между группами и пользователями и имеет следующие поля:

  • group_id: идентификатор группы.

  • user_id: идентификатор пользователя.

Отношения «группа-пользователь» не имеют объектных привязок.

7.7.4. Объектно-привязанные роли #

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

Для более детального контроля прав доступа в поле role_privileges.object вместе с классом можно также указать идентификатор объекта. Таким образом, действие роли и права будет распространяться только на объект с указанным идентификатором. Объект можно указать в нескольких местах:

  • Для роли в role_privileges.object, тогда доступ к объекту предоставляется всем членам роли.

  • Для пользователя в user_roles.object, тогда доступ предоставляется только для одного пользователя.

  • Для группы в group_roles.object, тогда доступ предоставляется только для пользователей группы.

7.7.5. Проверка прав доступа у субъектов #

В процессе аутентификации субъекта создаётся сам сеанс, а также сессионные токены JWT. При создании токена доступа в него вкладывается user_id. Когда пользователь отправляет запросы на выполнение операций, токен доступа добавляется в заголовки запроса.

Менеджер выполняет авторизацию, извлекает из токена доступа user_id пользователя и через роли проверяет наличие права. При наличии права доступ разрешается, если права нет — запрос отклоняется.

Чтобы проверить право субъекта на выполнение операции с объектом, необходимы следующие данные:

  • user_id или agent_id: идентификатор пользователя или агента.

  • class: имя класса для объекта (тип ресурса).

  • object: идентификатор объекта (необязательно).

Клиент в запросе указывает заголовок Authorization: Bearer и прикладывает токен доступа.

Сервер получает запрос и извлекает данные, необходимые для проверки доступа:

  • Значение user_id (или agent_id) извлекается из токена доступа.

  • Значение class определяется на основе права.

  • Значения object:

    • Для GET-запросов вида /resources извлекаются из URL пути и параметров запроса (ids=?).

    • Для GET-запросов вида /resources/objectID извлекаются из URL пути.

    • Для PUT-запросов извлекаются из тела запроса.

    • Для DELETE-запросов вида /resources извлекаются из тела запросов (отдельное поле в объекте).

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