Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Глава 14. Когда одного отношения недостаточно

14.1 Прямое отношение — только самый простой случай

До сих пор мы часто использовали простую форму:

Subject → Relation → Object

Например:

Alice → owner → Document A

Здесь всё понятно.

Субъект непосредственно связан с объектом.

Но во многих системах такая связь отсутствует.

Например:

Alice → member → Group A
Group A → member of → Project P
Project P → contains → Document A

Alice не связана с Document A напрямую.

Тем не менее эта цепочка может иметь значение для доступа.


14.2 Отношение может быть промежуточным

Рассмотрим другой пример:

Alice → employee of → Company C
Company C → customer of → Service S
Service S → owns → Document A

Чтобы определить доступ Alice к документу, необходимо пройти несколько отношений.

Ни одно из них само по себе не отвечает на вопрос:

Can(Alice, READ, Document A)?

Но вместе они могут образовать основание для ответа.

Получается:

Alice
  ↓
Company C
  ↓
Service S
  ↓
Document A

Доступ определяется не одним отношением, а структурой отношений.


14.3 Цепочка отношений не означает автоматически наличие права

Здесь легко сделать ошибочный вывод:

если между субъектом и объектом существует путь, значит доступ разрешён.

Это неверно.

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

Например:

Alice → member → Group A
Group A → related to → Document A

Из этого ещё не следует:

Alice → READ → Document A

Потому что отношение related to может вообще не иметь значения для безопасности.

Даже если оно имеет значение, правила должны определить, какое именно значение.


14.4 Путь становится основанием только по правилу

Предположим, модель определяет:

member(Group)
+
contains(Group, Object)
→
READ(Object)

Тогда путь:

Alice → member → Group A
Group A → contains → Document A

становится основанием для READ.

Но это происходит не потому, что система «нашла путь».

Происходит другое:

правило интерпретирует определённую структуру отношений как основание доступа.

Это принципиальное различие.


14.5 Отношения могут иметь разную семантику

Рассмотрим три пути:

Alice → member → Group A
Alice → owner → Document A
Alice → reviewer → Document A

Все три являются отношениями.

Но их смысл различается.

owner может давать одни действия.

reviewer — другие.

member может вообще не давать непосредственного доступа к объекту.

Поэтому нельзя заменить все отношения одним понятием:

related

Отношение должно сохранять свою семантику.


14.6 Цепочка может состоять из разных типов отношений

Например:

Alice
  ↓ member
Group A
  ↓ belongs to
Project P
  ↓ contains
Document A

Здесь используются три разных отношения:

member
belongs to
contains

Их нельзя рассматривать как три одинаковых шага.

У каждого отношения есть собственный смысл и собственные правила.

Именно поэтому модель доступа работает не с простой топологией графа, а с семантическими отношениями.


14.7 Длина цепочки тоже имеет значение

Пусть модель разрешает:

Alice → member → Group A
Group A → member of → Project P
Project P → contains → Document A

Можно ли пройти ещё один уровень?

Например:

Alice
 → Group A
 → Group B
 → Project P
 → Document A

Это уже другой вопрос.

Если модель разрешает транзитивность, путь может продолжаться.

Если нет — цепочка заканчивается.

Следовательно, само наличие графа отношений ещё не определяет правила его обхода.


14.8 Иерархия не равна наследованию прав

Особенно часто эти понятия смешивают.

Пусть:

Group A
   ↓
Group B
   ↓
Group C

Это означает, что между группами существует иерархическое отношение.

Но из этого не следует автоматически:

право Group A
    ↓
право Group B
    ↓
право Group C

Наследование прав — отдельное правило.

Иерархия создаёт структуру.

Правило доступа определяет, как эта структура используется.


14.9 Иерархия может использоваться в обеих сторонах отношения

Иерархия может находиться со стороны субъекта:

Alice → member → Group C
Group C → child of → Group B
Group B → child of → Group A

Или со стороны объекта:

Document A → belongs to → Folder C
Folder C → child of → Folder B
Folder B → child of → Folder A

Возможен и более сложный случай:

Alice
  ↓
Group C
  ↓
Project P
  ↓
Folder B
  ↓
Document A

Тогда контекст доступа включает отношения с обеих сторон.


14.10 Один путь может быть недостаточным

Предположим:

Alice → member → Group A
Group A → contains → Document A

и одновременно:

Document A → status → Draft

Правило может требовать:

Membership
+
Publication
+
Object state

Тогда одного графового пути недостаточно.

Необходимо ещё проверить состояние объекта.

Это возвращает нас к главному принципу предыдущих глав:

контекст состоит не только из отношений между субъектом и объектом.


14.11 Цепочка отношений — часть контекста

Теперь можно уточнить понятие контекста.

Если доступ определяется через:

Alice
 → member of Group A
 → member of Project P
 → access to Document A

то для конкретного запроса релевантным является не только факт:

Alice → member → Group A

Но и структура отношений, связывающая субъект с объектом.

Таким образом:

Context
  =
  Direct relations
  +
  Relevant relation chains
  +
  Areas
  +
  Conditions
  +
  Object facts

Это не означает, что весь граф системы становится частью каждого запроса.

В контекст попадают только релевантные отношения.


14.12 Контекст не обязан содержать весь граф

В большой системе могут существовать миллионы отношений.

Для проверки:

Can(Alice, READ, Document A)?

нет необходимости рассматривать все отношения Alice.

Тем более не нужно рассматривать отношения всех пользователей системы.

Необходим только тот фрагмент модели, который может повлиять на конкретное решение.

Именно поэтому контекст — это не копия графа.

Это релевантная часть модели отношений для конкретного решения.


14.13 Один субъект может иметь несколько путей к объекту

Например:

Path A:
Alice → owner → Document A

Path B:
Alice → member → Group A
Group A → access to → Document A

Path C:
Alice → role → Reviewer
Reviewer → applies to → Project P
Project P → contains → Document A

Все три пути могут привести к одному результату:

READ

Но основания различаются.

Это полезно по двум причинам.

Во-первых, удаление одного пути не обязательно удалит доступ.

Во-вторых, для аудита можно определить, почему доступ существовал.


14.14 Один путь может давать несколько разрешений

Цепочка отношений также не обязана соответствовать одному permission.

Например:

Alice → owner → Document A

правило может определить:

READ
UPDATE
CLOSE

То есть отношение является основанием, а набор разрешений определяется правилом.

Поэтому:

Relation ≠ Permission

остаётся верным и для многошаговых отношений.


14.15 Разные пути могут давать разные разрешения

Теперь:

Path A → READ
Path B → UPDATE
Path C → APPROVE

Если все три пути применимы, эффективный результат может быть:

READ
UPDATE
APPROVE

Но снова важно не потерять область действия каждого пути.

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

Другой — только для определённого типа объектов.

Третий — только при определённом состоянии объекта.

Поэтому путь всегда нужно рассматривать вместе с его условиями применимости.


14.16 Отношения могут зависеть друг от друга

Не все цепочки являются независимыми.

Например:

Alice → member → Group A
Group A → access to → Project P

Если Alice больше не является членом Group A, второй факт сам по себе не должен продолжать давать ей доступ.

То есть:

Path validity
=
Validity(Relation 1)
AND
Validity(Relation 2)

В этом смысле цепочка отношений похожа на логическое условие.

Каждое звено необходимо для сохранения пути.


14.17 Изменение промежуточного отношения может изменить доступ

Это особенно важно для архитектуры.

Пусть:

Alice → member → Group A
Group A → access → Project P
Project P → contains → Document A

Изменяется только:

Alice → member → Group A

Сам документ не изменился.

Проект не изменился.

Правило доступа не изменилось.

Но доступ Alice к документу может исчезнуть.

Следовательно:

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

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


14.18 Изменение объекта может изменить сразу много путей

Обратная ситуация.

Пусть объект:

Document A

участвует сразу в нескольких отношениях:

published in Project P
belongs to Group A
owned by Alice

Изменение одного свойства объекта может сделать недействительными несколько оснований доступа.

Например, изменение состояния объекта:

Draft → Archived

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

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


14.19 Цепочки отношений образуют граф

На этом уровне удобно использовать графовое представление:

        Group A
        ↑     ↓
     member  contains
      ↑         ↓
    Alice → Document A

Вершины графа — сущности.

Рёбра — отношения.

Но для авторизации одного графа недостаточно.

Нужно ещё определить:

какие отношения значимы;
какие пути допустимы;
какая длина пути допустима;
какие области применяются;
какие permissions возникают;
какие ограничения действуют.

Именно правила превращают граф отношений в модель доступа.


14.20 Это уже другой уровень сложности

При прямом отношении вопрос выглядит так:

Does Alice relate to Document A?

При многошаговом:

Is there a valid relation path
from Alice to Document A
that satisfies the access rules?

Это принципиально разные задачи.

Вторая требует учитывать структуру отношений.

Поэтому с ростом числа типов сущностей и отношений простая модель:

User → Role → Permission

становится всё менее достаточной.


14.21 Но граф сам по себе не является моделью разрешений

Важно не сделать следующий шаг слишком быстро.

Можно построить огромный граф отношений и всё равно не получить работающую модель безопасности.

Потому что граф отвечает на вопрос:

что с чем связано?

А модель доступа должна отвечать на другой вопрос:

какие из этих связей и каким образом влияют на конкретное действие?

Поэтому:

Graph
+
Semantics
+
Rules
=
Access Model

14.22 Связи между субъектами тоже могут быть частью основания

Ранее мы в основном рассматривали путь:

Subject → Group → Object

Но отношения могут быть сложнее:

Alice → manager of → Bob
Bob → owner of → Document A

Модель может разрешать Alice выполнять определённые действия над объектами Bob.

В этом случае объект вообще не связан с Alice напрямую.

Но и здесь нельзя автоматически считать manager of разрешением.

Необходимо правило, которое определяет смысл этой связи.


14.23 Делегирование особенно хорошо показывает многошаговость

Рассмотрим:

Alice → delegates → Bob
Bob → reviewer of → Document A

Если модель разрешает делегирование полномочий, то Alice может получить право, связанное с ролью Bob.

Но это уже требует нескольких проверок:

делегирование существует
        AND
делегирование действительно
        AND
Bob имеет соответствующее отношение
        AND
правило разрешает передачу этого права

Одного отношения здесь явно недостаточно.


14.24 Не всякая транзитивность безопасна

Если система разрешает:

A → related → B
B → related → C

это не означает, что:

A → related → C

должно считаться эквивалентным.

Для некоторых отношений транзитивность естественна.

Для других она совершенно неверна.

Например, parent of может образовывать иерархию.

Но reviewed by не означает, что связанные через два шага объекты автоматически имеют такое же отношение.

Следовательно:

транзитивность — это свойство конкретного отношения или правила, а не общего свойства графа.


14.25 То же относится к наследованию

Если:

A → parent → B

то возможны разные правила:

rights(A) → rights(B)

или:

rights(B) → rights(A)

или вообще:

no rights inheritance

Сама связь parent ничего из этого не определяет.

Это должна определить модель.


14.26 Почему многошаговые отношения усложняют систему

С появлением цепочек возникают дополнительные вопросы:

  • какие отношения можно соединять;

  • в каком направлении;

  • какие пути допустимы;

  • где заканчивается поиск;

  • что считается валидным путём;

  • какие отношения дают permission;

  • какие только ограничивают путь;

  • как учитывать области;

  • как учитывать состояние объектов;

  • что происходит при нескольких путях;

  • что происходит при конфликте путей.

Именно поэтому сложная авторизация — это не просто большое количество permissions.

Это большая модель отношений.


14.27 Но сложность должна оставаться объяснимой

Хорошая модель должна позволять ответить не только:

ALLOW

но и:

почему ALLOW?

Например:

Alice
  → member of Group A
  → Group A has access to Project P
  → Document A belongs to Project P
  → rule grants READ

Такой результат можно проверить.

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


14.28 Что добавилось к нашей модели

После этой главы мы можем представить доступ так:

                 Subject
                    │
                    ▼
             Direct Relations
                    │
                    ▼
           Relation Chains
                    │
                    ▼
             Relevant Context
                    │
             ┌──────┴──────┐
             ▼             ▼
        Access Grounds   Constraints
             │             │
             └──────┬──────┘
                    ▼
             Effective Permission
                    │
                    ▼
             Access Decision

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


14.29 Главный вывод

Одного отношения достаточно только для простейшего случая:

Subject → Relation → Object

В реальных системах основание доступа часто строится из нескольких отношений:

Subject
  ↓
Relation
  ↓
Intermediate Object
  ↓
Relation
  ↓
Object

Но наличие пути само по себе не означает наличие права.

Путь становится основанием доступа только тогда, когда правило модели придаёт этому пути соответствующий смысл.

Поэтому нужно различать:

Связь       → что соединяет сущности
Путь        → как отношения образуют цепочку
Контекст    → какие из этих отношений релевантны
Основание   → почему путь может участвовать в доступе
Permission  → какое действие становится допустимым

И здесь появляется следующий уровень вопроса.

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

С этого начинается следующий этап — разделение исходных и производных фактов.