NODEDC_PLATFORM/docs/AUTH_MODEL.md

187 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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.
Текущее безопасное решение зафиксировано в `docs/AUTH_BRANDED_LOGIN_RFC.md`: сначала используем Authentik-native Brand/CSS/Flow customization. Reverse proxy HTML-rewrite, password form в Launcher и пересылка пароля через BFF запрещены.
## 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.