АРХ - NODEDC PLATFORM: каркас платформенного репозитория
This commit is contained in:
commit
0f89c4d126
|
|
@ -0,0 +1,24 @@
|
|||
.DS_Store
|
||||
|
||||
# local env and secrets
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.*.example
|
||||
|
||||
# dependencies and build output
|
||||
node_modules/
|
||||
dist/
|
||||
build/
|
||||
.turbo/
|
||||
.next/
|
||||
coverage/
|
||||
|
||||
# logs
|
||||
*.log
|
||||
logs/
|
||||
|
||||
# local runtime data
|
||||
tmp/
|
||||
data/
|
||||
volumes/
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
# NODE.DC Platform
|
||||
|
||||
Платформенный слой для multi-app authentication architecture NODE.DC.
|
||||
|
||||
Эта папка не является монорепозиторием всех приложений. Здесь живут общая архитектура, Authentik/reverse-proxy инфраструктура, правила локального разворачивания, auth model, migration plan для Plane и будущий общий auth-sdk.
|
||||
|
||||
Git repo:
|
||||
|
||||
- `origin`: `https://git.dcserve.ru/SILVER/NODEDC_PLATFORM.git`
|
||||
- local branch: `main`
|
||||
|
||||
Текущие приложения остаются отдельными репозиториями:
|
||||
|
||||
- Launcher: `/Users/dcconstructions/Downloads/mnt/data/nodedc_launcher`
|
||||
- Task Manager / Plane fork: `/Users/dcconstructions/Downloads/mnt/data/dc_taskmanager/NODEDC_TASKMANAGER`
|
||||
- Plane runtime: `/Users/dcconstructions/Downloads/mnt/data/dc_taskmanager/NODEDC_TASKMANAGER/plane-app`
|
||||
- Plane source fork: `/Users/dcconstructions/Downloads/mnt/data/dc_taskmanager/NODEDC_TASKMANAGER/plane-src`
|
||||
|
||||
## Нулевой этап
|
||||
|
||||
Нулевой этап фиксирует discovery и каркас платформы без изменения бизнес-логики Launcher и Plane.
|
||||
|
||||
Артефакты:
|
||||
|
||||
- `docs/DISCOVERY_REPORT.md`
|
||||
- `docs/ARCHITECTURE.md`
|
||||
- `docs/AUTH_MODEL.md`
|
||||
- `docs/DEPLOYMENT_LOCAL.md`
|
||||
- `docs/SECURITY_CHECKLIST.md`
|
||||
- `docs/MIGRATION_PLANE_USER.md`
|
||||
- `infra/README.md`
|
||||
- `packages/auth-sdk/README.md`
|
||||
- `tasks/CODEX_PLATFORM_AUTH_TASK.md`
|
||||
|
||||
## Базовое правило
|
||||
|
||||
Plane не переносится внутрь Launcher. Launcher не становится владельцем таблиц Plane. Authentik становится единым Identity Provider, а приложения сохраняют собственные доменные БД и роли.
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
# Architecture: NODE.DC Multi-App Platform
|
||||
|
||||
## Цель
|
||||
|
||||
Собрать единую платформенную основу для Launcher, Task Manager / Plane и будущих приложений NODE.DC.
|
||||
|
||||
Целевой пользовательский сценарий:
|
||||
|
||||
1. Пользователь открывает Launcher.
|
||||
2. Если сессии нет, его отправляет в Authentik.
|
||||
3. После логина Launcher получает identity и app access.
|
||||
4. Launcher показывает только доступные приложения.
|
||||
5. Переход в Task Manager не требует повторного логина.
|
||||
6. Прямой URL Task Manager тоже защищен.
|
||||
|
||||
## Роли компонентов
|
||||
|
||||
`Authentik` является единым Identity Provider:
|
||||
|
||||
- логин;
|
||||
- пароль;
|
||||
- активность пользователя;
|
||||
- группы;
|
||||
- app access;
|
||||
- OIDC claims;
|
||||
- будущие invite/enrollment/MFA flows.
|
||||
|
||||
`Launcher` является control plane:
|
||||
|
||||
- входная точка пользователя;
|
||||
- список доступных приложений;
|
||||
- admin UI управления пользователями и доступами;
|
||||
- backend-интеграция с Authentik API;
|
||||
- audit log админских действий.
|
||||
|
||||
`Task Manager / Plane` остается отдельным приложением:
|
||||
|
||||
- собственная БД;
|
||||
- собственные workspace/project/task/comment модели;
|
||||
- собственные роли workspace/project;
|
||||
- OIDC login через Authentik;
|
||||
- mapping внешней identity на существующего Plane user.
|
||||
|
||||
`Reverse proxy` является внешним защитным и маршрутизирующим слоем:
|
||||
|
||||
- единая точка входа;
|
||||
- HTTPS в staging/production;
|
||||
- routing по app domain;
|
||||
- forward headers для Authentik;
|
||||
- deny для пользователей без app access.
|
||||
|
||||
## Repository layout
|
||||
|
||||
Рабочая схема:
|
||||
|
||||
```text
|
||||
NODEDC/
|
||||
DOC/
|
||||
platform/
|
||||
docs/
|
||||
infra/
|
||||
packages/
|
||||
tasks/
|
||||
|
||||
/Users/dcconstructions/Downloads/mnt/data/nodedc_launcher
|
||||
/Users/dcconstructions/Downloads/mnt/data/dc_taskmanager/NODEDC_TASKMANAGER
|
||||
```
|
||||
|
||||
`platform/` не забирает исходники Launcher и Plane внутрь себя. Он хранит только платформенный слой и договоренности между приложениями.
|
||||
|
||||
## Data ownership
|
||||
|
||||
Не создается единая общая таблица `users` для всех приложений.
|
||||
|
||||
Логическая схема:
|
||||
|
||||
```text
|
||||
authentik_db -> identity, groups, app access
|
||||
launcher_db -> app registry, local profiles, audit
|
||||
plane_db -> workspace, projects, tasks, comments, app roles
|
||||
future_app_db -> доменная логика будущих приложений
|
||||
```
|
||||
|
||||
Связь между identity и локальными пользователями выполняется через explicit mapping, а не через прямое чтение чужих таблиц.
|
||||
|
||||
## Auth flow
|
||||
|
||||
Для приложений, которые контролируются кодом:
|
||||
|
||||
- OIDC Authorization Code Flow + PKCE;
|
||||
- backend/session или BFF layer;
|
||||
- JWT/JWKS validation server-side;
|
||||
- проверка `issuer`, `audience`, `exp`, `sub`;
|
||||
- проверка app access group;
|
||||
- локальный user profile или external identity link.
|
||||
|
||||
Для legacy/временных приложений допускается reverse proxy forward-auth, но это временный внешний слой, а не единственная долгосрочная модель.
|
||||
|
||||
## Plane migration rule
|
||||
|
||||
Существующий Plane user нельзя пересоздавать.
|
||||
|
||||
Нужен mapping:
|
||||
|
||||
```text
|
||||
authentik_user.sub -> existing plane_user.id
|
||||
```
|
||||
|
||||
Plane должен логинить существующего пользователя по link, сохраняя все старые workspace, assignee, owner, created_by, comments и attachments.
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
# Auth Model
|
||||
|
||||
## Identity source
|
||||
|
||||
Единственный источник identity: Authentik.
|
||||
|
||||
Launcher, Plane и будущие приложения не хранят пароли пользователей и не становятся главным источником truth по логину.
|
||||
|
||||
## Required claims
|
||||
|
||||
Минимальный normalized user object:
|
||||
|
||||
```ts
|
||||
type AuthUser = {
|
||||
sub: string;
|
||||
email: string;
|
||||
name?: string;
|
||||
groups: string[];
|
||||
entitlements?: string[];
|
||||
};
|
||||
```
|
||||
|
||||
Обязательные проверки:
|
||||
|
||||
- `iss` совпадает с настроенным issuer;
|
||||
- `aud` совпадает с client/application audience;
|
||||
- `exp` не истек;
|
||||
- `sub` непустой и стабилен;
|
||||
- `email` присутствует для user-facing приложений;
|
||||
- `groups` или `entitlements` содержат требуемый app access.
|
||||
|
||||
## Groups
|
||||
|
||||
Минимальная группа верхнего уровня:
|
||||
|
||||
```text
|
||||
nodedc:superadmin
|
||||
```
|
||||
|
||||
Launcher:
|
||||
|
||||
```text
|
||||
nodedc:launcher:access
|
||||
nodedc:launcher:admin
|
||||
nodedc:launcher:user-manager
|
||||
```
|
||||
|
||||
Task Manager:
|
||||
|
||||
```text
|
||||
nodedc:taskmanager:access
|
||||
nodedc:taskmanager:admin
|
||||
```
|
||||
|
||||
Future apps:
|
||||
|
||||
```text
|
||||
nodedc:agents:access
|
||||
nodedc:tender:access
|
||||
nodedc:onec:access
|
||||
nodedc:dm:access
|
||||
```
|
||||
|
||||
## Access levels
|
||||
|
||||
Уровень 1: Authentik app access.
|
||||
|
||||
Отвечает на вопрос, можно ли открыть приложение.
|
||||
|
||||
Уровень 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;
|
||||
- выполнять admin calls к Authentik API;
|
||||
- хранить audit log;
|
||||
- возвращать frontend только нормализованные данные пользователя и разрешенные действия;
|
||||
- не отдавать access/refresh/service tokens в browser bundle.
|
||||
|
||||
## 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.
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
# Local Deployment Plan
|
||||
|
||||
## Domains
|
||||
|
||||
Для локальной разработки целевая схема:
|
||||
|
||||
```text
|
||||
127.0.0.1 auth.local.nodedc
|
||||
127.0.0.1 launcher.local.nodedc
|
||||
127.0.0.1 task.local.nodedc
|
||||
127.0.0.1 agents.local.nodedc
|
||||
127.0.0.1 tender.local.nodedc
|
||||
127.0.0.1 onec.local.nodedc
|
||||
127.0.0.1 dm.local.nodedc
|
||||
```
|
||||
|
||||
## Current local apps
|
||||
|
||||
Launcher сейчас запускается как Vite app из:
|
||||
|
||||
```text
|
||||
/Users/dcconstructions/Downloads/mnt/data/nodedc_launcher
|
||||
```
|
||||
|
||||
Task Manager сейчас доступен как Plane self-host runtime:
|
||||
|
||||
```text
|
||||
http://localhost:8090
|
||||
```
|
||||
|
||||
Runtime:
|
||||
|
||||
```text
|
||||
/Users/dcconstructions/Downloads/mnt/data/dc_taskmanager/NODEDC_TASKMANAGER/plane-app
|
||||
```
|
||||
|
||||
Source fork:
|
||||
|
||||
```text
|
||||
/Users/dcconstructions/Downloads/mnt/data/dc_taskmanager/NODEDC_TASKMANAGER/plane-src
|
||||
```
|
||||
|
||||
## Target local flow
|
||||
|
||||
Первый local infra milestone:
|
||||
|
||||
```text
|
||||
auth.local.nodedc -> Authentik
|
||||
launcher.local.nodedc -> Launcher web/backend
|
||||
task.local.nodedc -> Plane proxy/runtime
|
||||
```
|
||||
|
||||
Все внешние запросы идут через reverse proxy.
|
||||
|
||||
## Environment
|
||||
|
||||
Базовые переменные должны жить в:
|
||||
|
||||
```text
|
||||
platform/infra/.env
|
||||
```
|
||||
|
||||
Пример значений хранится в:
|
||||
|
||||
```text
|
||||
platform/infra/.env.example
|
||||
```
|
||||
|
||||
## Implementation order
|
||||
|
||||
1. Согласовать локальные domain/port bindings.
|
||||
2. Добавить reverse proxy config.
|
||||
3. Поднять Authentik server, worker, Postgres и Redis.
|
||||
4. Прокинуть Authentik за proxy с корректными headers.
|
||||
5. Подключить текущий Launcher как внешний сервис или через compose service.
|
||||
6. Подключить текущий Plane runtime как внешний service target.
|
||||
7. После стабилизации собрать воспроизводимый compose.
|
||||
|
||||
## Notes
|
||||
|
||||
Текущий Plane runtime не переносится на нулевом этапе. Любое изменение `plane-app/plane.env`, volumes или startup scripts делается только после backup и отдельной задачи.
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
# Discovery Report: NODE.DC Platform
|
||||
|
||||
Дата: 2026-05-04
|
||||
|
||||
## Источники
|
||||
|
||||
- Базовое ТЗ: `/Users/dcconstructions/Downloads/mnt/NODEDC/DOC/BASE/tz_codex_platform_authentik_launcher_plane.md`
|
||||
- Краткое ТЗ: `/Users/dcconstructions/Downloads/mnt/NODEDC/DOC/BASE/nodedc_auth.md`
|
||||
- Launcher repo: `/Users/dcconstructions/Downloads/mnt/data/nodedc_launcher`
|
||||
- Task Manager repo: `/Users/dcconstructions/Downloads/mnt/data/dc_taskmanager/NODEDC_TASKMANAGER`
|
||||
|
||||
## Workspace
|
||||
|
||||
`/Users/dcconstructions/Downloads/mnt/NODEDC` используется как внешний workspace-корень для платформенной работы.
|
||||
|
||||
Текущая папка `NODEDC` до нулевого этапа содержала только базовые документы в `DOC/BASE`. Отдельного git-репозитория в этой папке нет.
|
||||
|
||||
## Launcher
|
||||
|
||||
Путь: `/Users/dcconstructions/Downloads/mnt/data/nodedc_launcher`
|
||||
|
||||
Факты discovery:
|
||||
|
||||
- отдельный git-репозиторий;
|
||||
- Vite/React приложение;
|
||||
- основной entrypoint: `src/main.tsx`;
|
||||
- команды из `package.json`: `npm run dev`, `npm run build`, `npm run preview`, `npm run test`;
|
||||
- backend слоя в текущем Launcher не найдено;
|
||||
- значит OIDC/session handling, Authentik service token, app registry и audit log нельзя хранить только во frontend.
|
||||
|
||||
Минимальный вывод: для production-like auth нужен Launcher backend или BFF слой.
|
||||
|
||||
## Task Manager / Plane
|
||||
|
||||
Путь: `/Users/dcconstructions/Downloads/mnt/data/dc_taskmanager/NODEDC_TASKMANAGER`
|
||||
|
||||
Факты discovery:
|
||||
|
||||
- отдельный git-репозиторий;
|
||||
- self-host runtime лежит в `plane-app`;
|
||||
- локальный fork исходников лежит в `plane-src`;
|
||||
- Plane CE self-host запущен через Docker;
|
||||
- локальный URL стенда: `http://localhost:8090`;
|
||||
- текущий compose/env: `plane-app/docker-compose.yaml` и `plane-app/plane.env`;
|
||||
- текущий fork Plane: `plane-src`, версия `1.3.0`;
|
||||
- основной runtime-контейнер API: `plane-app-api-1`;
|
||||
- активные контейнеры Plane: web, proxy, api, worker, beat-worker, db, redis, minio, mq, admin, space, live.
|
||||
|
||||
Текущий workspace в Plane:
|
||||
|
||||
- slug: `nodedc`;
|
||||
- name: `NODE DC`;
|
||||
- owner: `dcctouch@gmail.com`;
|
||||
- codex user: `codex@nodedc.local`.
|
||||
|
||||
Существующие проекты в workspace `nodedc` на момент discovery:
|
||||
|
||||
- `NODEDCLAUN` / `NODEDC LAUNCHER`
|
||||
- `CODEX` / `DCTM-WT-CODEX`
|
||||
- `NODEDCTASK` / `NODEDC TASKMANAGER`
|
||||
- `MGR` / `Менеджмент`
|
||||
- `BUH` / `Бухгалтерия`
|
||||
|
||||
## NDC details в карточках
|
||||
|
||||
Канон карточек описан в `/Users/dcconstructions/Downloads/mnt/data/dc_taskmanager/NODEDC_TASKMANAGER/AGENTS.md`.
|
||||
|
||||
Структурированные блоки карточки хранятся в `Issue.detail_layout` под ключом:
|
||||
|
||||
```text
|
||||
nodedc_structured_blocks
|
||||
```
|
||||
|
||||
Типы блоков:
|
||||
|
||||
- `text`: текстовый блок с `title` и `body`;
|
||||
- `checker`: чекер с `title` и пунктами `items`.
|
||||
|
||||
Frontend отображает эти блоки через компоненты:
|
||||
|
||||
- `plane-src/apps/web/core/components/issues/issue-detail-widgets/structured-content.helpers.ts`
|
||||
- `plane-src/apps/web/core/components/issues/issue-detail-widgets/structured-content-blocks.tsx`
|
||||
|
||||
## Решение по переносам
|
||||
|
||||
Физически переносить Launcher и Task Manager внутрь `NODEDC` на нулевом этапе не нужно.
|
||||
|
||||
Причины:
|
||||
|
||||
- оба приложения уже являются отдельными git-репозиториями;
|
||||
- Plane runtime завязан на текущие `plane-app`, `plane.env`, volumes и backup;
|
||||
- перенос может сломать локальный self-host стенд;
|
||||
- платформенный слой должен управлять интеграцией, а не становиться монорепозиторием всех исходников.
|
||||
|
||||
Допустимый вариант позже: добавить symlink или workspace manifest из `NODEDC` на внешние репозитории, если это потребуется для удобства навигации.
|
||||
|
||||
## Риски
|
||||
|
||||
- Нельзя пересоздавать существующего Plane admin/user, иначе потеряются связи workspace, задач, комментариев и assignee.
|
||||
- Нельзя делать Authentik admin token доступным frontend-коду Launcher.
|
||||
- Нельзя полагаться только на reverse proxy как единственный долгосрочный auth layer для приложений, которые мы контролируем кодом.
|
||||
- Нельзя публиковать наружу Postgres, Redis, MinIO и внутренние API в staging/production.
|
||||
|
||||
## Следующий технический шаг
|
||||
|
||||
Создать локальный `platform/infra` слой с Authentik и reverse proxy, но сначала согласовать конкретную схему доменов, ports и secrets.
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
# Plane User Migration Plan
|
||||
|
||||
## Цель
|
||||
|
||||
Связать существующего пользователя Plane с Authentik identity без потери workspace, projects, tasks, comments, attachments и истории.
|
||||
|
||||
## Current baseline
|
||||
|
||||
Текущий рабочий Plane workspace:
|
||||
|
||||
```text
|
||||
workspace slug: nodedc
|
||||
workspace name: NODE DC
|
||||
workspace owner: dcctouch@gmail.com
|
||||
codex user: codex@nodedc.local
|
||||
```
|
||||
|
||||
Перед реализацией OIDC нужно дополнительно снять точный snapshot:
|
||||
|
||||
- users;
|
||||
- profiles;
|
||||
- workspace memberships;
|
||||
- project memberships;
|
||||
- issue ownership;
|
||||
- issue assignees;
|
||||
- comments;
|
||||
- attachments;
|
||||
- uploaded files/storage.
|
||||
|
||||
## Backup before changes
|
||||
|
||||
Перед любыми изменениями Plane auth:
|
||||
|
||||
```text
|
||||
plane_db dump
|
||||
plane-app/plane.env
|
||||
uploads / MinIO volumes
|
||||
redis, если в нем есть важные очереди/сессии
|
||||
rabbitmq, если есть невыполненные jobs
|
||||
```
|
||||
|
||||
## Mapping model
|
||||
|
||||
Минимальная модель:
|
||||
|
||||
```text
|
||||
external_identity_link
|
||||
id
|
||||
provider = authentik
|
||||
authentik_sub
|
||||
email
|
||||
plane_user_id
|
||||
created_at
|
||||
last_login_at
|
||||
status
|
||||
```
|
||||
|
||||
Уникальность:
|
||||
|
||||
- `provider + authentik_sub`;
|
||||
- `provider + plane_user_id`;
|
||||
- желательно `provider + email`, если email используется для migration auto-link.
|
||||
|
||||
## Login flow
|
||||
|
||||
```text
|
||||
Authentik login
|
||||
-> Plane OIDC callback
|
||||
-> validate state/nonce/token
|
||||
-> validate issuer/audience/exp/sub
|
||||
-> check nodedc:taskmanager:access
|
||||
-> find external_identity_link by authentik_sub
|
||||
-> login existing plane_user_id
|
||||
```
|
||||
|
||||
Migration auto-link допускается только контролируемо:
|
||||
|
||||
```text
|
||||
if no link and email matches existing Plane user and migration mode enabled:
|
||||
create external_identity_link
|
||||
else:
|
||||
deny or provisioning flow
|
||||
```
|
||||
|
||||
## Forbidden during migration
|
||||
|
||||
- Не пересоздавать существующего Plane user.
|
||||
- Не менять `created_by`.
|
||||
- Не менять `owner_id`.
|
||||
- Не менять `assignee_id`.
|
||||
- Не менять `member_id`.
|
||||
- Не делать bulk update связей задач без отдельной проверки.
|
||||
|
||||
## Management command target
|
||||
|
||||
Целевая команда:
|
||||
|
||||
```bash
|
||||
python manage.py link_authentik_user --email admin@example.ru --sub <authentik-sub>
|
||||
```
|
||||
|
||||
Требования:
|
||||
|
||||
- idempotent;
|
||||
- проверяет конфликтующий mapping;
|
||||
- ничего не меняет в задачах/workspace;
|
||||
- выводит summary;
|
||||
- поддерживает dry-run.
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
# Security Checklist
|
||||
|
||||
## Network
|
||||
|
||||
- [ ] Наружу опубликованы только reverse proxy ports.
|
||||
- [ ] Postgres не опубликован наружу в staging/production.
|
||||
- [ ] Redis не опубликован наружу в staging/production.
|
||||
- [ ] MinIO/storage не опубликован наружу в staging/production.
|
||||
- [ ] Внутренние API не доступны напрямую извне.
|
||||
- [ ] Authentik получает корректные `X-Forwarded-Proto`, `X-Forwarded-For`, `Host`.
|
||||
- [ ] WebSocket headers настроены для Authentik/Plane/live.
|
||||
|
||||
## Authentik
|
||||
|
||||
- [ ] Каждое приложение имеет отдельный Authentik Application.
|
||||
- [ ] Каждое приложение имеет отдельный Provider.
|
||||
- [ ] Для каждого приложения задана отдельная access policy.
|
||||
- [ ] Группы app access заведены отдельно от app-local ролей.
|
||||
- [ ] MFA/enrollment policy вынесены в отдельный этап.
|
||||
|
||||
## Launcher
|
||||
|
||||
- [ ] Authentik service token хранится только server-side.
|
||||
- [ ] Frontend не получает service token.
|
||||
- [ ] Admin endpoints требуют `nodedc:superadmin` или `nodedc:launcher:admin`.
|
||||
- [ ] Все admin actions пишутся в audit log.
|
||||
- [ ] Удаление пользователя реализовано как deactivate/disable, не hard delete.
|
||||
|
||||
## Plane
|
||||
|
||||
- [ ] Перед изменениями сделан backup DB/env/uploads/storage.
|
||||
- [ ] Существующий Plane user не пересоздается.
|
||||
- [ ] `owner_id`, `created_by`, `assignee_id`, `member_id` не меняются без отдельной миграции.
|
||||
- [ ] Публичный signup отключен.
|
||||
- [ ] Лишние обходные auth сценарии закрыты или явно оставлены как временные.
|
||||
- [ ] OIDC login проверяет state/nonce/token.
|
||||
- [ ] `authentik_sub` связан с существующим `plane_user_id`.
|
||||
|
||||
## Tokens and secrets
|
||||
|
||||
- [ ] Secrets не попадают в git.
|
||||
- [ ] Access/refresh tokens не логируются.
|
||||
- [ ] Session cookies имеют `secure=true` в staging/production.
|
||||
- [ ] В production включены HTTPS и HSTS.
|
||||
|
||||
## Acceptance scenarios
|
||||
|
||||
- [ ] Без логина Launcher отправляет в Authentik.
|
||||
- [ ] Пользователь без `nodedc:taskmanager:access` не видит Task Manager в Launcher.
|
||||
- [ ] Пользователь без `nodedc:taskmanager:access` получает deny на прямой `task.local.nodedc`.
|
||||
- [ ] Пользователь с доступом открывает Task Manager.
|
||||
- [ ] Старый Plane admin после OIDC видит старые workspace/tasks/comments.
|
||||
- [ ] Деактивированный пользователь теряет доступ.
|
||||
- [ ] Admin action появляется в audit log.
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
# domains
|
||||
AUTH_DOMAIN=auth.local.nodedc
|
||||
LAUNCHER_DOMAIN=launcher.local.nodedc
|
||||
TASK_DOMAIN=task.local.nodedc
|
||||
|
||||
# authentik
|
||||
AUTHENTIK_SECRET_KEY=
|
||||
AUTHENTIK_POSTGRES_PASSWORD=
|
||||
AUTHENTIK_REDIS_HOST=redis-authentik
|
||||
|
||||
# launcher oidc
|
||||
LAUNCHER_OIDC_ISSUER=http://auth.local.nodedc/application/o/launcher/
|
||||
LAUNCHER_OIDC_CLIENT_ID=
|
||||
LAUNCHER_OIDC_CLIENT_SECRET=
|
||||
LAUNCHER_OIDC_REDIRECT_URI=http://launcher.local.nodedc/auth/callback
|
||||
|
||||
# plane oidc
|
||||
PLANE_OIDC_ISSUER=http://auth.local.nodedc/application/o/task-manager/
|
||||
PLANE_OIDC_CLIENT_ID=
|
||||
PLANE_OIDC_CLIENT_SECRET=
|
||||
PLANE_OIDC_REDIRECT_URI=http://task.local.nodedc/auth/oidc/callback
|
||||
|
||||
# security
|
||||
SESSION_SECRET=
|
||||
COOKIE_DOMAIN=.local.nodedc
|
||||
COOKIE_SECURE=false
|
||||
|
||||
# current external local apps
|
||||
LOCAL_LAUNCHER_URL=http://localhost:5173
|
||||
LOCAL_TASK_MANAGER_URL=http://localhost:8090
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
# NODE.DC Platform Infra
|
||||
|
||||
Эта папка предназначена для локального и staging infra слоя:
|
||||
|
||||
- Authentik;
|
||||
- reverse proxy;
|
||||
- локальные домены;
|
||||
- shared env examples;
|
||||
- будущие docker compose файлы.
|
||||
|
||||
На нулевом этапе здесь фиксируется только каркас. Рабочий `docker-compose.dev.yml` создается отдельным этапом после согласования ports/domains и стратегии подключения текущих Launcher/Plane runtime.
|
||||
|
||||
## Expected files
|
||||
|
||||
```text
|
||||
infra/
|
||||
.env.example
|
||||
docker-compose.dev.yml
|
||||
docker-compose.staging.yml
|
||||
reverse-proxy/
|
||||
authentik/
|
||||
```
|
||||
|
||||
## Current decision
|
||||
|
||||
Текущий Plane runtime не переносится в compose платформы до backup и отдельного шага миграции.
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
# NODE.DC Auth SDK
|
||||
|
||||
Будущий общий пакет для приложений, которые контролируются кодом NODE.DC.
|
||||
|
||||
## Target responsibilities
|
||||
|
||||
- загрузка JWKS;
|
||||
- валидация JWT;
|
||||
- проверка issuer/audience/exp;
|
||||
- нормализация claims;
|
||||
- helper `requireAppAccess(groupName)`;
|
||||
- helper `getCurrentUser()`;
|
||||
- typed `AuthUser`.
|
||||
|
||||
## Type contract
|
||||
|
||||
```ts
|
||||
export type AuthUser = {
|
||||
sub: string;
|
||||
email: string;
|
||||
name?: string;
|
||||
groups: string[];
|
||||
entitlements?: string[];
|
||||
};
|
||||
```
|
||||
|
||||
## Scope
|
||||
|
||||
Первый SDK рассчитан на Launcher backend и будущие Node.js/Next.js сервисы.
|
||||
|
||||
Для Plane fork на Python/Django нужна отдельная реализация middleware по тем же правилам, а этот пакет остается спецификацией для TypeScript приложений.
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
# CODEX Platform Auth Task
|
||||
|
||||
## Goal
|
||||
|
||||
Построить NODE.DC platform auth architecture:
|
||||
|
||||
- Authentik как единый Identity Provider;
|
||||
- Launcher как access/admin control plane;
|
||||
- Plane fork как отдельное приложение;
|
||||
- reverse proxy как внешний защитный слой;
|
||||
- сохранение существующего Plane user и всех связанных данных;
|
||||
- поддержка будущих приложений.
|
||||
|
||||
## Hard constraints
|
||||
|
||||
- Не класть Plane внутрь Launcher.
|
||||
- Не делать единую `users` таблицу для всех приложений.
|
||||
- Не ломать существующего Plane user.
|
||||
- Не менять `owner`, `assignee`, `created_by`, `member` связи Plane без отдельной миграции.
|
||||
- Не хранить service tokens во frontend.
|
||||
- Не использовать reverse-proxy forward-auth как единственный долгосрочный auth mechanism для собственных приложений.
|
||||
|
||||
## Phase 0 result
|
||||
|
||||
Выполнены:
|
||||
|
||||
- discovery текущих путей Launcher и Task Manager;
|
||||
- фиксация решения не переносить репозитории физически;
|
||||
- platform skeleton;
|
||||
- базовые документы архитектуры, auth model, local deployment, security и migration plan.
|
||||
|
||||
## Next phases
|
||||
|
||||
1. Local domains + reverse proxy.
|
||||
2. Authentik bootstrap.
|
||||
3. Launcher backend/BFF.
|
||||
4. Launcher OIDC login and app filtering.
|
||||
5. Launcher admin API and audit.
|
||||
6. Plane OIDC integration.
|
||||
7. Plane user migration command.
|
||||
8. Security acceptance and staging path.
|
||||
Loading…
Reference in New Issue