docs(#16): ADR-007 (web-сервер) и ADR-008 (безопасность)
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
# 007. Web-сервер: встроенный uvicorn, без nginx
|
||||
|
||||
- **Статус:** принято
|
||||
- **Контекст/issue:** #15, #31
|
||||
|
||||
## Контекст
|
||||
|
||||
UI — SPA, API — REST и WebSocket, всё в одном контейнере. Нагрузка: LAN, единичный пользователь.
|
||||
Установка должна быть в одну команду `docker run` без дополнительных контейнеров.
|
||||
|
||||
## Решение
|
||||
|
||||
Один uvicorn-процесс `awg-api` отдаёт и API, и собранную статику UI, и WebSocket. Сборка UI выполняется
|
||||
на этапе билда образа и попадает в `ui/dist`. Закладывается совместимость с внешним reverse-proxy:
|
||||
поддержка base-path и заголовков `X-Forwarded-*`, без обязательной настройки хоста.
|
||||
|
||||
## Альтернативы
|
||||
|
||||
- **nginx в образе** — плюс к размеру и к конфигу, преимуществ при такой нагрузке нет.
|
||||
- **Отдельный контейнер для UI** — нарушает требование единого образа.
|
||||
|
||||
## Последствия
|
||||
|
||||
- Заголовки кэширования статики и `index.html` настраиваются в FastAPI (иначе UI кэшируется после обновления).
|
||||
- WebSocket идёт через тот же порт: учитывается при настройке reverse-proxy в runbook (#45).
|
||||
- Docker HEALTHCHECK опирается на `/api/v1/health` того же процесса (#31).
|
||||
@@ -0,0 +1,31 @@
|
||||
# 008. Безопасность API/UI: токен, CSRF, rate limit, маскировка секретов
|
||||
|
||||
- **Статус:** принято
|
||||
- **Контекст/issue:** #15, #34
|
||||
|
||||
## Контекст
|
||||
|
||||
Приложение управляет VPN-туннелем и принимает приватные ключи AmneziaWG. Оно доступно из LAN,
|
||||
а в перспективе может быть выставлено через reverse-proxy. В ТЗ этот слой не описан, но без него
|
||||
загрузка `.conf` через веб-интерфейс превращается в дыру.
|
||||
|
||||
## Решение
|
||||
|
||||
- API — токен доступа в заголовке (Bearer), токен только в виде хеша в БД;
|
||||
- UI — сессия + CSRF-токен на мутирующие запросы;
|
||||
- приватные ключи (`PrivateKey`, `PresharedKey`) — `writeOnly` в OpenAPI, маска в UI и логах,
|
||||
файлы 0600 в отдельном каталоге;
|
||||
- rate limit и lockout на `/auth`, ограничение допустимых источников, bind по умолчанию на LAN;
|
||||
- audit log всех изменений конфигурации.
|
||||
|
||||
## Альтернативы
|
||||
|
||||
- **Без аутентификации, доступ только по LAN** — не защищает от заражённого устройства в сети и от
|
||||
ошибочной публикации порта.
|
||||
- **OIDC-провайдер** — не для локального однопользовательского приложения.
|
||||
|
||||
## Последствия
|
||||
|
||||
- Начальный токен генерируется при первом старте и выводится в лог один раз — это шаг в runbook (#45).
|
||||
- Маскировка секретов проверяется автотестами (#41) и security-прогоном (#44).
|
||||
- UI обязан корректно вести себя при 401 (переход на форму входа) — часть AC #35.
|
||||
Reference in New Issue
Block a user