Документация

К списку статей
21. Вход, роли и режимы (DEMO_MODE): как работает аутентификация

Аудитория: суперадминистратор, интегратор, администратор стенда. Закрывает вопрос: «как устроен вход, почему список арендаторов бывает пустым, что такое DEMO_MODE, сколько живёт сессия и как отозвать доступ?». Связано: 07 — Роли и RBAC, 05 — Автономность и стек.


Как устроен вход
  • Эндпоинт: POST /api/auth/login с телом { "tenant", "login", "password" }.
  • Формат логина — `роль@арендатор` (например, it_manager@artek).
  • Пароль проверяется Argon2id (в БД — только хэш; Стрибог тут не применяется — он обезличивает

табельные, а не пароли).

  • При успехе сервер возвращает JWT и, в cookie-режиме, ставит httpOnly-cookie lz_token

(Secure, SameSite=Strict) + читаемую lz_csrf для double-submit. Срок — 8 часов.

Два транспорта токена
ТранспортКогдаCSRF
Cookie (AUTH_COOKIE_MODE=1, прод)вход из браузера, same-origin через nginxwrite-запрос обязан нести X-CSRF-Token = cookie lz_csrf
Bearer (Authorization: Bearer …)интеграции/скрипты (форвардер сбора)не требуется (браузер не ставит заголовок автоматически)

Режимы доступа
ПеременнаяЗначениеЭффект
DEMO_MODE1без токена — анонимный read-only просмотр публичного арендатора demo; список арендаторов (/api/tenants) открыт
DEMO_MODE0 (прод)без валидного токена — 401, анонимного доступа нет
DEV_AUTH0 (прод)dev-эндпоинт POST /api/auth/token (минт токена без пароля) выключен (404)
AUTH_COOKIE_MODE1 (прод)токен в httpOnly-cookie + CSRF
⚠️ Грабля: пустой список арендаторов на проде и как не остаться без входа

В проде (DEMO_MODE=0) /api/tenants требует токен → до входа анонимный вызов возвращает 401, и выпадающий список арендаторов на странице входа оказывается пустым.

Как это решено в продукте: форма входа при недоступном списке показывает поле ручного ввода идентификатора арендатора — введите его вручную (например, artek) и входите по логину/ паролю. (Дополнительно можно вынести публичный список арендаторов — пункт дорожной карты.)


Роли (RBAC) — кто что видит
РольНазначениеДоступ к разделам
viewerнаблюдательДашборд, Реестр, Эффективность, Риски, FinOps, Каталog (чтение)
it_managerзаявки, FinOps+ подача/работа с заявками
it_adminэксплуатация+ Оборудование, Жизненный цикл, Провижининг, Коллекторы, Отчёт
dpoПДн+ Журнал ФЗ-152, Сейф (раскрытие), Отчёт
superadminвсёвсе разделы + Настройки (обходит ролевые проверки)
collectorприём телеметриитолько POST /ingest/* (служебная, для форвардера)

Меню скрывает разделы по роли: например, «Отчёт», «Оборудование», «Сейф», «Настройки» наблюдатель (viewer) не видит — это не баг, а разграничение прав (см. ст. 07).


Сессия, выход и отзыв доступа
  • Срок токена — 8 ч, авто-обновления (refresh) нет → по истечении нужен повторный вход.
  • Выход (POST /api/auth/logout) очищает cookie в браузере. Важно: сам JWT остаётся

криптографически валидным до истечения `exp` — серверного «чёрного списка» нет.

  • Немедленно отозвать ВСЕ сессии можно сменой JWT_SECRET (все ранее выданные токены сразу

становятся недействительными — разлогинит всех; делать при инциденте).


Прод-гарды и секреты
  • При APP_ENV=prod старт падает (fail-fast), если JWT_SECRET / ANON_SALT / пароль БД

равны слабым/демо-значениям (см. settings.py).

  • Вход защищён rate-limit (RATELIMIT_ENABLED=1): частые попытки → 429.
  • Демо-пароль `licenziar` одинаков у всех демо-учёток — на боевом контуре сменить и завести

реальные учётные записи (см. управление пользователями в Настройках, роль superadmin).


Чек-лист боевого входа
  1. APP_ENV=prod, заданы сильные JWT_SECRET/ANON_SALT/пароли БД.
  2. DEMO_MODE=0, DEV_AUTH=0, AUTH_COOKIE_MODE=1.
  3. Заведены операторы с реальными паролями (не licenziar).
  4. Проверить вход: арендатор (из списка или ручным вводом) + роль@арендатор + пароль → попадаете

в свой контур; чужой арендатор по вашему токену недоступен (RLS).


Связанные: 07 — Роли и RBAC · 22 — Сводный отчёт и период · 02 — ПДн и Сейф.