# Auth Model ## Identity и control-plane source Пользовательский и административный источник истины: Launcher backend. Launcher владеет продуктовыми сущностями платформы: клиенты/компании, участники, роли клиента, группы клиента, инвайты, доступы к сервисам, audit log и пользовательский профиль платформы. Authentik остается внутренним identity/session слоем. Он хранит техническую identity, password/session/MFA/OIDC и получает из Launcher только синхронизированную проекцию, нужную для SSO: пользователей, enrollment/reset flows, группы/entitlements и профильные claims. Пользователь и обычный администратор не должны видеть бренд Authentik в платформенном UI. Прямой доступ к Authentik допускается только через отдельную внутреннюю/служебную ссылку для системной настройки. Plane и будущие приложения не хранят пароли пользователей и не становятся главным источником truth по платформенному пользователю. Они принимают OIDC/session claims и связывают их со своими локальными доменными моделями. ## User journey Целевой production flow: ```text nodedc.ru marketing site -> Войти на платформу -> platform login -> NODE.DC Launcher -> application tiles -> Task Manager / future apps ``` UI платформы не должен показывать пользователю название identity-провайдера. В пользовательских кнопках и текстах используется нейтральное "Войти", "Вход на платформу", "Сессия NODE.DC". Прямые ссылки на приложения остаются допустимым пользовательским сценарием. Если session нет, приложение или внешний proxy/auth layer должен увести пользователя в login flow и после успешного входа вернуть к исходному приложению. ## Platform login UX Текущий hosted Authentik login допустим только как dev/runtime bootstrap для проверки OIDC, JWKS, session и app redirect. Production login должен быть NODE.DC-branded: - пользователь видит только NODE.DC экран входа; - тексты, ошибки, recovery/enrollment и logout не светят бренд Authentik; - Authentik остается внутренним password/session/MFA/OIDC слоем; - пароль, service tokens и refresh tokens не попадают во frontend bundle; - прямые ссылки на Launcher/Task Manager/future apps ведут через этот же NODE.DC login facade и возвращают пользователя в исходное приложение. Допустимые реализации: 1. Кастомизированный Authentik flow, если его можно привести к NODE.DC UX без компромиссов по дизайну. 2. Launcher/BFF login facade, который server-side вызывает внутренний Authentik flow/API и сохраняет безопасность IdP. Запрещено делать быстрый frontend-only password form, который обходит IdP protections, хранит секреты в браузере или ломает MFA/recovery/audit. ## Required claims Минимальный normalized user object: ```ts type AuthUser = { sub: string; email: string; name?: string; avatarUrl?: string | null; groups: string[]; entitlements?: string[]; }; ``` Обязательные проверки: - `iss` совпадает с настроенным issuer; - `aud` совпадает с client/application audience; - `exp` не истек; - `sub` непустой и стабилен; - `email` присутствует для user-facing приложений; - `name`, `picture`/`avatar_url` используются как единый профильный контекст, но мастер-данные профиля должны приходить из Launcher; - `groups` или `entitlements` содержат требуемую техническую app access projection. ## Groups Минимальная группа верхнего уровня: ```text nodedc:superadmin ``` Launcher: ```text nodedc:launcher:admin nodedc:launcher:user ``` Task Manager: ```text nodedc:taskmanager:admin nodedc:taskmanager:user ``` Future apps: ```text nodedc:agents:access nodedc:tender:access nodedc:onec:access nodedc:dm:access ``` ## Access levels Уровень 1: Launcher access model. Отвечает на вопрос, можно ли открыть приложение. Источник решения — данные Launcher: клиент, членство, группы клиента, user grants, deny exceptions, статус сервиса и период доступа. Authentik app access является технической проекцией этого решения для SSO/enforcement, а не местом ручного бизнес-администрирования. Launcher показывает каталог приложений как витрину, а не скрывает все недоступные плитки. Для приложения без доступа кнопка перехода отключена и отображается состояние "Нет доступа". Это важно для продаж, onboarding и понимания доступных модулей платформы. Уровень 2: Launcher admin roles. Отвечает на вопрос, можно ли управлять пользователями, группами, app registry и audit. Уровень 3: Application roles. Например, Plane workspace owner/admin/member/viewer. Эти роли остаются внутри Plane. ## Launcher backend requirements Backend должен: - хранить Authentik service token только server-side; - хранить клиентов, пользователей, членства, группы, инвайты, grants/exceptions и профиль платформы; - выполнять server-side sync в Authentik API без раскрытия Authentik пользователю; - создавать invite/enrollment flows из Launcher UI; - хранить audit log; - возвращать frontend только нормализованные данные пользователя и разрешенные действия; - не отдавать access/refresh/service tokens в browser bundle. ## Live control-plane data rule Демо-пользователи Launcher допустимы только как fixture на этапе frontend MVP. Как только появляется backend/admin API, Launcher control-plane должен перейти на живой seed: - реальные платформенные пользователи вместо `root@nodedc.local`, `ivan@romashka.ru` и прочих декоративных участников; - явный superadmin NODE.DC; - реальные клиентские пользователи и группы, подтвержденные по Plane/Auth/Launcher данным; - idempotent seed/migration script с backup текущего `launcher-data.json`; - отсутствие прямого изменения Plane users/workspace/task данных из Launcher seed; - все дальнейшие проверки клиентов, групп, инвайтов и доступов выполняются через Launcher admin UI. Если пользователь существует в Plane, но еще не существует в Authentik, он должен быть заведен через Launcher/Auth sync flow, а не ручным рассинхроном. ## Plane identity link Минимальная таблица или эквивалентная модель в Plane: ```text external_identity_link provider = authentik authentik_sub email plane_user_id created_at last_login_at status ``` Правило миграции: - сначала искать link по `authentik_sub`; - если link найден, логинить связанный `plane_user_id`; - если link не найден, но email совпадает и включен migration auto-link, создать link; - если доступа нет, вернуть deny. ## Plane standalone compatibility Plane является подключаемым приложением NODE.DC, но не должен становиться технически невынимаемым модулем. Правила интеграции: - OIDC NODE.DC добавляется как отдельный auth provider path, а не как замена всей Plane auth системы; - стандартные Plane session/API-token возможности сохраняются, пока нет отдельного решения их убрать; - Launcher хранит только платформенные привязки и access projection, но не владеет Plane workspace/project/task/comment; - связь с Plane строится через external identity link и будущий service adapter/API, а не через прямое изменение Plane DB из Launcher; - env-флаги должны позволять включать NODE.DC SSO в составе платформы и выключать его для standalone-поставки Plane.