3 Проектирование серверной части защищённой микросервисной платформы
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).
Архитектура системы строится на базе микросервисного шаблона, где каждый сервис выполняет узкоспециализированную функцию и обладает собственной изолированной средой исполнения. Ключевыми архитектурными принципами стали:
- Разделение полномочий: чёткое разграничение функций управления учебными материалами и функций управления вычислительными ресурсами.
- Принцип наименьших привилегий: каждый микросервис имеет доступ только к тем ресурсам (базам данных, очередям, API Kubernetes), которые необходимы для его функционирования 20.
- Изоляция по умолчанию: лабораторные окружения обучающихся создаются в выделенных пространствах имён (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-проверка владения или назначения ресурса.
Модель назначения прав состоит из четырёх уровней:
- Определения (definitions) — версионируемый каталог возможностей, зафиксированный в коде серверной части как источник истины;
- Наборы прав (bundles) — стартовые наборы возможностей для типового профиля (например,
teacher.base,student.base,admin.base); - Назначения (assignments) — выдача наборов и отдельных полномочий пользователю через группы доступа (access groups);
- Атрибутные ограничения (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_role | Keycloak (JWT) | Базовая классификация пользователя |
| Субъект | is_active | PostgreSQL | Проверка блокировки учётной записи |
| Субъект | group_membership | PostgreSQL | Список групп, в которых состоит студент |
| Объект | creator_id | PostgreSQL | Идентификатор автора (владельца) ресурса |
| Объект | topic_id | Метаданные / URL | Идентификатор проверяемого ресурса |
| Объект | is_archived | PostgreSQL | Запрет действий с архивными данными |
| Окружение | assignment_state | PostgreSQL | Наличие активного назначения темы группе |
| Окружение | 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) с единым реестром возможностей, матрицей атрибутов и жизненным циклом полномочий, а управление лабораторными средами оформлено как асинхронный контракт с инфраструктурным слоем без расширения доверенной вычислительной базы прикладного сервиса. Полученные проектные решения служат основой для программной реализации, рассматриваемой в четвёртой главе.
Pdp Pep Flow
%%{init: {"theme": "neutral", "themeVariables": {"fontFamily": "Times New Roman, serif"}}}%% flowchart TB U("Пользователь(сессия / JWT)") PEP"PEP(промежуточный слой)" CAP"Проверкаполномочия" PDP"PDP(модуль решений)" PIP("PIP(PostgreSQL)") CACHE("Redisкэш решений") BIZ"Прикладная логика(контроллер)"
4 Реализация серверной части платформы и апробация