docs: решено перевести хранилище и файлы записей на PocketBase

- разведка pocketbase-admin-fit ответила замером панели версии 0.39.10:
  записка в docs/research/pocketbase.md, решение — в ADR
- панель показывает файлы и пользователей только своих, поэтому файлы
  переезжают в её раскладку, а вход идёт через её провайдера OIDC
- периметр расширился панелью на /_/ и паролем суперпользователя;
  закрывает её Authelia на прокси, задачи в беклоге у этого нет
This commit is contained in:
av
2026-08-11 13:03:38 +03:00
parent ba7b4f37a6
commit 10ffe8bec3
10 changed files with 299 additions and 34 deletions
+31
View File
@@ -17,6 +17,17 @@
сделало сервис архивом. Оба сдвига описаны ниже разделами «Куда
уходит содержимое записи» и «Что вне модели».
**Третий сдвиг — панель администратора.** Решением от 2026-08-11
([adr](adr/ADR-2026-08-11-pocketbase-storage-with-admin-panel.md)) хранилищем
становится PocketBase, и вместе с ним на том же порту появляется панель по
адресу `/_/`: доступ ко всем записям, всем файлам и всем пользователям разом.
Порт опубликован в интернет через обратный прокси, а сама PocketBase вход в
панель через Authelia не пускает — у неё свой пароль суперпользователя.
**Закрывает панель контур, а не приложение:** решением владельца от 2026-08-11
адрес `/_/` закрывает Authelia на обратном прокси, пропуская только группу
администраторов. Задачи в беклоге у этого нет — работа принадлежит выкладке, а
она вне модели («Что вне модели», строка про контур).
Отсюда главное следствие, из которого читается всё остальное: **`POST /api/audio`
доступен кому угодно из интернета**. Отправитель не назван, не ограничен по числу
запросов и не ограничен по размеру файла.
@@ -93,6 +104,14 @@ Telegram отправителю.
заодно сообщал бы, что запись у кого-то уже есть.
- **Файлы фрагментов** (`long-audio-chunking`) ложатся рядом с исходным в тот же
плоский каталог — раскладка `data/files` меняется, и это необратимо.
- **Раскладку выбирает PocketBase** (`pocketbase-storage`), и плоского каталога
не остаётся вовсе: файл ложится в
`pb_data/storage/<коллекция>/<запись>/<имя>_<10 случайных символов>` рядом с
файлом атрибутов. Имя, данное отправителем, в путь при этом попадает — сегодня
от него берётся только расширение. Файл уходит не с диска напрямую, а по ссылке
вида `/api/files/<коллекция>/<запись>/<имя>`; закрытым он становится, только если
поле помечено защищённым, и тогда нужен отдельный файловый токен. Замер —
[research/pocketbase.md](research/pocketbase.md).
- **Имя отправляемого документа** (`long-text-delivery`) собирается из
идентификатора задачи: имя, данное пользователем, в него не попадает.
@@ -126,6 +145,14 @@ Telegram отправителю.
Откуда он берётся — из группы OIDC или из конфигурации — не решено
(`admin-stats-screen`).
**Панель администратора в эту таблицу не входит и разграничению не подчиняется.**
Суперпользователь PocketBase видит все записи, все файлы и всех пользователей
мимо любого из четырёх механизмов, а пускает его свой пароль, а не Authelia.
Замер показал, что закрыть панель провайдером OIDC или вторым фактором нельзя:
обе настройки у коллекции суперпользователей отклоняются. Остаётся ограничение
по списку адресов (`superuserIPs`), и оно же запирает владельца, если список
задан неверно: сброса в наборе команд нет.
## Что чувствительнее чего
1. **Содержимое записей и расшифровок.** Голосовые сообщения — личная переписка;
@@ -153,6 +180,10 @@ Telegram отправителю.
5. **Статистика потребления** (`usage-accounting`). Текста записей не содержит,
но говорит, кто и когда пользовался сервисом и сколько; страница расхода
открыта только владельцу.
6. **Пароль суперпользователя панели** (`pocketbase-storage`). Открывает все
записи, все файлы и всех пользователей разом, то есть стоит вровень с самым
чувствительным из списка выше. Второй секрет после токенов пользователей,
который лежит **не в конфигурации**: его отпечаток хранит сама база.
Тексты расшифровок в логи не пишутся — логируется длина текста и
идентификаторы. **Имя файла, данное отправителем, пишется**: строка