HTTP API закрыт за вход через OIDC у Authelia
- шаг схемы закрывает поверхность, которую хранилище приносит открытой: собственную регистрацию, вход по паролю и одноразовый код — без этого закрытие приёма обходилось двумя запросами - продление сессии выключено, срок семь суток: иначе отзыв доступа у провайдера до сервиса не доходит никогда - файл записи отдаётся вошедшему по токену файла — пересмотр ADR-2026-08-12-file-link-open-but-not-logged
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
# Файл записи закрыт защищённым полем и отдаётся вошедшему по токену файла
|
||||
|
||||
- **Дата:** 2026-08-12
|
||||
- **Источник:** [../../openspec/changes/archive/2026-08-12-oidc-login/design.md](../../openspec/changes/archive/2026-08-12-oidc-login/design.md),
|
||||
раздел «Что изменило ревью кода», плюс отчёт триажа
|
||||
[../../openspec/changes/archive/2026-08-12-oidc-login/review/report.md](../../openspec/changes/archive/2026-08-12-oidc-login/review/report.md),
|
||||
пункт 3
|
||||
|
||||
## Решение
|
||||
|
||||
Поле файла в хранилище **помечается защищённым**, а правило просмотра коллекции
|
||||
файлов пускает всякого узнанного. Ссылка `/api/files/<коллекция>/<запись>/<имя>`
|
||||
перестаёт быть правом пройти по ней: нужен короткий токен файла, который берут,
|
||||
предъявив сессию.
|
||||
|
||||
Запись заменяет [ADR-2026-08-12-file-link-open-but-not-logged](ADR-2026-08-12-file-link-open-but-not-logged.md).
|
||||
|
||||
## Почему
|
||||
|
||||
Прежнее решение было обусловленным и само назвало условие своего пересмотра:
|
||||
|
||||
> Решение действует до разграничения доступа: задачи `oidc-login` и
|
||||
> `record-ownership` меняют условие, и тогда пометку стоит пересмотреть новой
|
||||
> записью.
|
||||
|
||||
Условие наступило. Прежний довод — «право прочитать задачу даёт знание её
|
||||
идентификатора, и файл встаёт вровень с `GET /api/status/:id`» — держался на том,
|
||||
что опрос готовности открыт анонимно. Этот change закрывает опрос за вход, и
|
||||
файл, оставшийся открытым, стал бы единственным анонимным путём к содержимому
|
||||
записи — самому чувствительному, что есть у проекта.
|
||||
|
||||
Вторая половина прежнего решения остаётся в силе: имя файла в журнал по-прежнему
|
||||
не пишется. Защищённое поле сужает право пройти, но не отменяет запрета —
|
||||
строка журнала со ссылкой собирала бы половину ключа.
|
||||
|
||||
Пометки самой по себе оказалось мало, и это выяснило ревью кода прогоном:
|
||||
защищённый файл судится **и** токеном, **и** правилом просмотра коллекции, а
|
||||
незаданное правило означает «только владелец панели». Файл не получал ни аноним,
|
||||
ни вошедший — сценарий спеки не исполнялся вовсе. Правило назначено тем же шагом
|
||||
схемы.
|
||||
|
||||
## Последствия
|
||||
|
||||
- `+` содержимое записи перестало быть доступным по одному знанию ссылки; после
|
||||
закрытия API это был последний анонимный путь к нему.
|
||||
- `+` условие, названное прежней записью, отработало как задумано: решение
|
||||
пересмотрено записью, а не молча.
|
||||
- `−` ссылка усложнилась для потребителя: браузер с одной кукой файла не
|
||||
получает, нужен порядок «сессия → токен файла → ссылка». Будущее приложение
|
||||
обязано этот шаг делать, и задача про прослушивание записи начинается с него.
|
||||
- `−` разграничения по владельцу нет: токен файла берёт всякий вошедший, и по
|
||||
ссылке он получит **любую** запись, а не только свою. Сужение приносит
|
||||
`record-ownership`; до неё круг сузился с «кто угодно из интернета» до «кто
|
||||
угодно из вошедших», и это меньше, чем кажется.
|
||||
- `−` отзыва у выданного токена нет, как не было у ссылки; смягчает только его
|
||||
короткий срок.
|
||||
Reference in New Issue
Block a user