Админ-панель
Единственная аутентифицированная поверхность — вход, назначение экранов, что попадает в аудит.
Всё в публичном API — только на чтение. Редактирование каталога происходит на /admin, за логином.
Вход
Один аккаунт, настроенный через окружение:
| Настройка | Что |
|---|---|
ADMIN_USERNAME |
логин |
ADMIN_PASSWORD_HASH_FILE |
путь к файлу с argon2id-хешем, никогда не паролем |
ADMIN_SECRET_KEY_FILE |
путь к файлу с ключом подписи сессионной куки |
(ADMIN_PASSWORD_HASH и ADMIN_SECRET_KEY тоже работают как прямые значения — так
удобно локально. В проде нужна форма *_FILE, см. предупреждение ниже.)
Сгенерируйте хеш на машине, которая его будет держать:
python -m app.cli hash-password
# Password: ········
# $argon2id$v=19$m=65536,t=3,p=4$...
Никогда не кладите хеш в compose-
.env
docker compose раскрывает $ в том же env_file, который использует для
собственной подстановки переменных. Argon2-хеш полон $, так что $argon2id$v=19$m=65536,…,
записанный в .env, доезжает в контейнер как =19=65536,…. Панель стартует,
считает себя настроенной и отклоняет правильный пароль с 401 — и нигде нет
ошибки, которая бы это объяснила. Монтируйте оба значения файлами; прод-compose уже так делает.
Пароль в открытом виде нигде не пишется — ни в .env, ни в docker inspect, ни в лог деплоя. Утечка окружения даёт хеш для брутфорса, а не рабочий кред.
Прод не стартует без этого
С APP_ENV=production и включённой админкой отсутствующий ADMIN_SECRET_KEY или ADMIN_PASSWORD_HASH — ошибка старта. Пустой ключ подписи делал бы каждую сессионную куку подделываемой, и упасть громко на буте лучше, чем это обслуживать.
Сессии — подписанные куки, HttpOnly, SameSite=Lax, Secure в проде, действительны 12 часов. Неудачные попытки входа троттлятся по IP клиента (10 попыток / 5 минут). Смена ADMIN_USERNAME инвалидирует все существующие сессии.
Экраны
Overview — счётчики каталога и таблица покрытия по провайдерам. Важные колонки: explicit (закреплено), derived (ответ дала лестница фолбэка) и unsupported, посчитанные только по активным региональным языкам, потому что базовым маппинг не нужен. Счётчик derived — это ваша очередь работы.
Providers — та же таблица плюс настройки провайдера: название, категория, политика фолбэка, алиасы и инструмент copy mappings для подключения новых.
Matrix — главный экран. См. Editing the Matrix.
Languages — поиск по названиям, кодам и алиасам; редактирование языка; добавление и удаление алиасов; создание нового. Страница языка также показывает, что каждый провайдер получит для него, с возможностью править по строке.
Tools — живой тестер резолвинга, выполняющий ровно тот же код, что и /v1/resolve, и JSON-экспорт всего каталога в формате сид-файлов.
Audit — каждая запись, только добавление, новейшие сверху.
Что попадает в аудит
Каждая мутация фиксирует актора, действие, сущность, её ключ и снимок before/after. Актор — логин админа плюс IP клиента: в панели один аккаунт, так что именно IP отличает двух людей, ею пользующихся.
Строки аудита приложение никогда не редактирует и не удаляет.
Если панель недоступна
| Симптом | Причина |
|---|---|
503 admin_unavailable |
пустой ADMIN_PASSWORD_HASH или ADMIN_SECRET_KEY |
| «Session expired» на каждый сабмит | заблокированы куки, или ADMIN_COOKIE_SECURE=true при работе по HTTP |
429 |
троттлинг входа — переждите 5-минутное окно |
ADMIN_ENABLED=false убирает панель полностью; публичный API это не затрагивает.
Далее
- Editing the Matrix — экран, в котором вы проведёте время
- Закрепить код провайдера