diff --git a/tasks/BACKLOG.md b/tasks/BACKLOG.md index a43ba11..0b096c2 100644 --- a/tasks/BACKLOG.md +++ b/tasks/BACKLOG.md @@ -43,7 +43,6 @@ ## Очередь -- [✨ Пускать по доверенным заголовкам Authelia вместо входа OIDC](items/trusted-header-login.md) — Вход собран своими руками — состояние, PKCE, обмен кода внутрипроцессным запросом к роутеру хранилища, — а обратный прокси уже отдаёт трём соседним сервисам заголовки Remote-* от Authelia; заодно секрет клиента лежит в базе, а панель обходится подменой знака в пути. - [🧹 Поднимать сервис для локальной работы одной командой](items/dev-run-task.md) — Локальная проверка требует ручной чистки каталога данных и остановки процесса, а владельца панели заводят по одноразовой ссылке из журнала. - [✨ Сделать экран загрузки записи и её состояния](items/upload-and-status-screen.md) — Первое, ради чего приложение открывают: отдать файл и увидеть, что с ним происходит. - [✨ Сделать экран списка своих записей и чтения текста](items/records-list-screen.md) — Расшифровка сегодня доходит одним сообщением и теряется в переписке; вернуться к ней через неделю нечем. diff --git a/tasks/items/dev-run-task.md b/tasks/items/dev-run-task.md index c053442..d1d0908 100644 --- a/tasks/items/dev-run-task.md +++ b/tasks/items/dev-run-task.md @@ -8,7 +8,8 @@ временный каталог, заводит владельца панели и гасит процесс по Ctrl+C. Работа состоит из двух частей, и они едут одним коммитом: инструмент -`cmd/devadmin` и шаг `dev`, который его зовёт. Порознь они не нужны — шаг без +подкоманда `cmd/devtools admin` и шаг `dev`, который её зовёт. Порознь они не +нужны — шаг без инструмента не заведёт владельца панели, инструмент без шага останется вызовом, который никто не делает. @@ -24,23 +25,27 @@ каталог со своим `data_dir`, чтобы прогон начинался с пустой базы независимо от того, что написано в конфиге. Временное живёт в `/tmp` — в `data/` писать запрещено (CLAUDE.md, «Запреты»); -- владельца панели заводит `cmd/devadmin` — отдельный main-пакет рядом с - `cmd/transcriber`, в образ он не едет. Базу открывает тем же `pbrepo.New`, что и - сервис, и потому получает её со схемой целиком; зовётся до подъёма сервиса, на - пустом каталоге. Пароль существующего владельца не переписывает; +- владельца панели заводит подкоманда `cmd/devtools admin`. Пакет оснастки уже + заведён задачей `trusted-header-login` и в образ не едет; своего пакета + заводить не надо — решение владельца 2026-08-22: инструмент оснастки стоит + четырёх мест, и платить их надо однажды. Базу подкоманда открывает тем же + `pbrepo.New`, что и сервис, и потому получает её со схемой целиком; зовётся до + подъёма сервиса, на пустом каталоге. Пароль существующего владельца не + переписывает; - обычная учётная запись заводится первым запросом с заголовком: имя берётся из `USER`, и заводить её отдельно шагу не нужно; - `trap` на `INT` и `TERM` гасит процесс, `wait` держит терминал. ## Затрагивает -- `cmd/devadmin` — новый main-пакет: заводит владельца панели в базе; +- `cmd/devtools` — подкоманда `admin` рядом с готовой `proxy`: заводит + владельца панели в базе; - `Taskfile.yml` — шаг `dev` с переменными `CONFIG` и `USER`; - скрипт запуска в `scripts/` — он попадает под шаг `shell` гейта; - `CLAUDE.md`, раздел «Команды»; - `README.md`, раздел про локальный запуск; -- `Dockerfile` — строка сборки называет точку входа поимённо, и новый пакет в - образ попасть не должен. +- `Dockerfile` — строка сборки называет точку входа поимённо; новых пакетов не + прибавляется, и правки ей не нужно. ## Критерии приёмки diff --git a/tasks/items/settings-screen.md b/tasks/items/settings-screen.md index 69f3c20..3585cc8 100644 --- a/tasks/items/settings-screen.md +++ b/tasks/items/settings-screen.md @@ -37,4 +37,4 @@ Применением настроек к конвейеру занимаются `llm-insights-adapter`, `literary-text-level` и `ntfy-delivery` — здесь только дом настроек и экран. Выпуск токенов API живёт на этом же экране, но заводит его `api-tokens`. -Берётся после `oidc-login`: до неё настройки не к кому привязать. +Берётся после `trusted-header-login`: до неё настройки не к кому привязать. diff --git a/tasks/items/speechkit-callback-fit.md b/tasks/items/speechkit-callback-fit.md index c367033..1d4d8f1 100644 --- a/tasks/items/speechkit-callback-fit.md +++ b/tasks/items/speechkit-callback-fit.md @@ -29,4 +29,4 @@ Прогон на реальных ключах Yandex запрещён — ответ ищется в документации сервиса и, если понадобится замер, отдельным разрешением человека с названной ценой. Уведомление требует адреса, доступного снаружи: сегодня он есть, но закрывать -его будет `oidc-login`, и это учитывается в ответе. +его будет `trusted-header-login`, и это учитывается в ответе. diff --git a/tasks/items/trusted-header-login.md b/tasks/items/trusted-header-login.md deleted file mode 100644 index f2c8ef1..0000000 --- a/tasks/items/trusted-header-login.md +++ /dev/null @@ -1,72 +0,0 @@ -# ✨ Пускать по доверенным заголовкам Authelia вместо входа OIDC - -- **Тип:** feature -- **Категория:** Очередь — Вход переезжает на заголовки прокси: пять задач про механику OIDC этим закрываются, а всё, что трогает вход и локальный прогон, ставится на него -- **Зачем:** Вход собран своими руками — состояние, PKCE, обмен кода внутрипроцессным запросом к роутеру хранилища, — а обратный прокси уже отдаёт трём соседним сервисам заголовки Remote-* от Authelia; заодно секрет клиента лежит в базе, а панель обходится подменой знака в пути. - -Кто пришёл, сервис узнаёт из заголовка, который поставил обратный прокси, сходив -к Authelia. Своего входа у сервиса не остаётся вовсе: ни адреса, уводящего к -провайдеру, ни возврата, ни куки сессии, ни выхода. - -Контур к этому готов: `files/caddyproxy/Caddyfile.template` в -`pet-project-server` уже отдаёт `Remote-User`, `Remote-Groups`, `Remote-Email` и -`Remote-Name` панели, netdata и remembos, а правила для этого сервиса там нет -вовсе — он не выложен. Контейнер портов наружу не публикует. - -Три следствия, ради которых это и делается. Отзыв доступа перестаёт ждать -семи суток: Authelia судит каждый запрос, а не только вход. Секрет клиента -уходит из конфига и из базы — вместе с ним снимается изъятие из инварианта -«Секрет не покидает конфиг». Панель закрывается доменом, а не правилом на литерал -пути, и обход `/%5f/` перестаёт существовать. - -## Затрагивает - -- адреса `GET /auth/login`, `GET /auth/callback`, `POST /auth/logout` — исчезают - целиком вместе с корнем `/auth`; -- куки `transcriber_session` и `transcriber_login`, слои `SessionFromCookie` и - `BlockSessionRefresh`; -- заголовки `Remote-User`, `Remote-Email`, `Remote-Name` — новый недоверенный - вход, и адрес источника запроса как условие доверия к ним; -- секция `[auth]` конфига и `config.example.toml`: имена ключей — необратимое; -- настройки провайдера у коллекции `users` (`ApplyProviderSettings`) и новый шаг - схемы; применённый `202608120001_oidc_login` не переписывается; -- собственные адреса входа хранилища под `/api/collections/users/`: обмена кода, - входа по паролю и запроса подтверждения почты больше не предъявляет никто; -- `cmd/oidcstub` и подставной провайдер в тестах входа; -- способ представиться на машине без прокси: сегодня им служит заглушка - провайдера, и замену ей называет эта задача — на неё опирается `dev-run-task`; -- спека `access`; `docs/security.md` — периметр, недоверенный вход, «Четвёртый - сдвиг»; `CLAUDE.md` — изъятие из инварианта о секрете; `docs/architecture.md`; -- правило прокси и правило Authelia для домена сервиса — они живут в - `pet-project-server`, вне этого репозитория. - -## Критерии приёмки - -- Обращение к адресу приложения с заголовком от доверенного источника идёт от - имени учётной записи, заведённой при первом таком обращении, а повторное с тем - же значением попадает в ту же запись. Оракул — тест обработчика: два запроса - подряд, в хранилище одна запись пользователя. -- Тот же заголовок с недоверенного адреса даёт `401`, а не вход под названным - именем. Оракул — тест: запрос с адресом источника вне перечня доверенных. -- Собственные адреса входа хранилища сессии не выдают и учётную запись не - меняют. Оракул — тест по перечню адресов под `/api/collections/users/`: каждый - отвечает отказом. -- Механики OIDC в дереве не осталось: корня `/auth`, кук входа, - `ApplyProviderSettings`, `cmd/oidcstub` и секрета клиента в конфиге. Оракул — - поиск по этим именам плюс зелёный `task gate`. -- Разграничение записей по владельцу работает как прежде: чужая запись - неотличима от несуществующей. Оракул — существующие тесты владельца остаются - зелёными. - -## Рамки - -Ключ учётной записи — `Remote-User`: переименование пользователя в Authelia -заведёт новую запись, и прежние записи останутся у прежней. Это принятая цена, -и она записывается в спеку, а не обходится. - -Второй уровень доступа по `Remote-Groups` здесь не заводится: его потребителя — -страницы расхода — ещё нет. - -Половина работы живёт в `pet-project-server` и этим репозиторием не проверяется -ничем: задача обязана назвать требование к контуру в `docs/security.md`, а -выкладку запускает человек.