Глава 17. Проекции безопасности
17.1. Почему появляется проекция
К этому моменту модель уже содержит несколько уровней:
Source facts
↓
Relationships
↓
Context
↓
Rules
↓
Effective permissions
Если все эти вычисления выполнять непосредственно во время каждого запроса, проверка доступа может превратиться в обход сложного графа отношений.
Поэтому часть результата можно вычислить заранее.
Так появляется проекция безопасности.
Проекция — это производное представление исходной модели, подготовленное для определённого класса проверок.
17.2. Проекция не является второй моделью
Проекция не должна становиться независимым источником истины.
Например:
UserGroupLink
является исходным фактом.
А:
effective_user_group
является производным представлением.
Если удалить исходную связь, проекция должна измениться.
Поэтому:
Source facts → Projection
а не:
Source facts ↔ Projection
Проекция существует ради вычисления и проверки.
17.3. Какие результаты имеет смысл материализовать
В сложной системе обычно не требуется заранее создать запись для каждой комбинации:
User × Action × Object
Это может быть слишком дорого.
Гораздо полезнее материализовать устойчивые промежуточные результаты.
Например:
effective_user_group
effective_user_permission
object_scope
Они представляют разные части модели.
Первая описывает производные отношения субъекта и групп.
Вторая — эффективные разрешения субъекта в определённых областях.
Третья — области и основания, относящиеся к объекту.
17.4. Проекция строится из фактов и правил
Концептуально построение можно представить так:
function rebuildProjection(sourceFacts):
relevantFacts = selectRelevantFacts(sourceFacts)
derivedFacts = deriveSecurityFacts(
relevantFacts,
securityRules
)
replaceProjection(derivedFacts)
Это архитектурный псевдокод.
Он не предполагает конкретного механизма обновления.
Важна причинная цепочка:
Source facts
↓
Security rules
↓
Derived security facts
↓
Projection
17.5. Проекции Guardian
В Guardian значительная часть оснований доступа материализуется заранее.
Например:
KUserGroupLink
↓
effective_user_group
↓
Scope Barrier
↓
effective_user_permission
Отдельно:
KPublish
↓
object_scope
А для владельца существует отдельный OWNER-scope в object_scope.
Таким образом, при обычной проверке объекта система не должна заново обходить всю модель отношений.
Она использует уже подготовленные результаты.
17.6. Почему effective_user_group не проверяется непосредственно
Это важное архитектурное различие.
Можно было бы предположить:
has_object_permission()
↓
effective_user_group
↓
effective_user_permission
Но текущая модель работает иначе.
effective_user_group используется на этапе построения производных разрешений и обработки Scope Barrier.
После этого результат материализуется в:
effective_user_permission
Поэтому проверка объекта непосредственно использует:
effective_user_permission
object_scope
а не заново вычисляет групповую модель.
17.7. Проекция не является окончательным решением
Даже наличие записи в проекции не означает автоматически:
ALLOW
Например:
effective_user_permission = READ
object_scope = UPDATE
required = UPDATE
результат будет отрицательным.
Проекция предоставляет данные для проверки.
Она не заменяет правило.
Поэтому нужно различать:
Projection
и
Authorization decision
17.8. Проекция — часть архитектуры вычисления доступа
Проекции меняют место вычисления.
Без них:
Request
↓
Graph traversal
↓
Rules
↓
Decision
С ними:
Source changes
↓
Projection building
↓
Prepared security facts
Request
↓
Prepared security facts
↓
Decision
Стоимость сложной модели переносится с каждого запроса на этап изменения исходных фактов.
Это не устраняет стоимость.
Оно делает её управляемой.
17.9. Главный принцип
Проекция безопасности должна отвечать на конкретный класс вопросов.
Она не обязана содержать всю модель.
Хорошая проекция:
-
имеет понятный источник;
-
имеет определённые правила построения;
-
имеет понятную область применимости;
-
может быть пересоздана;
-
не становится самостоятельным источником истины.
Поэтому безопасность можно рассматривать как отдельный производный слой над моделью предметной области:
Domain facts
↓
Security-relevant facts
↓
Security projections
↓
Authorization
Следующий вопрос возникает естественно:
Что произойдёт, если изменится один из исходных фактов, от которого зависят несколько проекций?
Это уже проблема распространения изменений.