KsaiLab
Глава 3

3 Проектирование серверной части защищённой микросервисной платформы

DOCX

3 Проектирование серверной части защищённой микросервисной платформы

3.1 Разделение зон ответственности

Проектирование серверной части начинается с фиксации границ ответственности за аутентификацию, сессии и авторизацию между ключевыми компонентами. Чёткое распределение этих зон является условием конструктивной безопасности: каждый компонент отвечает за строго определённый набор функций, а его компрометация не распространяется на смежные зоны. Распределение ответственности приведено в таблице 3.1.

Таблица 3.1 — Распределение ответственности в системе управления доступом

Зона ответственностиВладелецСодержание ответственности
Поставщик аутентификацииKeycloakУправление учётными данными, форма входа, роли области, выпуск токенов (OIDC)
Поток аутентификацииСерверная частьМаршруты /login, /callback, обмен кода на токены, создание серверной сессии
Инициализация правСерверная частьВыдача набора прав (effective_capabilities) через конечную точку /auth/me
Ограничение интерфейсаКлиентская частьВизуальное скрытие меню и кнопок на основе полученного набора прав
Доступ к ресурсамСерверная частьABAC: окончательная серверная проверка каждого действия пользователя
Развёртывание средИнфраструктурный слойСоздание и удаление изолированных лабораторных окружений в кластере

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

3.2 Выбор стека технологий

Выбор технологического стека обусловлен сформулированными во второй главе требованиями к производительности, безопасности и масштабируемости:

  • Python 3.11 / FastAPI 24: асинхронная обработка запросов и автогенерируемая спецификация OpenAPI;
  • Keycloak 17: внешний поставщик аутентификации (OIDC) и управление учётными записями через Admin API;
  • PostgreSQL: хранение профилей, прав доступа и учебного контента;
  • Redis: серверные сессии и кэширование решений о доступе;
  • MinIO: объектное хранилище файлов учебных материалов;
  • RabbitMQ и Celery 25, 26: очередь задач и обработчики для асинхронного управления инфраструктурой.

Стек сочетает асинхронную серверную часть с внешним поставщиком аутентификации и асинхронным контуром обработки инфраструктурных задач, что соответствует выбранной микросервисной архитектуре и принципу минимизации доверенной вычислительной базы.

3.3 Архитектурные шаблоны и принципы кибериммунности

При проектировании серверной части разрабатываемой платформы (далее — KSAILab) за основу принят кибериммунный подход, теоретические основы которого рассмотрены в подразделе 1.4. На уровне проектирования он выражается в строгом разделении доменов безопасности и минимизации доверенной вычислительной базы (TCB).

Архитектура системы строится на базе микросервисного шаблона, где каждый сервис выполняет узкоспециализированную функцию и обладает собственной изолированной средой исполнения. Ключевыми архитектурными принципами стали:

  1. Разделение полномочий: чёткое разграничение функций управления учебными материалами и функций управления вычислительными ресурсами.
  2. Принцип наименьших привилегий: каждый микросервис имеет доступ только к тем ресурсам (базам данных, очередям, API Kubernetes), которые необходимы для его функционирования 20.
  3. Изоляция по умолчанию: лабораторные окружения обучающихся создаются в выделенных пространствах имён (namespaces) Kubernetes 21 с применением строгих сетевых политик (Network Policies) 19 и стандартов безопасности подов 22.

3.4 Компонентная структура серверной части

Серверная часть платформы выступает как координационное ядро, связывающее пользователей, рабочие программы дисциплин, учебные материалы и вычислительные ресурсы инфраструктуры. Принципиальным архитектурным ограничением является то, что прикладной сервис не обладает прямым доступом к API оркестратора Kubernetes: операции с вычислительными ресурсами он инициирует косвенно, публикуя задачи в брокер сообщений, а их выполнением занимается отдельный инфраструктурный слой. Такое разделение минимизирует доверенную вычислительную базу прикладного сервиса. Состав компонентов и их связи приведены на рисунке 3.1.

%%{init: {"theme": "neutral", "themeVariables": {"fontFamily": "Times New Roman, serif"}}}%%
flowchart TB
    KC(["Keycloak<br/>аутентификация (OIDC)"])
    BP["backend-platform<br/>прикладная логика<br/>и контроль доступа"]
    DB[("PostgreSQL<br/>профили, доступ, контент")]
    REDIS[("Redis<br/>сессии и кэш решений")]
    MINIO[("MinIO<br/>файлы материалов")]
    MQ{{"RabbitMQ<br/>очередь задач"}}
    subgraph INFRA["Инфраструктурный слой"]
        WK["Обработчики задач<br/>(Celery)"]
        K8S["Kubernetes<br/>лабораторные среды"]
    end

    KC <--> BP
    BP <--> DB
    BP <--> REDIS
    BP <--> MINIO
    BP -->|"публикация задач"| MQ
    MQ --> WK
    WK --> K8S

Рисунок 3.1 — Компонентная структура серверной части платформы

Обозначения: поставщик аутентификации — Keycloak (протокол OIDC); прикладной сервис — backend-platform (FastAPI); реляционная СУБД — PostgreSQL; серверные сессии и кэш решений о доступе — Redis; объектное хранилище файлов — MinIO; брокер сообщений (очередь задач) — RabbitMQ; обработчики задач — Celery; оркестратор контейнеров — Kubernetes.

Серверная часть включает два уровня:

  • Прикладной сервис (backend-platform) — единый сервис на фреймворке FastAPI, являющийся «точкой входа» для клиентской части. Он реализует проверку личности и ведение серверной сессии, вычисление эффективных прав пользователя, управление дисциплинами, разделами, банком вопросов и тестами, а также постановку инфраструктурных задач в очередь.
  • Инфраструктурный слой (обработчики задач) — отдельный слой, выполняющий развёртывание и удаление изолированных лабораторных сред и являющийся единственным компонентом, обладающим доступом к API Kubernetes. Он получает задачи из брокера сообщений и абстрагирует сложность оркестрации от прикладной логики платформы. Детальное проектирование этого слоя относится к инфраструктурному контуру; со стороны серверной части фиксируется лишь контракт взаимодействия с ним (подраздел 3.7).

3.5 Проектирование логической модели данных

Для хранения состояний платформы используется реляционная СУБД PostgreSQL. Для наглядности логическая модель данных серверной части представлена четырьмя взаимосвязанными фрагментами: идентификация, учебные группы и назначение дисциплин (рисунок 3.2); структура учебного контента (рисунок 3.3); группы доступа и членство в них (рисунок 3.4); права, назначаемые группам доступа (рисунок 3.5).

%%{init: {"theme": "neutral", "themeVariables": {"fontFamily": "Times New Roman, serif"}}}%%
erDiagram
    organizations ||--o{ users : ""
    organizations ||--o{ groups : ""
    users ||--o{ group_students : ""
    groups ||--o{ group_students : ""
    users ||--o{ group_teachers : ""
    groups ||--o{ group_teachers : ""
    groups ||--o{ group_topics : ""
    topics ||--o{ group_topics : ""
    organizations {
        int id PK
        string name
    }
    users {
        int id PK
        string role
        int organization_id FK
    }
    groups {
        int id PK
        int organization_id FK
    }
    group_students {
        int group_id FK
        int user_id FK
    }
    group_teachers {
        int group_id FK
        int user_id FK
    }
    group_topics {
        int group_id FK
        int topic_id FK
    }
    topics {
        int id PK
        string title
    }

Рисунок 3.2 — Идентификация, учебные группы и назначение дисциплин (ER-диаграмма)

Обозначения: organizations — организации; users — пользователи; groups — учебные группы; group_students, group_teachers — членство студентов и преподавателей; group_topics — назначение дисциплин (topics) учебным группам. PK — первичный ключ, FK — внешний ключ.

%%{init: {"theme": "neutral", "themeVariables": {"fontFamily": "Times New Roman, serif"}}}%%
erDiagram
    topics ||--o{ sections : ""
    sections ||--o{ subsections : ""
    topics ||--o{ tests : ""
    sections ||--o{ tests : ""
    topics ||--o{ questions : ""
    sections ||--o{ questions : ""
    tests ||--o{ test_questions : ""
    questions ||--o{ test_questions : ""
    tests ||--o{ test_attempts : ""
    topics {
        int id PK
        string title
    }
    sections {
        int id PK
        int topic_id FK
    }
    subsections {
        int id PK
        int section_id FK
        string type
    }
    tests {
        int id PK
        int topic_id FK
        int section_id FK
        string type
    }
    questions {
        int id PK
        int topic_id FK
        int section_id FK
    }
    test_questions {
        int test_id FK
        int question_id FK
    }
    test_attempts {
        int id PK
        int test_id FK
        string status
    }

Рисунок 3.3 — Структура учебного контента (ER-диаграмма)

Обозначения: topics → sections → subsections — иерархия учебных материалов (дисциплина, раздел, подраздел); tests, questions — тесты и вопросы; test_questions — связь тестов и вопросов (многие-ко-многим); test_attempts — попытки прохождения тестов студентами (связаны также с таблицей users). Прогресс прохождения фиксируется отдельными таблицами (topic_progress, section_progress, subsection_progress). PK — первичный ключ, FK — внешний ключ.

%%{init: {"theme": "neutral", "themeVariables": {"fontFamily": "Times New Roman, serif"}}}%%
erDiagram
    organizations ||--o{ users : ""
    organizations ||--o{ access_groups : ""
    access_groups ||--o{ access_group_memberships : ""
    users ||--o{ access_group_memberships : ""
    organizations {
        int id PK
        string name
    }
    users {
        int id PK
        string role
        string access_assignment_mode
        string keycloak_sub
    }
    access_groups {
        int id PK
        string key
        int organization_id FK
    }
    access_group_memberships {
        int access_group_id FK
        int user_id FK
    }

Рисунок 3.4 — Группы доступа и членство пользователей (ER-диаграмма)

Обозначения: access_groups — группы доступа; access_group_memberships — членство пользователей в группах доступа; access_assignment_mode — режим назначения прикладного доступа пользователю; keycloak_sub — идентификатор пользователя во внешнем поставщике аутентификации.

%%{init: {"theme": "neutral", "themeVariables": {"fontFamily": "Times New Roman, serif"}}}%%
erDiagram
    access_groups ||--o{ access_group_role_assignments : ""
    access_groups ||--o{ access_group_bundle_assignments : ""
    access_groups ||--o{ access_group_capability_grants : ""
    access_groups {
        int id PK
        string key
    }
    access_group_role_assignments {
        int access_group_id FK
        string role
    }
    access_group_bundle_assignments {
        int access_group_id FK
        string bundle_key
    }
    access_group_capability_grants {
        int access_group_id FK
        string capability_key
    }

Рисунок 3.5 — Права, назначаемые группам доступа (ER-диаграмма)

Обозначения: access_group_role_assignments, access_group_bundle_assignments, access_group_capability_grants — назначаемые группе доступа роли, наборы прав (bundles) и отдельные полномочия (capabilities) соответственно.

3.6 Проектирование гибридной модели доступа (RBAC + ABAC)

Спроектированная модель контроля доступа KSAILab сочетает ролевую (RBAC) и атрибутную (ABAC) модели и базируется на едином реестре полномочий (Capabilities) и архитектурном шаблоне PDP/PEP. Эффективные права пользователя вычисляются по схеме «принципал + назначенный доступ + наборы прав + точечные ограничения ресурса», а защищённая операция последовательно проходит три проверки: подтверждение личности, наличие требуемого полномочия и проверку прав на конкретный ресурс. Структура назначения прав показана на рисунке 3.6.

%%{init: {"theme": "neutral", "themeVariables": {"fontFamily": "Times New Roman, serif"}}}%%
flowchart TB
    U[Пользователь] --> AG[Группа доступа]
    AG --> R[Роли]
    AG --> B["Наборы прав<br/>(bundles)"]
    AG --> C["Отдельные полномочия<br/>(capabilities)"]
    R --> EFF[Эффективные полномочия]
    B --> EFF
    C --> EFF
    EFF --> ABAC["ABAC: проверка<br/>владения и назначения ресурса"]
    ABAC --> DEC["Решение о доступе<br/>(разрешить / 403)"]

Рисунок 3.6 — Структура назначения прав в гибридной модели доступа

Обозначения: группа доступа (access group) объединяет назначаемые пользователю роли, наборы прав и отдельные полномочия; эффективные полномочия — итоговый набор прав, выдаваемый при инициализации сессии; ABAC — атрибутная проверка прав на конкретный ресурс.

Реестр полномочий и модель назначения доступа. В системе спроектирован единый словарь платформенных прав — каталог возможностей (Capabilities Catalog), обеспечивающий согласованность между слоями системы: ограничение интерфейса (видимость пунктов меню и компонентов клиентской части), проверку права на инициирование операций и инициализацию сессии (выдача набора эффективных прав через GET /api/v1/auth/me). Ключи полномочий следуют иерархическому формату <раздел>.<ресурс>.<действие> (например, education.courses.read), что обеспечивает стабильность и читаемость контракта. Каждой возможности сопоставлена область действия (scope): глобальная (global), глобальная с ограничением своей карточкой (global+self), только над собственными данными (self) и глобальная с дополнительной проверкой конкретного ресурса (global+resource). Именно global+resource указывает, что поверх наличия права требуется ABAC-проверка владения или назначения ресурса.

Модель назначения прав состоит из четырёх уровней:

  1. Определения (definitions) — версионируемый каталог возможностей, зафиксированный в коде серверной части как источник истины;
  2. Наборы прав (bundles) — стартовые наборы возможностей для типового профиля (например, teacher.base, student.base, admin.base);
  3. Назначения (assignments) — выдача наборов и отдельных полномочий пользователю через группы доступа (access groups);
  4. Атрибутные ограничения (ABAC) — точечная проверка прав на конкретный ресурс.

Группа доступа (access group) является основным механизмом назначения прикладного доступа: членство пользователя в ней задаёт набор ролей, наборов прав и отдельных возможностей. Это позволяет гибко расширять доступ сверх базовой системной роли, не изменяя саму роль. Системные роли (администратор, преподаватель, студент) рассматриваются как неизменяемая грубая классификация, а более гибкие профили доступа — например, роль модератора, сопровождающего учебный процесс в закреплённых группах, — выражаются именно через группы доступа, а не как отдельная системная роль. Режим назначения доступа фиксируется явно и принимает одно из трёх значений: доступ выводится из базовой роли, выдан через группу доступа либо ещё не назначен; последнее состояние штатно — пользователь может пройти аутентификацию, но до выдачи прикладного доступа запросы к защищённым ресурсам отклоняются с кодом 403.

Системный каталог возможностей. Каталог охватывает все разделы платформы — от базовой навигации до администрирования прав. Для иллюстрации его структуры в таблице 3.2 приведены характерные примеры возможностей; полный системный реестр (39 возможностей: 33 каталожных и 6 базовых исполняемых) с указанием области действия и допустимых ролей вынесен в приложение А (таблица А.1).

Таблица 3.2 — Примеры возможностей из системного реестра

ГруппаВозможность (ключ)НазначениеРоли
Базовыеhome.readДоступ к главной странице и сводной панелиВсе
Образованиеeducation.courses.readПросмотр учебных курсов и темВсе
Образованиеeducation.courses.manageСоздание и изменение курсов и темАдминистратор, Преподаватель
Мониторингmonitoring.logs.readПросмотр аудитных и системных журналовАдминистратор
Доступыpermissions.roles.manageУправление ролями и грантамиАдминистратор

Матрица атрибутов ABAC. Для точечной проверки прав (Resource-scoped access) точка принятия решения использует набор атрибутов, извлекаемых из различных точек предоставления информации (PIP), приведённый в таблице 3.3.

Таблица 3.3 — Матрица атрибутов модели доступа платформы

КатегорияАтрибутИсточник (PIP)Роль в политике безопасности
Субъектrealm_roleKeycloak (JWT)Базовая классификация пользователя
Субъектis_activePostgreSQLПроверка блокировки учётной записи
Субъектgroup_membershipPostgreSQLСписок групп, в которых состоит студент
Объектcreator_idPostgreSQLИдентификатор автора (владельца) ресурса
Объектtopic_idМетаданные / URLИдентификатор проверяемого ресурса
Объектis_archivedPostgreSQLЗапрет действий с архивными данными
Окружениеassignment_statePostgreSQLНаличие активного назначения темы группе
Окружениеcurrent_timeСистемаОграничение доступа по расписанию

Атрибутные правила конкретизируются для каждого домена. Доступ студента к учебному материалу предоставляется только при наличии активной цепочки «студент → учебная группа → назначенная дисциплина» при условии, что ни одна из связей не архивирована. Преподаватель получает доступ к управлению материалом не по одной лишь роли, а как создатель или соавтор дисциплины либо по принадлежности раздела, подраздела или теста к доступной ему дисциплине. Банк вопросов и тесты ограничены областью соответствующей дисциплины, а ответ, возвращаемый студенту, намеренно не содержит правильных вариантов и служебных полей. Доступ к файлам материалов авторизуется по связанному учебному ресурсу, а не по пути объекта в хранилище.

Жизненный цикл полномочий. Для согласованного развития системы зафиксирована строгая последовательность внедрения новых функций: регистрация новой возможности (capability) в серверном реестре и документации; добавление правила её проверки в точку принятия решения; привязка ключа к элементам клиентского интерфейса; включение права в ответ метода /auth/me для соответствующих групп пользователей. Программная реализация точек принятия и исполнения решений (PDP/PEP) рассматривается в главе 4.

3.7 Контракт управления лабораторными средами

Запуск и остановка изолированных лабораторных сред спроектированы по асинхронной модели взаимодействия с инфраструктурным слоем. Прикладной сервис не обращается к оркестратору напрямую, а выступает инициатором: он проверяет права пользователя, фиксирует запись о лабораторной сессии в состоянии ожидания и публикует задачу в брокер сообщений RabbitMQ 26, после чего немедленно возвращает клиенту идентификатор задачи. Выполнением задачи занимается инфраструктурный слой (обработчики Celery 25), который взаимодействует с Kubernetes: по мере выполнения он переводит лабораторную сессию из состояния ожидания в состояние «запущена» и фиксирует адрес подключения (connection_url). Клиент периодически опрашивает статус и получает адрес подключения по готовности. Надёжность обеспечивается персистентностью задач в брокере и повторными попытками при временных сбоях, а детальное проектирование исполнения (создание подов, сетевые политики, очистка по таймауту) относится к инфраструктурному контуру. Последовательность взаимодействия приведена на рисунке 3.7.

%%{init: {"theme": "neutral", "themeVariables": {"fontFamily": "Times New Roman, serif"}, "sequence": {"mirrorActors": false, "wrap": true, "width": 160}}}%%
sequenceDiagram
    participant Student as Студент
    participant BP as Прикладной сервис
    participant MQ as RabbitMQ
    participant WK as Обработчики (Celery)
    participant K8s as Kubernetes

    Student->>BP: запрос на запуск среды
    BP->>BP: проверка доступа (ABAC)
    BP->>MQ: публикация задачи
    BP-->>Student: принято (task_id, «ожидание»)
    MQ->>WK: выдача задачи
    WK->>K8s: создание ресурсов
    K8s-->>WK: ресурсы готовы
    WK->>BP: обновление статуса (запущена, connection_url)
    Student->>BP: опрос статуса
    BP-->>Student: адрес подключения (connection_url)

Рисунок 3.7 — Диаграмма последовательности процессов развёртывания лабораторного окружения

В третьей главе спроектирована серверная часть платформы: зафиксированы зоны ответственности между поставщиком аутентификации, серверной частью и инфраструктурным слоем, обоснован выбор технологического стека и архитектурных шаблонов, разработаны компонентная структура и логическая модель данных. Спроектирована гибридная модель доступа (RBAC + ABAC) с единым реестром возможностей, матрицей атрибутов и жизненным циклом полномочий, а управление лабораторными средами оформлено как асинхронный контракт с инфраструктурным слоем без расширения доверенной вычислительной базы прикладного сервиса. Полученные проектные решения служат основой для программной реализации, рассматриваемой в четвёртой главе.