# NODE.DC branded login RFC

## Цель

Пользователь должен видеть единое окно входа NODE.DC в визуальной логике текущего Plane login: темный фон, компактная карточка, NODE.DC logo, крупный заголовок, email/password, яркая CTA-кнопка.

При этом Authentik остается внутренним identity provider и продолжает владеть паролями, MFA, recovery, lockout, session, OAuth/OIDC и audit events.

## Жесткие запреты

Запрещенные варианты реализации:

- reverse proxy, который переписывает HTML Authentik на лету;
- frontend-only форма в Launcher, которая принимает email/password;
- BFF endpoint в Launcher, который принимает пароль пользователя и пересылает его в Authentik;
- OAuth password grant / ROPC;
- хранение паролей, refresh tokens или Authentik session cookies в frontend/localStorage;
- обход Authentik CSRF, MFA, recovery, lockout, enrollment и audit flow.

Эти варианты расширяют trusted boundary платформы: Launcher становится обработчиком паролей, а это ломает разделение ответственности и усложняет аудит.

## Выбранный безопасный путь

Базовый production-safe путь: Authentik-native branded flow.

- UI кастомизируется через Brand/Flow внутри Authentik.
- `branding_custom_css` задает NODE.DC look без HTML-прокси.
- Password stage, Identification stage, User Login stage, MFA/recovery остаются штатными Authentik stages.
- Identification stage связан со штатным Password stage, поэтому email и password показываются в одном Authentik challenge без передачи пароля в Launcher.
- Launcher и Task Manager остаются OIDC clients и не получают пароль пользователя.
- Direct links на Launcher/Task Manager продолжают идти через Authorization Code Flow + PKCE.
- OAuth2 provider end-session использует штатный Authentik invalidation flow с UserLogoutStage, чтобы пользователь не попадал на Authentik application logout dashboard.

Если Brand/CSS не даст pixel-level соответствие Plane login, следующий допустимый уровень — кастомный Authentik template/flow executor внутри Authentik deployment. Это тоже остается IdP-side custom UI, но требует отдельной security review при каждом upgrade Authentik.

## Runtime prototype

Локальный bootstrap настраивает Brand для `auth.local.nodedc`:

- title: `NODE.DC`;
- default authentication flow: `default-authentication-flow`;
- flow title: `Работайте во всех измерениях.`;
- default locale: `ru`;
- theme: `dark`;
- dark NODE.DC CSS из `/templates/branding/nodedc-login.css`;
- без изменения password/MFA/recovery mechanics.

Файлы:

- `infra/authentik/bootstrap-dev.py` — idempotent Brand/Flow bootstrap;
- `infra/authentik/custom-templates/branding/nodedc-login.css` — native Authentik Brand CSS.

## Security acceptance

Перед переводом в production нужно проверить:

- пароль не проходит через Launcher/BFF/network logs вне Authentik;
- CSRF token и Authentik cookies остаются штатными;
- MFA/passkeys/recovery/enrollment работают после стилизации;
- failed login/lockout/audit events остаются в Authentik;
- logout/SLO закрывает Launcher и app sessions;
- прямой заход `task.local.nodedc` и `launcher.local.nodedc` возвращает пользователя после login;
- UI не содержит слова `authentik` в пользовательском flow;
- кастомизация переживает restart контейнеров и повторный bootstrap;
- fallback admin URL к Authentik остается доступен только как служебный контур.

## Upgrade policy

Brand/CSS считается безопасным maintenance layer. Template override считается повышенным риском: перед обновлением Authentik нужно прогонять visual/security regression, потому что DOM web components может измениться.

## Источники

- Authentik Flows: https://docs.goauthentik.io/docs/add-secure-apps/flows-stages/flow/
- Authentik Stages: https://docs.goauthentik.io/docs/flow/stages
- Password stage: https://docs.goauthentik.io/add-secure-apps/flows-stages/stages/password/
- Custom CSS: https://docs.goauthentik.io/brands/custom-css/
- Single Logout: https://docs.goauthentik.io/add-secure-apps/providers/single-logout/
