Files
transcriber/docs/adr/ADR-2026-08-12-protected-file-behind-session.md
T
av ad5b5e377f записано решение уйти с PocketBase на SQLite со своим каталогом файлов
- разведка storage-without-pocketbase: шесть ролей библиотеки в этом коде, отпавший довод перевода, шесть модулей достижимы только через неё
- ADR-2026-08-22-storage-without-pocketbase заменяет три записи: перевод в PocketBase, очередь коллекцией, файл за защищённым полем
- задача storage-without-pocketbase встала первой строкой плана стройки
2026-08-22 21:00:14 +03:00

4.8 KiB
Raw Blame History

Файл записи закрыт защищённым полем и отдаётся вошедшему по токену файла

Решение

Поле файла в хранилище помечается защищённым, а правило просмотра коллекции файлов пускает всякого узнанного. Ссылка /api/files/<коллекция>/<запись>/<имя> перестаёт быть правом пройти по ней: нужен короткий токен файла, который берут, предъявив сессию.

Запись заменяет ADR-2026-08-12-file-link-open-but-not-logged.

Почему

Прежнее решение было обусловленным и само назвало условие своего пересмотра:

Решение действует до разграничения доступа: задачи oidc-login и record-ownership меняют условие, и тогда пометку стоит пересмотреть новой записью.

Условие наступило. Прежний довод — «право прочитать задачу даёт знание её идентификатора, и файл встаёт вровень с GET /api/status/:id» — держался на том, что опрос готовности открыт анонимно. Этот change закрывает опрос за вход, и файл, оставшийся открытым, стал бы единственным анонимным путём к содержимому записи — самому чувствительному, что есть у проекта.

Вторая половина прежнего решения остаётся в силе: имя файла в журнал по-прежнему не пишется. Защищённое поле сужает право пройти, но не отменяет запрета — строка журнала со ссылкой собирала бы половину ключа.

Пометки самой по себе оказалось мало, и это выяснило ревью кода прогоном: защищённый файл судится и токеном, и правилом просмотра коллекции, а незаданное правило означает «только владелец панели». Файл не получал ни аноним, ни вошедший — сценарий спеки не исполнялся вовсе. Правило назначено тем же шагом схемы.

Последствия

  • + содержимое записи перестало быть доступным по одному знанию ссылки; после закрытия API это был последний анонимный путь к нему.
  • + условие, названное прежней записью, отработало как задумано: решение пересмотрено записью, а не молча.
  • ссылка усложнилась для потребителя: браузер с одной кукой файла не получает, нужен порядок «сессия → токен файла → ссылка». Будущее приложение обязано этот шаг делать, и задача про прослушивание записи начинается с него.
  • разграничения по владельцу нет: токен файла берёт всякий вошедший, и по ссылке он получит любую запись, а не только свою. Сужение приносит record-ownership; до неё круг сузился с «кто угодно из интернета» до «кто угодно из вошедших», и это меньше, чем кажется.
  • отзыва у выданного токена нет, как не было у ссылки; смягчает только его короткий срок.