Backend Platform
Backend Platform
Статус и контекст
Этот раздел описывает реальное состояние backend-ksailab после auth foundation MR !10, follow-up reconciliation !13 и runtime browser-session sync в !15, а не только целевую архитектуру.
Важно:
- текущий backend-репозиторий (
backend-ksailab) был перенесён из предыдущего образовательного проекта; - доменная и CRUD-часть по пользователям, группам, темам, разделам, тестам и файлам уже была зрелой до миграции auth;
- по состоянию на
2026-03-16в backend уже landedKeycloak-first auth foundation, follow-up reconciliation по human identity readiness и runtime browser-session contract; - остаточный auth-foundation reconciliation дальше продолжается в
ksailab/backend-ksailab#1, поэтому migration нельзя считать полностью законченной.
Связанные репозитории:
backend-ksailabfrontend-ksailabkeycloak-scripts-ksailabdocs-ksailab
Что backend представляет собой сейчас
По текущему коду backend уже реализует:
- REST API на FastAPI;
- хранение данных в PostgreSQL через SQLAlchemy;
- работу с группами, темами, секциями, подразделами, тестами, вопросами и файлами;
- часть бизнес-ограничений на уровне сервисов и security dependencies;
- точечные ABAC-проверки для доступа к темам и учебному контенту;
Keycloak-firstprincipal bootstrap черезGET /api/v1/auth/me;- onboarding orchestration для teacher, group, teacher assignment и bulk student provisioning;
- receipt-based handoff для одноразовой выдачи временного пароля;
- startup и health diagnostics по
Keycloak issuerиJWKS.
Одновременно backend всё ещё содержит legacy-следы старой системы:
- старые local-auth endpoints ещё существуют как deprecated compatibility layer;
- часть старого кода по-прежнему завязана на локальный профиль пользователя и числовой
id; - часть reconciliation вокруг human admin readiness и legacy cleanup ещё остаётся в
ksailab/backend-ksailab#1.
Что landed в auth foundation
В рамках backend MR !10, !13 и !15 в runtime уже зафиксировано следующее:
Keycloakстал источником identity и coarse-grained realm rolesadmin,teacher,student;- backend валидирует Keycloak token через issuer metadata и
JWKS; - canonical browser login entry теперь
GET /api/v1/auth/login; - canonical callback endpoint теперь
GET /api/v1/auth/callback; - canonical logout endpoint теперь
POST /api/v1/auth/logout; - frontend bootstrap теперь должен опираться на
GET /api/v1/auth/me, который поднимает current principal из backend-owned session/cookie; - отдельного
/capabilitiesendpoint в этой фазе нет; - local
POST /api/v1/auth/loginиPOST /api/v1/auth/refreshбольше не являются рабочим auth flow и возвращают410 Gone; - explicit bearer path оставлен только как отдельно очерченный non-browser/manual Keycloak JWT flow;
- onboarding вынесен в отдельный набор
POST /api/v1/onboarding/*endpoints; - временный пароль больше не отдаётся inline из create-операций, а передаётся через receipt-based handoff;
/api/v1/healthи startup logs показывают состояние связности с Keycloak и диагностическую human identity readiness.
Отдельно для следующей auth wave backend contract уже зафиксирован в ksailab/backend-ksailab#14:
- browser cookie должен содержать только opaque session identifier;
- browser auth session должна жить server-side;
- target storage для неё —
Redis; - canonical logout surface должен эволюционировать от local session cleanup к full platform logout.
Реальная роль backend в KSAILab
После миграции backend должен оставаться не IAM-системой, а оркестратором бизнес-логики и авторизации на платформенных данных.
Backend отвечает за
- валидацию identity-контекста, полученного через Keycloak;
- загрузку платформенного профиля и связей пользователя;
- вычисление глобальных platform capabilities для UI;
- исполнение resource-scoped ABAC по данным собственной БД;
- выдачу
GET /api/v1/auth/meкак единого bootstrap-контракта для фронта; - вызовы
Keycloak Admin APIдля user lifecycle из platform UI; - сохранение и проверку платформенных состояний, которых нет в IAM:
- membership;
- ownership;
- co-author access;
- archive state;
- progress state;
- publication and availability state.
Backend не должен больше быть источником истины для
- primary credentials;
- локального login/password flow как основной auth-модели;
- собственного access/refresh token lifecycle как canonical auth source;
- полного permission catalog внутри Keycloak.
Текущая backend auth-модель
1. Identity integration layer
Новый auth-слой backend уже включает:
- OIDC/JWKS validation against Keycloak;
- principal resolver;
- profile binding;
- normalised request context;
- health/startup probe для issuer metadata и
JWKS.
Минимальный runtime principal в backend:
id— локальный платформенный профиль;username;full_name;role— классификация профиля;keycloak_sub— внешнийsubиз Keycloak;identity_source;is_active;is_archived.
2. Capability layer
Backend стал источником capability bootstrap для фронта.
В первой auth-foundation фазе bootstrap идёт только через GET /api/v1/auth/me. Отдельного /capabilities endpoint в этой фазе нет.
Сейчас effective access рассчитывается по модели:
principal + bundles + overrides
При этом важно различать четыре слоя:
capability definitions— версионируемый каталог прав;bundles— рабочие наборы capabilities;assignments/overrides— административные назначения;ABAC— проверки по конкретным ресурсам.
Definitions фиксируются в коде и документации, а bundles и assignments должны жить в БД платформы и администрироваться через UI.
3. Policy layer
Любой защищённый endpoint в целевой модели должен раскладываться на три шага:
- identity validated;
- capability granted;
- resource-specific ABAC passed.
Это особенно важно для перехода от coarse-grained bootstrap к будущему полномасштабному ABAC Rollout.
Контракт между backend и frontend
GET /api/v1/auth/me
Текущий runtime bootstrap-контракт возвращает:
principal;classification;realm_roles;bundles;effective_capabilities.
Этого уже достаточно для:
- initial render;
- route guards;
- menu gating;
- component gating;
- понимания, какие onboarding/action surfaces показывать пользователю.
Canonical browser-session surface
Backend runtime для human/browser auth теперь фиксирует такой surface:
GET /api/v1/auth/login— start browser login flow;GET /api/v1/auth/callback— принять authorization code и поднять backend session;POST /api/v1/auth/logout— canonical browser logout surface; current baseline очищает локальную backend session, target next wave должна довести его до full platform logout;GET /api/v1/auth/me— вернуть bootstrap payload для уже поднятой session.
Storage semantics для этого surface нужно фиксировать явно:
- browser cookie не должен быть местом хранения auth payload;
GET /api/v1/auth/meдолжен поднимать principal из server-side auth session;- access/refresh/id tokens должны жить server-side;
Redisявляется target store для этой auth session в следующей wave.
Этот контракт не должен описываться как frontend-managed bearer lifecycle.
Explicit bearer path
Backend всё ещё может принять Keycloak-issued bearer token, но только как явно отдельный non-browser/manual сценарий.
- bearer token должен соответствовать настроенному Keycloak issuer;
- bearer token не должен считаться canonical browser path;
- browser flow должен документироваться через session/cookie contract.
Это важно и для logout semantics:
- explicit bearer/manual flow не определяет browser logout поведение;
- local app logout и full platform logout нужно описывать отдельно;
- кнопка
Выйтив продукте не должна закреплять за собой только local cleanup semantics.
Deprecated local-auth endpoints
Следующие endpoints больше не считаются рабочим auth flow:
POST /api/v1/auth/loginPOST /api/v1/auth/refresh
Они оставлены только как deprecated compatibility layer и возвращают 410 Gone.
Provisioning orchestration layer
Backend уже поддерживает отдельный onboarding-контур поверх Keycloak Admin API.
Текущие canonical endpoints:
POST /api/v1/onboarding/teachersPOST /api/v1/onboarding/groupsPOST /api/v1/onboarding/groups/{group_id}/teachersPOST /api/v1/onboarding/groups/{group_id}/students/bulkPOST /api/v1/onboarding/credentials/consume
Что важно по credential flow
- identity создаётся в Keycloak;
- create-операция возвращает
credential_receipt, а не обычныйtemporary_passwordinline; - временный пароль раскрывается только через отдельный consume flow;
- receipt одноразовый и ограничен по времени жизни;
- первый вход по-прежнему требует смены пароля.
Что всё ещё считается переходным слоем
В backend остаются legacy endpoints старой системы, но для документации KSAILab они больше не являются основным auth/provisioning contract.
Они могут использоваться как transitional transport при миграции UI, но canonical поверхностью надо считать именно:
GET /api/v1/auth/mePOST /api/v1/onboarding/*
Source-of-truth boundaries
Для traceability backend docs должны явно разделять runtime contract и окружающую delivery-инфраструктуру:
- shared CI source-of-truth для KsaiLab живёт в
ci-pipelines/pipelines-ksailab; - backend deployment, ingress, callback-route exposure и runtime env source-of-truth живут в
infra/infra-backend-ksailab; - Keycloak realm/bootstrap/provisioning source-of-truth живёт в
keycloak-scripts-ksailab; - physical Keycloak deployment source-of-truth живёт в
infra-keycloak-ksailab; backend-ksailab!15не заявляет скрытый infra diff: если rollout session/cookie semantics требует follow-up, он должен отслеживаться отдельно в infra-репозитории.
Граница ответственности остаётся такой:
- backend runtime не создаёт первого human admin сам;
- первый human admin появляется отдельным operator flow на стороне Keycloak;
ksailab-admin-serviceостаётся service account для provisioning, а не surrogate для human admin.
Health и операционная диагностика
/api/v1/health теперь должен отражать не только доступность backend, но и:
- состояние связности с настроенным
Keycloak issuer; - диагностическую
human identity readinessпо ролямadmin,teacher,student.
Startup logs дополнительно показывают:
- configured issuer;
JWKS URI;- количество доступных ключей;
- ошибку связности, если issuer metadata не читается;
- наличие или отсутствие human identities по coarse roles.
Важно: это диагностический probe. Он не должен автоматически создавать human admin и не делает local backend bootstrap актуальной auth-моделью.
Это важно для эксплуатационной диагностики при запуске стенда и при расследовании auth-инцидентов.
Что ещё остаётся незавершённым
Нельзя считать, что backend auth-миграция полностью завершена.
Отдельно остаются:
- cleanup legacy local admin bootstrap;
- синхронизация первого human admin с чистой Keycloak-first моделью;
- дальнейшее развитие bundle/override persistence;
- расширение resource-scoped ABAC поверх текущего bootstrap.
Эти остатки дальше отслеживаются в ksailab/backend-ksailab#1.
Validation и expected tests
Для этой волны архитектура уже опирается на реальные backend-проверки:
- auth integration tests на
GET /api/v1/auth/me; - tests на deprecated
410 Goneдля local login/refresh; - onboarding tests на teacher/group/student flows;
- tests на receipt consume и одноразовую выдачу временного пароля;
- startup/health diagnostics tests для Keycloak issuer и
JWKS.
Frontend migration tests для потребления этого контракта остаются отдельной задачей во frontend-ksailab.