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

Глава 31. Надёжность и восстановление

31.1. Надёжность — это свойство всей цепочки

Модель доступа может быть логически правильной и при этом работать ненадёжно.

Например, исходный факт изменился:

User A removed from Group G

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

effective_user_group
effective_user_permission

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

Поэтому надёжность модели доступа нельзя свести к надёжности базы данных.

Нужно обеспечить всю цепочку:

Source fact
    ↓
Change propagation
    ↓
Projection
    ↓
Authorization
    ↓
Data enforcement

Ошибка на любом этапе может изменить фактический результат проверки.


31.2. Источник истины должен сохраняться

Проекция является производным состоянием.

Поэтому при восстановлении нельзя полагаться только на неё.

Если произошло повреждение:

effective_user_permission

система должна иметь возможность восстановить его из исходных фактов.

Принцип:

Source facts + Rules
        ↓
Rebuild
        ↓
Security projections

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

Это опасно.


31.3. Событие не заменяет исходный факт

События помогают распространять изменения:

UserGroupLinked
UserGroupUnlinked
ObjectPublished
ObjectUnpublished

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

Система должна уметь ответить:

В каком состоянии находится модель сейчас?

а не только:

Какие события когда-то были обработаны?

Поэтому устойчивее иметь:

Source state
    +
Change propagation
    +
Rebuild capability

Событие ускоряет изменение производного состояния.

Оно не заменяет исходную модель.


31.4. Выдача и отзыв должны быть симметричны

Для безопасности особенно опасен путь отзыва.

Выдача может выглядеть так:

Grant
  ↓
Projection updated
  ↓
ALLOW

Но отзыв должен обеспечить:

Revoke
  ↓
Projection updated
  ↓
DENY

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

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

Поэтому семантика задержки должна быть определена отдельно.


31.5. Инкрементальное обновление и полная перестройка

Обычно есть два механизма.

Первый — инкрементальный:

One fact changed
    ↓
Find affected projection rows
    ↓
Update them

Второй — полный:

All source facts
    ↓
Apply rules
    ↓
Rebuild projection

Инкрементальный механизм нужен для обычной работы.

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

Наличие полного rebuild особенно важно тогда, когда производные данные строятся сложными алгоритмами.


31.6. Восстановление должно быть частью архитектуры

Восстановление нельзя проектировать после появления первой аварии.

Должны быть заранее определены:

1. источник исходных фактов;
2. правила построения;
3. порядок восстановления;
4. способ проверки результата;
5. момент, когда восстановленная модель считается готовой.

Последний пункт особенно важен.

Заполненная таблица ещё не означает готовую security model.


31.7. Нельзя путать отсутствие проекции с отсутствием права

Пусть пользователь существует:

User A

но запись в производной проекции ещё не появилась.

Тогда возможны как минимум два состояния:

projection says DENY

и:

projection is not ready

Это разные состояния.

Если система автоматически превращает второе в первое, она получает безопасное, но потенциально некорректное поведение.

Если автоматически превращает его в разрешение, возникает очевидная проблема безопасности.

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


31.8. Правила тоже являются частью состояния

Проекция зависит не только от фактов.

Она зависит от:

Source facts
+
Security rules

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

Например:

Old rule
    ↓
Projection P

после изменения:

New rule
    ↓
Projection P'

Поэтому изменение самой модели правил может требовать перестроения проекций.


31.9. Проверка после восстановления

После rebuild недостаточно проверить:

row count > 0

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

Например:

Source facts
    ↓
Expected derived state

и затем проверять:

Actual projection
    =
Expected projection

Для критичных систем полезны также инварианты:

  • нет производного права без основания;

  • отзыв действительно удаляет право;

  • область разрешения не расширилась;

  • владелец соответствует объекту;

  • производные записи согласованы между собой.


31.10. Восстановление не должно зависеть от сломанной авторизации

Если обычная authorization model повреждена, нельзя делать восстановление зависимым от неё самой.

Иначе возникает цикл:

Need security projection
    ↓
Need projection to rebuild projection

Восстановление должно использовать более низкий уровень доверия:

Source facts
+
Controlled rebuild process

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


31.11. Главный вывод

Надёжная модель доступа должна иметь не только путь:

Fact → Projection → Authorization

но и обратный эксплуатационный путь:

Source facts
    ↓
Rebuild
    ↓
Projection
    ↓
Validation
    ↓
Normal authorization

Проекция может быть потеряна.

Проекция может устареть.

Алгоритм её построения может измениться.

Архитектура должна быть готова ко всем трём случаям.