ДОКИ - NODEDC PLATFORM: close auth acceptance hangers

This commit is contained in:
DCCONSTRUCTIONS 2026-05-04 22:07:16 +03:00
parent 4e90dcdd7c
commit a10b28f3ee
2 changed files with 22 additions and 20 deletions

2
.gitignore vendored
View File

@ -1,4 +1,6 @@
.DS_Store
__pycache__/
scripts/__pycache__/
plane-src/node_modules/
plane-src/.turbo/
plane-src/.next/

View File

@ -344,7 +344,7 @@ Launcher должен проходить OIDC Authorization Code Flow + PKCE ч
{"text": "Загрузить JWKS и валидировать JWT.", "checked": True},
{"text": "Нормализовать sub/email/name/groups.", "checked": True},
{"text": "Добавить logout flow.", "checked": True},
{"text": "Подтвердить browser login/logout через launcher.local.nodedc.", "checked": False},
{"text": "Подтвердить browser login/logout через launcher.local.nodedc.", "checked": True},
],
),
text_block(
@ -367,7 +367,7 @@ Launcher показывает приложения не статическим
{"text": "Добавить GET /api/apps.", "checked": True},
{"text": "Вычислять access state из runtime projection groups.", "checked": True},
{"text": "Не скрывать недоступные плитки, а показывать Нет доступа.", "checked": True},
{"text": "Проверить direct URL behavior через proxy.", "checked": False},
{"text": "Проверить direct URL behavior через proxy.", "checked": True},
],
),
text_block(
@ -408,10 +408,10 @@ Production flow: пользователь открывает nodedc.ru, види
{"text": "Скрыть Authentik brand в базовом authentication page title/brand.", "checked": True},
{"text": "Исключить Authentik My applications dashboard из пользовательского маршрута.", "checked": True},
{"text": "Исключить Authentik application logout dashboard из пользовательского маршрута.", "checked": True},
"Поддержать returnTo для прямых ссылок на приложения.",
"Поддержать forced login для диагностики.",
{"text": "Поддержать returnTo для прямых ссылок на приложения.", "checked": True},
{"text": "Поддержать forced login для диагностики.", "checked": True},
"Спроектировать recovery/enrollment/MFA без раскрытия Authentik UI.",
"Проверить, что password/service tokens не попадают во frontend.",
{"text": "Проверить, что password/service tokens не попадают во frontend.", "checked": True},
],
),
text_block(
@ -426,21 +426,21 @@ OIDC flow реализован как Authorization Code + PKCE: state хран
App registry возвращает полный каталог приложений из launcher storage и runtime access state: hasAccess, matchedGroups, accessReason. Frontend больше не скрывает недоступные плитки; он отключает переход и показывает "Нет доступа" через существующую механику карточек.
Frontend Launcher подключен к /api/me и /api/apps. Без session показывается нейтральный экран "Вход на платформу NODE.DC" и кнопка "Войти" без упоминания Authentik. После login пользователь нормализуется из OIDC claims, а плитки получают доступы из runtime app registry.
Frontend Launcher подключен к /api/me и /api/apps. Без session Launcher больше не показывает промежуточное окно с кнопкой "Войти": frontend делает прямой replace на /auth/login, а сам /auth/login сразу отдает 302 в Authentik authorize flow. Если пользователь пришел на непустой launcher path, frontend добавляет returnTo к login URL, чтобы после callback вернуть его на исходный маршрут. После login пользователь нормализуется из OIDC claims, а плитки получают доступы из runtime app registry.
Проверки 2026-05-04: npm run build проходит; http://launcher.local.nodedc/healthz возвращает oidcConfigured=true; http://launcher.local.nodedc/api/me без session возвращает 401 и loginUrl; http://launcher.local.nodedc/auth/login возвращает 302 на Authentik authorize endpoint; discovery endpoint Authentik для launcher возвращает issuer и authorization_endpoint.
Ручная проверка 2026-05-04 выявила callback error {"error":"JSON Web Key Set malformed"}. Root cause: Authentik OAuth2 providers были созданы без signing_key, поэтому JWKS endpoint отдавал {}. Bootstrap исправлен: providers получают authentik Self-signed Certificate как signing key. После повторного bootstrap JWKS отдает RSA key.
Открытый приемочный пункт: ручной browser login/logout через http://launcher.local.nodedc и проверка, что после callback видна плитка Task Manager.
Ручной browser login/logout через http://launcher.local.nodedc подтвержден пользователем: после callback видна витрина Launcher, OPERATIONAL CORE открывает Task Manager, global logout закрывает Launcher и downstream session.
Граница готовности на текущий момент: Launcher готов как базовый OIDC/BFF portal, но не является финально готовым production control plane. Остаются mock/dev элементы и следующий обязательный блок Plane OIDC. Пока Plane OIDC не реализован, переход из Launcher в task.local.nodedc ожидаемо приводит к старой авторизации Plane, потому что Task Manager еще не доверяет Authentik session.
Граница готовности на текущий момент: Launcher готов как базовый OIDC/BFF portal и local control-plane prototype, но не является финально готовым production control plane. Остаются mock/dev элементы, JSON-backed persistence, recovery/MFA UX и production storage/profile work.
2026-05-04 добавлен явный logout в профильное меню Launcher: кнопка "Выйти" вызывает /auth/logout и чистит local BFF session без ухода в Authentik UI/admin. Это нужно, чтобы пользователь оставался в NODE.DC UX после выхода.
SSO-session у identity provider может оставаться активной. Поэтому повторное нажатие "Войти" может вернуть пользователя в Launcher без ввода пароля это ожидаемое SSO-поведение, а не ошибка. Для диагностики добавлен prompt=login на /auth/login?prompt=login и отдельный global logout через /auth/logout?global=1, но пользовательский logout по умолчанию остается локальным.
2026-05-04 повторная ручная проверка подтвердила целевой UX gap: после нажатия "Войти" пользователь все еще видит стандартное окно Authentik. Это зафиксировано как отдельный backlog-этап NODE.DC login facade; текущий hosted login не считать production-ready.
2026-05-04 login facade переведен на безопасную Authentik-native кастомизацию: Brand/CSS/template JS без proxy над password form. Окно приведено к NODE.DC/Plane визуальному канону, Authentik dashboard/logout application UI исключены из пользовательского маршрута, логотип синхронизирован с Launcher top bar по размеру и позиции.
Текущий BFF/OIDC слой является переходной реализацией. Сейчас app access читается из OIDC groups как runtime projection, но целевая source-of-truth модель Launcher backend: клиенты, членства, группы клиента, user grants, deny exceptions, профиль платформы и audit. Authentik должен получать из Launcher синхронизированную техническую проекцию для SSO/enforcement, а не быть ручной бизнес-админкой.
""",
@ -473,7 +473,7 @@ Launcher Admin API должен владеть бизнес-администри
{"text": "Добавить admin_audit_log запись для backend mutations.", "checked": True},
{"text": "Подключить frontend admin overlay к новым admin endpoints.", "checked": True},
"Заменить JSON-backed store на production persistence.",
"Реализовать фактический server-side sync в Authentik.",
{"text": "Реализовать фактический server-side sync в Authentik.", "checked": True},
],
),
text_block(
@ -701,7 +701,7 @@ Plane должен принимать Authentik OIDC callback, валидиро
{"text": "Проверять nodedc:taskmanager:access.", "checked": True},
{"text": "Искать link по authentik_sub.", "checked": True},
{"text": "Логинить существующего plane_user_id.", "checked": True},
"Закрыть путь без mapping или app access.",
{"text": "Закрыть путь без mapping или app access.", "checked": True},
],
),
text_block(
@ -739,7 +739,7 @@ Access check завязан на группы Authentik: nodedc:superadmin, node
{"text": "Проверять конфликтующий mapping.", "checked": True},
{"text": "Не менять задачи/workspace/memberships.", "checked": True},
{"text": "Отключить публичный signup.", "checked": True},
"Закрыть лишние OAuth/magic-link обходы, если они нарушают invite/manual модель.",
{"text": "Закрыть лишние OAuth/magic-link обходы, если они нарушают invite/manual модель.", "checked": True},
{"text": "Проверить старый admin после OIDC login.", "checked": True},
],
),
@ -813,7 +813,7 @@ Plane должен не только пускать пользователя п
{"text": "Добавить Task Manager front-channel logout endpoint /logout.", "checked": True},
{"text": "Закрывать app sessions из Launcher global logout перед IdP logout.", "checked": True},
{"text": "Проверить Plane API -> Launcher check из контейнера.", "checked": True},
"Провести ручной browser acceptance: снять доступ и увидеть отзыв уже открытой Plane-сессии.",
{"text": "Провести ручной browser acceptance: снять доступ и увидеть отзыв уже открытой Plane-сессии.", "checked": True},
],
),
text_block(
@ -945,7 +945,7 @@ Plane должен оставаться самостоятельным прод
"security",
"Текущая архитектура",
"""
Security checklist создан в platform/docs/SECURITY_CHECKLIST.md. Реальных acceptance tests по новой auth architecture пока нет, потому что Authentik/proxy/Launcher OIDC/Plane OIDC еще не реализованы.
Security checklist создан в platform/docs/SECURITY_CHECKLIST.md. Базовый local acceptance по happy path и части negative path уже пройден: Launcher без session уводит в OIDC login, недоступные плитки отображаются как disabled/Нет доступа, снятие доступа отзывает открытую Plane-сессию, старый Plane admin проходит через OIDC migration, frontend bundle не содержит service-token маркеров. Остаются destructive/edge checks: direct deny без group access, deactivated user, audit log и staging-hardening.
""",
),
text_block(
@ -961,15 +961,15 @@ Security checklist создан в platform/docs/SECURITY_CHECKLIST.md. Реал
"security1",
"Чекер этапа 1. Security acceptance tests",
[
"Проверить redirect Launcher без логина.",
"Проверить скрытие Task Manager без group access.",
{"text": "Проверить redirect Launcher без логина.", "checked": True},
{"text": "Проверить скрытие Task Manager без group access.", "checked": True},
"Проверить deny на прямой task.local.nodedc без group access.",
"Проверить отзыв уже открытой downstream-сессии после снятия доступа.",
"Проверить успешный вход пользователя с access.",
"Проверить старого Plane admin после OIDC migration.",
{"text": "Проверить отзыв уже открытой downstream-сессии после снятия доступа.", "checked": True},
{"text": "Проверить успешный вход пользователя с access.", "checked": True},
{"text": "Проверить старого Plane admin после OIDC migration.", "checked": True},
"Проверить deactivate user.",
"Проверить audit log admin actions.",
"Проверить отсутствие service tokens во frontend bundle.",
{"text": "Проверить отсутствие service tokens во frontend bundle.", "checked": True},
],
),
text_block(