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

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

Когда человек смотрит на чашку чая и видит в ней остывающее Солнце, а в шуме вентилятора ноутбука — отголосок грядущей тепловой смерти Вселенной, он преодолевает хаос.

Он объединяет «отдельное».

Чашка перестаёт быть просто чашкой. Шум — просто шумом. За отдельными явлениями обнаруживается связь, а за связью — целое.

В этом и начинается понимание: не в способности увидеть больше объектов, а в способности увидеть то, что их связывает.


Пролог

Обычно разговор о доступе начинается с пользователя.

Есть пользователь.
У него есть роль.
У роли есть разрешения.

Получается простая цепочка:

User → Role → Permission

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

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

Например:

User
  ↓ member of
Group
  ↓ has role in
Project
  ↓ contains
Object

Ни одна из этих связей сама по себе не является разрешением. Но вместе они могут стать основанием для него. Здесь привычная модель начинает ломаться.

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


От пользователя к объекту

Чтобы понять доступ, приходится задать другой вопрос:

Что именно пользователь пытается сделать?

Теперь появляются три элемента:

Subject → Action → Object

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

Он владелец? Участник проекта? Член группы? Получил делегирование? Имеет роль в определённой области? Объект опубликован там, где эта роль действует?

Одного ответа может быть недостаточно. Поэтому между объектом и решением возникает ещё один уровень.

Контекст.


Что означает контекст

Слово «контекст» легко превратить в ещё один технический термин.

Компания.

Проект.

Группа.

Tenant.

Scope.

Все они могут оказаться частью конкретного контекста. Но ни один из них сам по себе контекстом не является.

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

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

Например:

User A → READ → Object X

и:

User A → UPDATE → Object X

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

Контекст не является ещё одним разрешением. Он является тем, на основании чего разрешение может быть вычислено.


Отношения важнее списка разрешений

Если смотреть только на итоговое право, легко потерять причину его возникновения.

Можно увидеть:

User A → READ → Object X

и не знать, почему это разрешение существует. Но в реальной системе причина может быть важнее самого результата. Пользователь получил доступ потому, что:

User A
   ↓
member of Group G
   ↓
Group G
   ↓
has role in Project P
   ↓
Project P
   ↓
contains Object X

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


Отношения не являются разрешениями

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

Кто с кем связан.

Правило определяет:

Что эта связь означает для конкретного действия.

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

Relationship
    ↓
Context
    ↓
Rule
    ↓
Effective permission
    ↓
Decision

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


От логической модели к данным

Даже после получения ALLOW задача не заканчивается. Разрешение относится к логическому объекту. Но данные находятся физически. Один объект может соответствовать нескольким строкам. Несколько объектов могут находиться в одной таблице. Один запрос может читать данные сразу для множества объектов. Поэтому возникает второй вопрос:

Как не просто принять решение, а физически не допустить запрещённые данные?

Здесь появляются Row-Level Security (RLS, ограничение доступа на уровне строк), фильтрация запросов, представления и другие механизмы. Но это уже другой уровень ответственности.

Авторизация определяет допустимость действия. Механизм применения ограничивает физические данные.


Зачем нужна вся эта сложность

Можно задать справедливый вопрос:

Не проще ли просто использовать роли?

Иногда — да. Если система проста, простая модель лучше сложной. Но сложность нельзя устранить, если она уже существует в предметной области. Если в системе есть:

много субъектов
+
много объектов
+
отношения между ними
+
иерархии
+
области действия
+
публикации
+
делегирование
+
массовый доступ к данным

то эти отношения всё равно существуют. Их можно либо выразить в модели явно, либо спрятать в наборе специальных исключений, условий и фильтров. Второй вариант не делает систему проще. Он только делает модель менее заметной.


О чём эта книга

Эта книга не начинается с конкретной технологии. Она начинается с вопроса:

Что должно быть известно системе, чтобы принять правильное решение о доступе?

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

Из этих фактов формируется контекст. К контексту применяются правила. Получается эффективное разрешение.

После этого решение должно быть применено к данным. Так возникает последовательность:

Object
   ↓
Relationships
   ↓
Relevant facts
   ↓
Context
   ↓
Rules
   ↓
Effective permission
   ↓
Authorization
   ↓
Data enforcement

Эта последовательность и будет предметом книги. Не как конкретный продукт. Не как конкретный фреймворк. И не как единственно возможная реализация.

А как способ смотреть на систему, в которой доступ определяется не одним свойством пользователя, а отношениями между объектами, субъектами и контекстом их взаимодействия.