документы: сведены расхождения, найденные сверкой канона

- один факт — один дом: рецепт локального входа, правило чтения
  X-Forwarded-For, уровень строки журнала и опись опор изъятия сведены к
  своим домам, копии заменены ссылками
- форма [auth.test_headers] выровнена по образцу конфига в семи местах;
  сценарии intake и archive перестали ссылаться на сессию, которой сервис
  не выдаёт
- поправлены протухшие факты: ключ объекта строит ULID, а не UUID; сверку
  адреса пира зовут трое, а не двое; обзор capability access знает о
  задаче 2026-08-23
This commit is contained in:
av
2026-08-23 16:41:06 +03:00
parent 11269c1567
commit 31ce520c5b
12 changed files with 65 additions and 66 deletions
+14 -15
View File
@@ -81,12 +81,10 @@
«Предохранитель отладки включает только подстановку заголовков»; снимать их
поодиночке нельзя: барьер держится всеми разом.
Держится изъятие **умолчанием, а не машиной**: предохранитель по умолчанию
выключен, а заполненная имитация без него роняет старт. Боевой перечень
доверенных адресов включению предохранителя не мешает — сервис, поднятый в бою с
включённым предохранителем и заполненной имитацией, назовёт своим именем всякого,
чей запрос пришёл через обратный прокси, то есть всякого, кто пришёл обычным
путём.
Держится изъятие умолчанием предохранителя «выключено» и отказом старта при
заполненной имитации без него. Что остаётся между боевой выкладкой и открытым
входом целиком, включая опору вне репозитория, перечисляет модель угроз —
`docs/security.md`, «Периметр».
#### Scenario: Названный провайдером получает доступ
@@ -275,14 +273,15 @@ MUST отвечать отказом `401`, когда пришедший не
**Изъятие одно — отладочный запуск.** При включённом предохранителе
`[server] debug` заголовок входа ставит не прокси, а сам сервис значением из
секции `[auth] test_headers`; узнавание при этом остаётся тем же и подставленного
секции `[auth.test_headers]`; узнавание при этом остаётся тем же и подставленного
заголовка от пришедшего не отличает. Условия, при которых источник этот законен,
и проверки старта, которыми он держится, стоят требованиями «Отладочный запуск
называет пришедшего настройками», «Настройка, открывающая вход всем, роняет
старт», «Отладочный запуск виден в журнале» и «Предохранитель отладки включает
только подстановку заголовков». Держится изъятие умолчанием предохранителя
«выключено» и отказом старта при заполненной имитации без него; боевой перечень
доверенных адресов включению предохранителя не мешает.
и проверки старта, которыми он держится, перечислены требованием «Кого пускать,
решает провайдер».
Держится изъятие умолчанием предохранителя «выключено» и отказом старта при
заполненной имитации без него. Что остаётся между боевой выкладкой и открытым
входом целиком, включая опору вне репозитория, перечисляет модель угроз —
`docs/security.md`, «Периметр».
Заголовку сервис MUST верить только тогда, когда запрос пришёл с адреса из
объявленного перечня доверенных, и адрес этот MUST браться у самого соединения,
@@ -591,7 +590,7 @@ MUST не выдавать вовсе — ни куки, ни токена се
### Requirement: Отладочный запуск называет пришедшего настройками
Сервис SHALL подставлять запросу заголовки входа значениями из секции
`[auth] test_headers`, когда включён предохранитель `[server] debug`, и MUST
`[auth.test_headers]`, когда включён предохранитель `[server] debug`, и MUST
делать это так, чтобы узнавание не отличало подставленный заголовок от
поставленного обратным прокси. Ветка кода, которой узнаётся пришедший, обязана
быть той же, что работает в бою: отладке подлежит боевой путь, а не его
@@ -685,7 +684,7 @@ MUST не выдавать вовсе — ни куки, ни токена се
Умолчания названы нормой, а не образцом конфига. Отсутствие ключа `[server]
debug` MUST читаться как выключенный предохранитель, а отсутствие секции
`[auth] test_headers` — как пустая секция: конфиг сегодняшнего дня, не тронутый
`[auth.test_headers]` — как пустая секция: конфиг сегодняшнего дня, не тронутый
ни на байт, обязан вести себя ровно как вёл. Ошибка разбора значения MUST
кончаться отказом старта, а не прочтением «включено».
+1 -1
View File
@@ -265,7 +265,7 @@ MUST называть в нём потолок размера одной зап
#### Scenario: Потолок размера равен тому, которым сервис отвергает
- **GIVEN** человек вошёл и предъявил сессию
- **GIVEN** человек узнан
- **WHEN** он спрашивает пределы сервиса
- **THEN** потолок размера в ответе равен потолку, которым сервис ограничивает
тело запроса приёма
+3 -3
View File
@@ -302,19 +302,19 @@ MUST ограничивать его длину и MUST убирать из не
#### Scenario: Имя доходит до записи
- **GIVEN** отправитель предъявил сессию
- **GIVEN** отправитель узнан
- **WHEN** он шлёт запись с именем `разговор.mp3`
- **THEN** колонка имени файла у заведённой записи несёт `разговор.mp3`
#### Scenario: Заголовок принятой записи пуст
- **GIVEN** отправитель предъявил сессию
- **GIVEN** отправитель узнан
- **WHEN** он шлёт запись с именем `разговор.mp3`
- **THEN** колонка заголовка у заведённой записи пуста
#### Scenario: Длинное и грязное имя приходит обрезанным и очищенным
- **GIVEN** отправитель предъявил сессию
- **GIVEN** отправитель узнан
- **WHEN** он шлёт запись, чьё имя длиннее предела и несёт управляющие знаки
- **THEN** колонка имени файла несёт имя не длиннее предела
- **AND** управляющих знаков в нём нет