
Всем привет! Сегодня окунёмся в мир безопасности приложения с точки зрения системного аналитика: расскажем про актуальный контроль доступа применительно к UI и API, а также предложим свой экспериментальный подход для работы с требованиями авторизации ‑ «постанализ юзкейсов».
На связи с вами Никита Таскин и Анастасия Ильина. Последние годы мы провели в разработке сервисов аутентификации и авторизации для огромной платформы, поэтому нам есть чем поделиться. Речь пойдёт про мегакейс внедрения атрибутивного контроля в нашу систему управления проектами Сфера.Задачи. Материала довольно много, поэтому мы разделили его на две части по типу интерфейсов: UI и API. Приятного погружения в наш мир!
Введение
Сейчас любой ИТ-специалист должен понимать основы безопасности, и игнорировать это требование уже нельзя. Оно становится неотъемлемой частью одной из главных задач системного аналитика — проектирования интерфейсов. Мы покажем на примере, как новые требования к контролю доступа могут стать серьёзной архитектурной проблемой вашего приложения, решаемой с помощью небольшой идеи и артефактов системного анализа.
Итак, ИТ-безопасность появилась как явление уже во времена первых промышленных вычислительных машин. Подробнее про эту эволюцию от ACL-файликов до безопасности в современных распределенных системах в разрезе функций идентификации, аутентификации и авторизации можно почитать в телеграм-канале Никиты «постанализ». А здесь мы сосредоточимся на самых актуальных понятиях: модели атрибутивной авторизации ABAC и концепция безопасности Zero Trust.
Об атрибутивном контроле доступа есть довольно много статей и видео, поэтому напомним, что в момент принятия решения о доступе пользователя необходимо вычисление условий на атрибут субъектов, объектов и окружения. В статье будут примеры реальных условий атрибутивного контроля, поэтому не беспокойтесь, если чувствуете, что «плаваете» в теме — это не помешает ознакомиться с темой.
А вот второй «зверь», возможно, не так широко известен. Парадигма Zero Trust возникла в 2010-м году, и без неё сегодня и без того огромное количество жертв киберпреступности, возможно, было бы в разы больше. В основе парадигмы лежит подход «Не доверяй никому», и она следует трём простым принципам:
Явная проверка каждого запроса.
Принцип наименьших привилегий.
Предположение о взломе.
Первый принцип рождает понятие непрерывной проверки — использование наших функций безопасности буквально для каждого действия пользователя. Второй принцип говорит о том, что не нужно давать пользователю больше прав, чем ему нужно для работы в рамках его бизнес-роли, и для этого требуется гибкая система доступа. И наконец, третий принцип говорит о том, что злоумышленник может быть уже внутри вашей системы, и необходимо его вычислить до возникновения критического урона.
Количество используемых принципов можно варьировать в зависимости от конфиденциальности данных и критичности системы. Здесь мы подробно остановимся на непрерывной авторизации и будем разбираться с ней на уровне интерфейсов системы — главной зоне ответственности аналитиков.
Контекст задачи — Задачи
У нашего ИТ-холдинга есть очень интересная продуктовая линейка IT4IT, или, проще говоря, платформа для разработки софта Сфера. Один из самых ярких продуктов в ней — система управления проектами (или, по-народному, таск-трекер) Сфера.Задачи. Однажды его разработчикам пришло время доставать из бэклога и реализовывать гибкую ролевую систему, которую просили все потребители. Именно нам выпала честь помочь этой продуктовой команде с анализом требований и реализацией фичи.

В контексте этой истории мы рассмотрим достижение условий для реализации первых двух принципов ZeroTrust через переход от жёсткой к гибкой модели доступа. Подробно поговорим о трудностях выстраивания непрерывной ABAC-авторизации UI и API, а также о том, как нам помог с этим «постанализ юзкейсов».
Старая модель авторизации
Таск-трекер нужен, в первую очередь, для управления задачами разных команд, и для этого в нём была предусмотрена ролевая модель с двумя основными бизнес-ролями:
лидер команды, который отвечает за создание и архивирование задач, а также управляет доступом к рабочему пространству команды;
и участник команды, который может управлять любыми задачами в этом пространстве.

На первый взгляд, модель доступа — RBAC, однако есть завязка на команду, а редактировать участник мог при условии, что задача не закрыта. Эти ограничения выделены оранжевым цветом. По сути, это уже простенький ABAC: есть условия на основе проверки атрибутов субъекта (роли и команды) и объекта (команды и статуса).
Не только разработчикам в широком смысле необходим доступ к данным задач команды, но и разным заинтересованным лицам. Однако их сценарии использования ограничены в основном просмотром, а редактирование связано лишь с отдельными атрибутами, о чём мы ещё поговорим ниже. И чтобы дать им доступ, применяли единственную более-менее подходящую роль — «Участник команды». В этом заключалась главная проблема: предоставлялся одинаковый уровень доступа и реальным участникам команды, и заинтересованным лицам, что явно нарушает второй принцип Zero Trust. При этом ролевая модель была прописана в коде и любое её изменение требовало не работы с настройками, а нового релиза.
А теперь посмотрим на авторизацию в такой системе на примере открытия Kanban-доски (см. рисунки ниже):
Пользователь запускает веб-приложение, оно сначала запрашивает его роль. На основе ответа фронтенд решает, какие элементы интерфейса показать, а какие скрыть.
При запросе данных для отображения списка задач бэкенд фильтрует ответ, основываясь на том, к пространствам каких команд пользователь имеет доступ.
Когда пользователь выбрал задачу, необходимо отобразить её подробную карточку. Фронтенд на основе ролей субъекта и статуса задачи решает, отображать карточку в режиме чтения или редактирования.
При изменении задачи приложение запрашивает бэкенд о доступности такой операции.


Наглядно видно непрерывную авторизацию: ни одно действие пользователя не осталось без проверки. Такой подход можно классифицировать как параллельную логику, когда фронтенд и бэкенд независимо друг от друга авторизуют действия пользователя.
Желаемая модель авторизации
Какой должна была быть идеальная ролевая модель в нашей системе управления проектами? По-хорошему, для каждого заинтересованного лица необходимо было бы создавать роль с особым набором прав. Примеры необходимых правил доступа:

Обратите внимание, что теперь условия доступа задаются не для объекта задачи, а для её атрибутов. Например, нужно проверять доступ не к редактированию задачи, а к изменению её основной информации: статуса, комментариев и множества других отдельных атрибутов. Также выделены конфиденциальные данные, требующие особого внимания.
В новой схеме задача в зависимости от состояния попадает в контекст заинтересованного лица (связанного с финансами, с ИБ и так далее), и доступ к ней других участников команды должен измениться. Причём можно разрешить либо чтение, либо полное редактирование, либо редактирование только отдельных атрибутов.
Здесь уже отчётливо видны интересные и сложные примеры использования ABAC: есть отдельные правила для атрибутов задачи. Как же достичь этого с точки зрения непрерывной авторизации?
Пользовательский Интерфейс и Авторизация
Полноценный ABAC принёс трудности. Нужен был переход от проверки ролей к проверке разрешения, от авторизации действий с задачей к авторизации операций с её отдельными атрибутами, и всё это с учётом контекста задачи.
Требовалось понять, какие грядут изменения во фронтенде и бэкенде. Но сравнивать таблицы и рисовать диаграммы последовательностей для каждого случая казалось нерационально долгим. Мы, как Колумб, решили отправиться в плаванье по морям неопределённостей, где ориентирами у нас были только юзкейсы!
Роль фронтенда и бэкенда в старой модели авторизации
Мы вынесли шаги основных сценариев использования — создание, редактирование и архивирование задачи — в виде некой карты «путей пользователя». Всё начинается с просмотра данных — получаем список задач. Затем пользователь создаёт задачу: он выбирает соответствующую команду, заполняет необходимые атрибуты и сохраняет её. Или пользователь может найти задачу и выбрать её для просмотра: здесь он сможет редактировать атрибуты или архивировать задачу, если она завершена.

Табличное и досочное представление отвечают за отображение и выбор задач, а детальная работа с каждой задачей — редактирование, архивирование — выполняется уже в карточном представлении.
Теперь на каждый шаг добавляем условие авторизации и определяем, чья эта зона ответственности — фронтенда или бэкенда, — выделяя их своими цветами. Чтение данных — явная зона ответственности бэкенда, данные фильтруются согласно уровню доступа. А вот отрисовка элементов управления, выбор команды и отображение карточки задачи в режиме чтения и редактирования в зависимости от прав пользователя — уже работа фронтенда. Ну и, конечно, сохранение изменений — это задача бэкенда: он проверяет права доступа к операции над конкретной задачей.
Роль фронтенда и бэкенда в желаемой модели авторизации
Сейчас проделаем те же манипуляции с новоей версией. В отличие от старой у нас появились сценарии просмотра и редактирования конфиденциальных атрибутов. Основные изменения коснулись работы с карточкой задачи. Теперь часть атрибутов можно скрыть для чтения в зависимости от прав пользователя. Например, задача попала в контекст заинтересованного лица и часть атрибутов становится недоступна для обычных участников.

Но что делать, если эти атрибуты участвовали в определении условий доступа? Фронтенд не сможет просчитать условия и выполнить правильные требования к авторизации. Также у нас нет чёткого понимания количества ролей с возможными условиями для атрибутов. Это зоны неопределённости, выделим их красным цветом. Очевидно, что фронтенду в этих зонах будет сложно поддерживать логику самостоятельно. Почему бы тогда не переложить это на бэкенд? И справится ли он с этим?
Как может быть устроена авторизация в этом случае: при запуске веб-приложения фронтенд отправляет запрос на получение не ролей пользователя, а конфигурации представления под него. Ответ уже учитывает все его права. Далее фронтенд запрашивает список задач. И здесь есть отличие: после формирования бэкендом списка доступных задач нужно ещё дополнительно очистить данные у каждой задачи для атрибутов, недоступных для чтения. Когда пользователь выбирает задачу, фронтенд снова запрашивает конфигурарацию, только на этот раз карточки задачи. Отдельно запрашиваются все атрибуты задачи с последующей фильтрацией, а при изменении бэкенд проверяет доступ не к задаче, а к атрибуту.

Теперь вся логика авторизации выделена красным цветом. Фронтенд становится проще, но гибче настраиваемым под любые сценарии. Такой подход можно назвать бэкенд-ориентированным.
Постанализ юзкейсов для проектирования авторизации пользовательского интерфейса

Что мы сделали:
Объединили варианты использования и составили схему путей пользователя.
Визуализировали непрерывную авторизацию, добавили в схему условия доступа для выполнения действия.
Определили зоны ответственности за авторизацию, примерили «чтение и сохранение данных — бэкенд, процесс — фронтенд», оценили риски в зоне ответственности фронтенда.
Сравнили подходы Parallel FE-BE и BE-driven. Если есть риски, то лучше BE-driven, или даже гибридный подход: применяется один из вариантов в зависимости от разных сценариев или экранов.
Так мы провели «постанализ юзкейсов» для определения подхода к авторизации. Теперь подробнее о рисках.
Определение рисков в зоне фронтенда

Как обнаружить риски, что фронтенд может не справиться с каким-то условием? Если авторизация по ролям или разрешениям, то проблем нет, а если нужны правила доступа, то смотрим на условия. Требуются сложные вычисления, функции? — это проблемная зона. Но и простые правила могут быть проблемой для фронтенда, если ему не хватает данных для проверки, например, бэкенд не отдал атрибуты, закрытые для чтения. Также дополнительном индикатором является количество атрибутов: если оно неопределённое и может увеличиваться, то лучше выбрать бэкенд.
Дизайн непрерывной авторизации пользовательского интерфейса

При параллельном подходе во время проектирования пользовательского интерфейса можно один раз сосредоточиться на получении доступов через API, а требования к новым функциям должны сразу содержать описание необходимых прав (ролей, разрешений).
При бэкенд-ориентированном подходе в каждый элемент интерфейса нужно закладывать разное поведение в зависимости от приходящих настроек и, соответственно, разработать специальный API для их получения. Для новых функций в требованиях связывают настройки с правилами доступа, а API должен отдавать не только сами данные ресурсов, но и информацию о доступных пользователю действиях с ними — интеграция прямо в метод чтения или отдельная ручка только для получения доступных пользователю действий с объектами.
На этом первая часть окончена, а в следующей будет про API.
Авторы:
Никита Таскин, эксперт-системный аналитик
Анастасия Ильина, системный аналитик