Files
ipam_control/docs/changes/017-jwt-secret-validation/PLAN.md
T

25 lines
2.7 KiB
Markdown
Raw Normal View History

# Проверка секретов при старте (изменение 017)
Находка ревью № 7, серьёзность — средняя.
## Context
`Settings.jwt_secret = "dev-only-secret"` (`app/config.py`). При запуске без `JWT_SECRET` (локально, другое развёртывание) токены подписываются
общеизвестным ключом — их можно подделать для любого логина. В compose пустое значение даёт 500 при входе (PyJWT отвергает пустой ключ) — ошибка всплывает поздно.
Аналогично: при пустой БД и пустом `ADMIN_PASSWORD` администратор молча не создаётся.
## Решение
1. `app/config.py`: `jwt_secret: str` без значения по умолчанию; валидатор — не короче 32 символов и не из списка известных заглушек (`change-me`, `dev-only-secret`, `secret`).
Ошибка — при импорте настроек, т.е. при старте: контейнер падает с понятным сообщением «JWT_SECRET не задан или слишком короткий (python scripts/gen_env.py)».
2. `app/main.py` `seed()`: пустая таблица `users` и пустой `ADMIN_PASSWORD` → `logging.warning` с инструкцией (не падение: БД может заполняться иначе);
`ADMIN_PASSWORD` короче 8 символов → отказ старта (иначе создаётся пароль слабее, чем разрешает UI).
3. `.env.example`: пометка, что `JWT_SECRET` ≥ 32 символов; `scripts/gen_env.py` уже генерирует 64 символа — без изменений.
4. `alembic/env.py` импортирует `settings` — проверить, что миграции не требуют `JWT_SECRET` (при необходимости вынести `database_url` в отдельный доступ).
## Файлы
`app/config.py`, `app/main.py`, `alembic/env.py` (при необходимости), `.env.example`, `README.md` (Быстрый старт).
## Тест
Юнит-тест без БД: `Settings(jwt_secret="short")` → `ValidationError`; `Settings(jwt_secret="x"*32)` — успешно.
## Проверка
Пересборка стенда с текущим `.env` — старт успешен; запуск контейнера с `JWT_SECRET=` → контейнер завершается с сообщением в логах; `alembic upgrade head` работает.