Files
transcriber/docs/adr/ADR-2026-08-22-login-by-trusted-header.md
T
av 7f33c957e5 вход переехал на доверенный заголовок Authelia вместо собственного OIDC
- пришедшего называет заголовок Remote-User от прокси, и верят ему только с
  адреса из перечня trusted_proxies; своего входа у сервиса не осталось — ни
  корня /auth, ни кук, ни срока сессии, ни секрета клиента в конфиге и в базе
- учётная запись заводится первым обращением: EnsureUser в пакете хранилища,
  шаг схемы 202608220001 с колонкой provider_login и снятыми правилами users
- cmd/oidcstub заменён на cmd/devtools с подкомандой proxy; заодно закрыт
  унаследованный DL3066 — пользователь образа назван числом
2026-08-22 20:24:22 +03:00

5.9 KiB
Raw Blame History

Пришедшего называет заголовок доверенного прокси, а не собственный вход OIDC

  • Дата: 2026-08-22
  • Источник: openspec/changes/archive/trusted-header-login/design.md

Решение

Сервис перестаёт вести вход сам. Кто пришёл, он узнаёт из заголовка Remote-User, поставленного обратным прокси, который сходил к Authelia; заголовку верят только с адреса из объявленного перечня, а адрес берётся у самого соединения. Учётная запись заводится первым обращением с новым логином и находится по нему же дальше.

Убраны целиком: корень /auth с тремя адресами, куки transcriber_session и transcriber_login, сверка состояния и проверочный код PKCE, обмен кода внутрипроцессным запросом к роутеру хранилища, слои предъявления куки и запрета продления, приведение настроек провайдера к конфигу, секрет клиента и срок жизни сессии.

Почему

Цитата из источника, раздел Р3:

Сервис не выдаёт браузеру ни куки, ни токена. Каждый запрос узнаётся заново, по заголовку, который прокси поставил, сходив к Authelia.

Это и есть выгода задачи: отзыв доступа перестаёт ждать. Пока сервис выдавал значение, живущее семь суток, отозванный у провайдера человек работал до истечения этого значения, и другого канала отзыва не было.

Оттуда же, Р1 — почему доверие судится адресом соединения, а не пересылаемым заголовком:

X-Forwarded-For и его родня. Значение целиком задаёт тот, кто шлёт запрос. Барьер, который подделывается той же строкой, что и обходится, не барьер вовсе.

Отвергнут промежуточный вариант — заголовок как вход, сессия хранилища как продолжение (Р3):

Дешевле в работе (слой срабатывал бы раз в неделю, а не на каждом запросе), но возвращает ровно то, что задача убирает: значение, переживающее отзыв. Семь суток вернулись бы вместе с ним.

Контур к решению был готов заранее: обратный прокси уже отдавал Remote-* трём соседним сервисам того же контура, а правила для этого сервиса там не было вовсе — он не выложен.

Последствия

  • + Отзыв доступа действует со следующего запроса, а не через семь суток: Authelia судит каждое обращение.
  • + Секрет клиента исчез из конфига и из базы. Изъятие из инварианта «Секрет не покидает конфиг» снято: чтение файла базы больше не равносильно чтению секрета.
  • + Своего протокола входа у сервиса не осталось — вместе с ним исчезли пять накопившихся задач о его механике.
  • + Панель закрывается доменом, а не правилом на литерал пути; обход подменой знака перестаёт существовать.
  • Весь барьер держится на настройке прокси. Прокси, добавляющий заголовок вместо замены, открывает сервис любому под любым именем. Половину беды сервис закрывает сам — запрос с двумя значениями заголовка не узнаёт никого, — вторую проверить отсюда нечем: правило живёт в pet-project-server.
  • Логин у провайдера переиспользуем, и новый его владелец получает архив прежнего. Неизменяемого признака заголовок не приносит; не допускать переиспользования — работа провайдера. Обратная сторона: переименование заводит новую запись, а прежняя остаётся с архивом, который нечем ни слить, ни убрать.
  • Поиск учётной записи идёт на каждом запросе к области приложения вместо раза в неделю. Уникальный индекс делает это одним обращением к базе; замера не требовалось — сервисом пользуются единицы человек.
  • Половина работы лежит вне репозитория: до того как правило прокси и правило Authelia на домен заведут, сервис не узнает никого.