Как стать автором
Обновить

Использование Verified Permissions для реализации точной авторизации в высоконагруженных приложениях

Уровень сложностиСредний
Время на прочтение13 мин
Количество просмотров1.2K
Всего голосов 7: ↑6 и ↓1+7
Комментарии9

Комментарии 9

Что делать, если разрешенные действия пользователя по отношению к объекту зависят в частности от состояния и/или набора свойств самого объекта - например, овнер (автор записи) при том же наборе ролей в системе имеет другой набор разрешенных действий по отношению к этой записи, чем по отношению к другим. Как эти принципы прописать в облако, чтобы оно выдавало пермиссионный вектор с учетом этого?

Если я правильно понял ваш вопрос, то решить обозначенную проблему поможет ABAC, то есть использование наборов свойств субъекта и объекта при описании политик доступа. На Cedar применение этой концепции можно показать на следующем примере:

Задача: Разрешить любое действие любому пользователю над любым ресурсом, если пользователю назначены права на работу со всеми сегментами, в которые включён ресурс. Действие "Удалить" разрешить только пользователю-владельцу ресурса.

Решение:

Характеристики наших сущностей (User/Принципал и Photo/Ресурс):

[
  {
    "uid": { "type": "User", "id": "alice"},
    "attrs": {"id": "alice","age": 18, "allowed_segments": ["b2o", "b2b", "b2c"]},
    "parents": []
  },
  {
    "uid": { "type": "Photo", "id": "VacationPhoto94.jpg"},
    "attrs": {"object_segment":["b2c","b2o"], "owner": "alice"},
    "parents": [{ "type": "Album", "id": "jane_vacation" }]
  }
]

Политика, решающая поставленную задачу:

permit (
    principal,
    action,
    resource
)
when {
    (principal.allowed_segments.containsAll(resource.object_segment)
        && action != Action::"delete") ||
    resource.owner == principal.id
};

Действие "удалить" над ресурсом "VacationPhoto94.jpg" будет доступно только для пользователя с id="alice", тогда как любые другие действия будут доступны для всех пользователей, сегменты которых совпадут с сегментами объектов, к которым пользователели будут обращаться

Да, все так, спасибо. Удаление в подавляющем большинстве случаев - единичная, а не групповая операция, проверку политики недорого провести перед действием.

А что будет, если например у нас в БД список из миллиона объектов с разными статусами и разными овнерами, и нам нужно показать их разным ролям в зависимости от овнера и от статуса? Скажем, объекты в статусе draft видны только овнерам, а в статусе published - всем, у кого есть право смотреть объекты определенного типа. Мы вызываем метод получения списка объектов для данного пользователя - и хотим получить те записи, на которые есть права на просмотр, и вектор причин, по которым просмотр разрешен (чел может быть одновременно и овнером и членом группы). Есть шанс решить эту задачу за O(log N)?

Интересная задача, на вскидку я бы положил интересующие нас характеристики в индексируемые структуры и делегировал функцию фильрации на сторону БД. В случае, если проблемы с производительностью такого решения сделают его не приемлемым, посмотрел бы на применимость альтернативных подходов вплоть до "хранения всех записей одного владельца в отдельной таблице/области памяти" и "предвычисления результатов для конкретной роли".
И да, шагом 0, бы поставил получение полного и исчерпывающего описания решаемой бизнес-задачи включая все NFR'ы

Задача типовая, я бы сказал. Средствами БД, когда карта ролей и овнерство хранятся внутри базы, она при правильных индексах решается гарантированно логарифмически. Мой вопрос в том, что будет, если я вынесу правила row-level security из БД наружу - смогу ли я сделать выборку такой же эффективной? Чтобы так было, я по сути должен построить модель определения прав во внешней относительно БД системе, и иметь возможность делать туда lookup, передавая сразу набор проверяемых ключей. И внешняя система мне должна ответить за log(N), какие права у меня есть на какую запись. После этого я делаю join со своим исходным набором, и выдаю результат.

Бизнес-описание может быть например таким - авторы пишут статьи в электронную газету в определенную рубрику. У статьи есть статус (draft -> checking -> published -> void). Есть роли в системе (author, editor, public). Есть ассоциация editor - rubric. Author - виртуальная роль - она определяется свойством документа, а не иерархией (кто создал - тот и автор). Дальше есть таблица пермиссий в зависимости от статуса и роли. Пермиссии - это набор флагов разрешенных действий (list, read, edit, delete)

Все это можно положить на внешний проверятор?

PS - это довольно простая модель (по идее переходы из статуса в статус тоже должны быть прописаны в карте пермиссий), но ее изюмина в том, что права нельзя прописать статически по группам - так как они зависят от свойств конкретных экземпляров документов. Еще один пример - многопользовательское редактирование - когда нужен checkin/checkout для элевации пермиссий.

Всё равно не могу до конца понять чего вы хотите достичь...

Может ли PDP (внешний по отношению к БД, хранящей бизнес-объекты и/или их метаданные) выполнить "policy eavaluation" имея на руках всю необходимую для этого информацию (как правило профиль пользователя, запрос пользователя и его контекст, метаданные каждого объекта (либо класса объектов) к которым адресован запрос) - определённо да, он для этого и создан.
Можно ли это сделать не имея всех необходимых данных (например отсутствуют метаданные объекта, используемые в политике) - очевидно, что нет.

Вопрос в том, может ли он сделать это за логарифмическое время.

Если проверяем каждую запись, то, вероятно, отработает за O(N) (возможно, существуют более эффективные решения, но мне о таких неизвестно).
Однако это не должно стать узким местом, так как в подавляющем большинстве случаев пользователь не будет работать с миллионом записей на одном экране.

Это как раз и будет узким местом, так как прежде чем вывести записи на экран, их нужно отфильтровать, чтобы те записи, которые пользователь не должен видеть, на экран не попали )

Поэтому проверить права доступа нужно еще ДО того, как набор строк ушел на фронт. Представьте - я редактор рубрики и автор нескольких статей. Я открываю веб-приложение, оно вызывает список тех статей, которые мне разрешено видеть - для этого нужно выбрать статьи тех рубрик, в которых я редактор плюс те статьи, в которых я автор плюс те, которые разрешены для просмотра public в соответствии с их статусом. И дальше этот набор строк нужно пагинировать, чтобы организовать постраничную выдачу. По поводу списка разрешенных действий с уже ОТОБРАННЫМИ статьями - здесь я согласен - можно проверить точечно права на редактирование/удаление/изменение_статуса из того подмножества, которое middle-tier собирается выдать на фронт. Здесь что N, что log(N) - разница некритичная.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий