Глава 10. Субъект
10.1 Субъект — это тот, от чьего имени выполняется действие
В начале книги мы использовали конструкцию:
Subject → Action → Object
Теперь можно рассмотреть её первый элемент подробнее.
Субъект — это сущность, от имени которой выполняется действие над объектом.
В простейшем случае субъектом является пользователь:
User A
│
│ READ
▼
Document B
Но пользователь — не единственный возможный субъект.
Действие может выполняться от имени:
-
пользователя;
-
группы;
-
сервиса;
-
технической учётной записи;
-
другого типа сущности, которому модель безопасности разрешает выступать субъектом.
Поэтому субъект — это не синоним пользователя.
10.2 Субъект определяется конкретным запросом
Один и тот же пользователь может выполнять множество действий.
Например:
User A → READ → Document X
User A → UPDATE → Document X
User A → READ → Document Y
Во всех трёх случаях субъект один.
Но контекст решений различается, потому что различаются действие и объект.
Поэтому нельзя заранее определить один «контекст пользователя», который полностью описывает все его будущие действия.
Контекст строится вокруг конкретного запроса:
Can(Subject, Action, Object).
10.3 Субъект не равен его правам
Пользователь существует независимо от того, какие разрешения ему выданы.
Это кажется очевидным, но именно здесь часто возникает архитектурная ошибка.
Можно представить модель:
User
│
└── Permissions
и начать считать permissions свойством пользователя.
Но разрешение почти никогда не существует само по себе.
Оно связано с:
-
определённым действием;
-
определённой областью;
-
определёнными отношениями;
-
иногда с определённым объектом;
-
иногда с дополнительными условиями.
Поэтому правильнее рассматривать разрешение как результат применения модели к субъекту и остальным фактам.
10.4 Один субъект может иметь несколько оснований доступа
Вернёмся к объекту Document A.
Пользователь Alice может иметь отношение к нему сразу несколькими способами:
Alice
├── owner ───────────────→ Document A
├── role ────────────────→ Project P
└── member ──────────────→ Group G
Document A
├── published in ────────→ Project P
└── published in ────────→ Group G
В этом случае один и тот же субъект участвует сразу в нескольких основаниях доступа.
Нельзя сказать, что существует одно «право Alice».
Существуют разные отношения, которые могут участвовать в одном решении.
10.5 Субъект может быть связан с другими субъектами
Субъект не обязательно связан с объектом напрямую.
Например:
Alice
│
└── member of
│
▼
Group G
│
└── relation with → Document A
Здесь между субъектом и объектом находится другое отношение.
В более сложном случае цепочка может выглядеть так:
Alice
│
▼
Group G
│
▼
Project P
│
▼
Document A
Каждая стрелка является отдельным фактом.
Наличие всей цепочки ещё не означает наличие права.
Но цепочка может оказаться частью основания, которое правило использует при принятии решения.
10.6 Субъект может иметь несколько ролей
Один пользователь может одновременно иметь разные роли.
Например:
Alice → role R1 → Company C
Alice → role R2 → Project P
Это не противоречие.
Роли имеют разные области действия.
В одной области пользователь может обладать одним набором возможностей, в другой — другим.
Поэтому вопрос:
«Какая роль у Alice?»
часто поставлен неправильно.
Более точный вопрос:
«Какие ролевые отношения Alice существуют в контексте данного действия над данным объектом?»
Это уже вопрос не о пользователе вообще, а о конкретном решении.
10.7 Субъект может получать доступ через группу
Группа позволяет отделить индивидуального пользователя от организационного отношения.
Например:
Alice
│
└── member of → Group G
Group G
│
└── relation with → Object A
При изменении членства меняется и результат последующих проверок доступа.
Сам объект при этом может вообще не измениться.
Это показывает ещё одну важную особенность модели:
доступ субъекта может зависеть от фактов, которые не являются свойствами самого субъекта и не являются свойствами самого объекта.
Они находятся между ними.
10.8 Группа не превращает пользователя в группу
Если пользователь является членом группы, это не означает, что субъект запроса автоматически заменяется группой.
Субъектом по-прежнему может оставаться:
Alice.
Группа является частью отношений, через которые определяется её доступ.
Это различие важно для аудита и для дальнейшей обработки запроса.
Система должна понимать:
кто выполняет действие
и отдельно:
через какое отношение он получил возможность его выполнить
Это разные вопросы.
10.9 Субъект и инициатор запроса могут различаться
В распределённых системах запрос часто проходит через несколько компонентов.
Например:
User A
│
▼
Frontend
│
▼
Service X
│
▼
Service Y
│
▼
Database
Физически запрос к базе выполняет сервис.
Но это ещё не означает, что субъектом бизнес-действия является сервис.
Нужно различать как минимум:
-
технического инициатора запроса;
-
субъект бизнес-действия;
-
источник аутентификации;
-
компонент, который непосредственно обращается к данным.
Если эти понятия смешать, система может проверять права не того участника, от имени которого фактически выполняется операция.
10.10 Субъект и аутентификация — разные понятия
Аутентификация отвечает на вопрос:
кто предъявил системе свои учётные данные?
Авторизация отвечает на другой вопрос:
может ли этот субъект выполнить конкретное действие?
Установленный identity ещё не означает разрешённого действия.
Например:
Authenticated User A
│
▼
Can(User A, READ, Object B)?
Первый факт подтверждает личность субъекта.
Второй требует анализа модели доступа.
Поэтому наличие действующей сессии, токена или другого механизма аутентификации не является само по себе основанием для доступа к объекту.
10.11 Субъект может быть техническим
Не каждое действие выполняется непосредственно человеком.
Например, сервис может:
-
создавать записи;
-
запускать обработку;
-
читать данные другого сервиса;
-
выполнять автоматическую операцию по расписанию.
Тогда субъектом модели может быть сервисная сущность.
Но сам принцип не меняется:
Service A → Action → Object B
Для такого субъекта также необходимо определить релевантные отношения и основания доступа.
Это позволяет применять одну модель к пользовательским и межсервисным операциям, не смешивая при этом их конкретные механизмы аутентификации.
10.12 Субъект может быть составным
Иногда действие выполняется не просто от имени одного пользователя.
Например:
Alice
+
Service A
+
Delegated Authority
В таком случае возникает вопрос, какие именно условия должны быть выполнены одновременно.
Одного факта:
Alice имеет право
может быть недостаточно.
Может требоваться:
Alice имеет право
и
Service A действует от имени Alice
и
Delegation действительна.
То есть субъект запроса может быть простым, а контекст его действия — составным.
10.13 Субъект не определяет область доступа
Сам факт существования субъекта ничего не говорит о том, где действуют его отношения.
У одного пользователя могут быть:
Role → Company A
Role → Project B
Membership → Group C
Ownership → Object D
Поэтому нельзя построить корректную модель:
Subject → Scope → Permission
как универсальную замену отношениям.
Scope относится к конкретным отношениям.
Субъект лишь участвует в этих отношениях.
10.14 Субъект не определяет объект
То же относится к объекту действия.
Один субъект может иметь совершенно разные основания доступа к разным объектам.
Например:
Alice → owner → Document A
Alice → reader → Document B
Alice → no relevant relation → Document C
То, что Alice имеет право на Document A, ничего само по себе не говорит о Document B или Document C.
Поэтому нельзя переносить разрешение с одного объекта на другой без соответствующего правила.
10.15 Субъект участвует в построении эффективного разрешения
Теперь можно вернуться к общей модели.
У нас есть:
Subject
│
├── Relations
│
└── Roles / Memberships / Other Grounds
│
▼
Context
│
▼
Rules
│
▼
Effective Permission
Субъект является одной из координат решения.
Но он не содержит решение внутри себя.
Чтобы определить эффективное разрешение, необходимо сопоставить субъекта:
-
с действием;
-
с объектом;
-
с релевантными отношениями;
-
с областями действия этих отношений;
-
с другими фактами и ограничениями.
10.16 Один субъект — разные результаты
Пусть существует два запроса:
Can(Alice, READ, Document A)
Can(Alice, UPDATE, Document A)
Субъект одинаков.
Объект одинаков.
Но действия различаются.
Поэтому результат может быть разным.
Теперь изменим объект:
Can(Alice, READ, Document B)
Даже при том же субъекте и том же действии результат снова может измениться.
Таким образом:
Permission ≠ Property(Subject)
Эффективное разрешение возникает из отношения субъекта к конкретному действию и конкретному объекту в определённом контексте.
10.17 Что важно сохранить в модели
Из этого следуют несколько ограничений.
Нельзя:
-
считать пользователя единственным возможным субъектом;
-
хранить все права как глобальные свойства пользователя;
-
заменять отношения пользователя группой;
-
считать членство в группе готовым разрешением;
-
переносить право одного объекта на другой;
-
считать аутентификацию авторизацией;
-
считать технического исполнителя запроса автоматически субъектом бизнес-действия.
Все эти упрощения могут работать в маленькой системе.
Но по мере роста числа отношений они начинают скрывать сам механизм возникновения доступа.
10.18 Субъект — точка входа, но не источник разрешения
Теперь можно уточнить исходную формулу.
Мы начали с:
Subject → Action → Object
Она определяет что именно требуется проверить.
Но для самой проверки этого недостаточно.
Необходимо найти факты, связывающие субъекта с объектом и окружающими его сущностями:
Subject
│
├── direct relations
├── memberships
├── roles
├── ownership
├── delegations
└── other relevant facts
│
▼
Context
│
▼
Rules
│
▼
Effective Permission
Следовательно, субъект является не источником разрешения, а участником отношения, из которого разрешение может быть выведено.
10.19 Главный вывод
Субъект — это участник конкретного действия, а не контейнер всех своих прав.
Им может быть пользователь, группа, сервис или другая сущность, допускаемая моделью безопасности.
Один субъект может иметь множество отношений, ролей и оснований доступа.
Эти отношения могут действовать в разных областях и приводить к разным результатам для разных объектов и действий.
Поэтому эффективное разрешение нельзя определить только по субъекту.
Нужна вся конструкция:
Subject
+
Action
+
Object
+
Relevant Relations
+
Areas
+
Rules
↓
Effective Permission
Но пока мы говорили в основном о том, откуда берутся основания, а не о том, что именно они разрешают.
Следующий шаг — разобраться с ролью и разрешением: что такое permission, где появляется роль и почему даже наличие permission ещё не означает доступа к конкретному объекту.