Verdict / Администратору
Руководство администратора
Состав стенда, требования, развёртывание через install.sh, пользователи, журнал аудита, резервное копирование.
Verdict
Версия Next
Руководство системного администратора платформы Verdict
Назначение документа. Установка и сопровождение on-prem Verdict.
Аудитория. Системный администратор, разворачивающий и обслуживающий стенд.
Пользовательский интерфейс (сканирование, реестр, аналитика) описан в Руководстве пользователя. Здесь — только то, что нужно для развёртывания и администрирования.
Содержание
- Состав стенда
- Требования
- Развёртывание через install.sh
- Переменные окружения
- Первый вход и суперпользователь
- Лицензия
- Управление пользователями
- Журнал аудита
- Данные, тома и резервное копирование
- Диагностика
1. Состав стенда
Наружу опубликован один порт — сервис nginx поставки (по умолчанию ${PORT:-13000} → 80). Остальные контейнеры живут во внутренней сети compose и портов на хост не публикуют.
| Сервис | Назначение | Порт внутри сети |
|---|---|---|
| nginx | Единая точка входа: SPA + прокси на API | 80 (с хоста — PORT) |
| frontend | React SPA | 3000 |
| verdict | Django API, файлы результатов, админка | 13010 |
| verdict-db | PostgreSQL 16 | 5432 |
| acoustic-poisoner | Речевые / ASR-атаки | 13011 |
| modelscaner-fastapi | Сканер файлов модели (ModelScan) | 13012 |
| model-drift-attack | RAG Attack | 9009 |
| model-drift-defense | RAG Defense | 9010 |
| models | One-shot: наполняет volume весов drift (~16 ГБ) | — |
Веса drift в образы не запекаются. Сервис models при старте синхронизирует volume drift_models; attack и defense монтируют его как /models:ro.
Демо-макеты систем ИИ в клиентскую поставку не входят. Подключите их адресами отдельно развёрнутых сервисов: QDRANT_IP / QDRANT_PORT и при необходимости RAG_HOST.

Рисунок 1 — Схема стенда: nginx, SPA, Verdict, БД и sidecar-сервисы
2. Требования
- Linux x86_64, доступ в интернет (скрипт, registry, при необходимости Docker).
- curl, openssl (скрипт проверяет при старте).
- Docker 24+ и Docker Compose v2 (если нет — скрипт предложит поставить Docker через get.docker.com).
- Учётка в registry
registry.sdlplatform.ru(логин/пароль выдаёт поставщик). - Свободное место: рекомендуется не менее 40 ГБ на разделе Docker (
/var/lib/docker) — образmodelsтянет ~16 ГБ весов drift. - Открыт наружу один порт стенда
PORT(по умолчанию13000); при внешнем HTTPS-прокси — настройтеBEHIND_HTTPS_PROXYиCSRF_TRUSTED_ORIGINS(см. п. 4).
3. Развёртывание через install.sh
Основной способ поставки заказчику. Скрипт скачивает docker-compose.yml выбранной версии, создаёт .env, авторизуется в registry, делает pull / up -d, дожидается готовности UI и печатает пароль администратора.
3.1. Запуск
На чистом сервере (из каталога, рядом с которым появится папка verdict/):
curl -fsSL https://sdlplatform.ru/verdict/install.sh | bash
Альтернатива — скачать и запустить вручную:
curl -fsSL -o install.sh https://sdlplatform.ru/verdict/install.sh
chmod +x install.sh
bash install.sh
Каталог установки по умолчанию — ./verdict. Чтобы указать другой путь:
# скачанный скрипт
VERDICT_INSTALL_DIR=/opt/verdict bash install.sh
# через pipe - переменная должна быть у bash, не у curl
curl -fsSL https://sdlplatform.ru/verdict/install.sh | VERDICT_INSTALL_DIR=/opt/verdict bash
Повторный запуск при уже существующем verdict/.env с TAG= переходит в режим обновления (повторный запуск install.sh).
3.2. Вопросы установщика
Скрипт интерактивно спросит:
- Registry host — по умолчанию
registry.sdlplatform.ru. - Логин и пароль registry (
docker login). - Версию Verdict (например
2.0.2) — проверяется наличие образа…/verdict:<tag>(до 3 попыток). - IP/хост(ы) сервера через запятую — попадут в
DJANGO_ALLOWED_HOSTSи вCSRF_TRUSTED_ORIGINS(с портом и вариантомhttps://). - Внешний порт — по умолчанию
13000(PORTв.env).
Далее скрипт:
- скачивает
https://sdlplatform.ru/verdict/<TAG>/docker-compose.yml(если нет — fallback на…/docker-compose.yml); - генерирует
SECRET_KEY,DATABASE_PASSWORD, парольadmin; - пишет
verdict/.envс правами600и сохраняет копиюinstall.shрядом; - выполняет
docker compose --env-file .env pullиup -d(при сбое старта БД — повтор через 15 с); - ждёт ответа UI на
http://127.0.0.1:<PORT>/(до ~3 минут).
В конце выводит:
UI: http://<хост>:<PORT>
Вход: admin / <сгенерированный-пароль>
Пароль также лежит в verdict/.env (DJANGO_SUPERUSER_PASSWORD). Сохраните его в менеджере паролей.

Рисунок 2 — Диалог install.sh: registry, версия, хост и порт

Рисунок 3 — Успешное завершение установки: адрес UI и учётные данные admin
3.3. Проверка после установки
cd verdict # или $VERDICT_INSTALL_DIR
sudo docker compose --env-file .env ps
P=$(grep -E '^PORT=' .env | cut -d= -f2)
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:$P/ # SPA → 200/3xx
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:$P/api/v1/ # API
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:$P/admin/ # Django admin
sudo docker compose --env-file .env exec verdict \
curl -s -o /dev/null -w "%{http_code}\n" http://acoustic-poisoner:13011/
sudo docker compose --env-file .env exec verdict \
curl -s -o /dev/null -w "%{http_code}\n" http://modelscaner-fastapi:13012/
UI: http://<HOST>:<PORT>/. Легаси-страницы Django (/check_model/, /rag/ и т. п.) через nginx поставки не открываются.
3.4. Типовые правки сразу после установки
cd verdict
nano .env
# при внешнем HTTPS-прокси:
# BEHIND_HTTPS_PROXY=true
# CSRF_TRUSTED_ORIGINS=https://verdict.example.com,...
# RAG отдельно:
# QDRANT_IP=<хост-qdrant>
# QDRANT_PORT=6333
# RAG_HOST=http://...
sudo docker compose --env-file .env up -d
Не меняйте DATABASE_PASSWORD после первого успешного старта Postgres: пароль уже записан в том verdict_postgres_data. Смена без пересоздания тома ломает подключение Verdict к БД.
4. Переменные окружения
Клиентский .env создаёт install.sh в каталоге установки. Ключевые поля:
REGISTRY=registry.sdlplatform.ru/verdict/
TAG=<версия>
PORT=13000
SECRET_KEY=<сгенерирован>
DEBUG=False
DJANGO_ALLOWED_HOSTS=<хост>,localhost,127.0.0.1
CSRF_TRUSTED_ORIGINS=http://<хост>:13000,https://<хост>,...
BEHIND_HTTPS_PROXY=false
DATABASE_PASSWORD=<сгенерирован>
DJANGO_SUPERUSER_USERNAME=admin
DJANGO_SUPERUSER_EMAIL=admin@...
DJANGO_SUPERUSER_PASSWORD=<сгенерирован>
ADDRESS_HOST_PLATFORM=http://127.0.0.1:13010
ADDRESS_SCANER_PLATFORM=http://127.0.0.1:13010
ADDRESS_ACUSTIC_POISONER=http://acoustic-poisoner:13011
MODELSCAN=http://modelscaner-fastapi:13012/api/v1/modelscan/scan
ATK_HOST=http://model-drift-attack:9009
DEF_HOST=http://model-drift-defense:9010
RAG_HOST=
QDRANT_IP=
QDRANT_PORT=
| Переменная | Зачем |
|---|---|
PORT | Единственный порт стенда на хосте (nginx → SPA/API) |
REGISTRY / TAG | Префикс образов и версия поставки |
DJANGO_ALLOWED_HOSTS | Хосты HTTP Host (без порта) |
CSRF_TRUSTED_ORIGINS | Origin’ы с схемой и портом; при TLS — https://… |
BEHIND_HTTPS_PROXY | true, если снаружи HTTPS-терминатор |
DATABASE_PASSWORD | Только при первой инициализации тома Postgres |
DJANGO_SUPERUSER_* | Первый admin; после смены пароля в UI строку пароля удалите из .env |
ADDRESS_*_PLATFORM | Self-вызовы внутри контейнера (127.0.0.1:13010), не внешний IP |
HF_TOKEN | Частные / gated модели Hugging Face |
EXTERNAL_LLM_* | Внешняя LLM для RAG Attack на CPU (иначе OOM локальной модели) |
При обновлении install.sh дописывает в .env недостающие ключи из актуального списка и предупреждает о устаревших значениях (например ADDRESS_*_PLATFORM с внешним :13010 или CSRF на порт 13010).
5. Первый вход и суперпользователь
После install.sh суперпользователь уже создан контейнером (DJANGO_SUPERUSER_*):
- Откройте
http://<HOST>:<PORT>/. - Войдите: логин
admin, пароль из финального вывода скрипта (илиDJANGO_SUPERUSER_PASSWORDв.env). - Смените пароль в приложении, затем удалите строку
DJANGO_SUPERUSER_PASSWORDиз.env. - В сайдбаре должен быть пункт Настройки. Создайте рабочих пользователей (п. 7); пароль
adminоператорам не раздавайте.
Через SPA выдать тип «Суперпользователь» нельзя (403 superuser_creation_forbidden). Второй суперпользователь тоже блокируется.
Правила пароля: не менее 10 символов, не похож на логин и почту, не из словаря частых паролей, не чисто цифровой.

Рисунок 4 — Первый вход суперпользователя admin

Рисунок 5 — Сайдбар суперпользователя с разделом «Настройки»
6. Лицензия
Без действующей лицензии запуск сканирований отклоняется (HTTP 402): нет ключа, срок истёк или исчерпана квота домена.
Активировать может суперпользователь или администратор.
- Вставьте ключ-файл / ключ в модалку Активация лицензии (кнопка на информере в сайдбаре или на тосте отказа при запуске скана).
- Нажмите Активировать.
- При успехе — срок («до ДД.ММ.ГГГГ») и кнопка Готово.
В меню аккаунта видны срок и квоты MLSecOps / DataSecOps (использовано / лимит или «Без ограничений»). Предупреждение о скором истечении: за 30 дней (expiring) и за 14 дней (critical). Карточку предупреждения можно скрыть на 24 часа крестиком.
Неактивный ключ даёт ошибку «Используемый лицензионный ключ неактивен».

Рисунок 6 — Информер лицензии в сайдбаре

Рисунок 7 — Окно активации лицензии

Рисунок 8 — Подтверждение успешной активации лицензии

Рисунок 9 — Квоты доменов MLSecOps и DataSecOps в меню аккаунта
7. Управление пользователями
Раздел Настройки → Пользователи (/settings/users). Пункт меню виден только администраторам; ручки API не-админу отвечают 403 permission_denied.
7.1. Список
Вкладки Активные / Неактивные, поиск, сортировка по имени, логину, типу, дате создания, последнему входу. Колонки: имя, логин, тип, создан, последний вход.
Типы в интерфейсе: Суперпользователь, Администратор, Пользователь. Назначить через форму можно только Администратор и Пользователь.

Рисунок 10 — Список пользователей
7.2. Создание
Создать пользователя → имя, фамилия, логин (латиница, цифры, @ . + - _), email, тип, пароль и подтверждение → Сохранить.
Передайте сотруднику логин и пароль по защищённому каналу. Пароль можно скопировать из формы кнопкой копирования.

Рисунок 11 — Окно создания пользователя
7.3. Редактирование и пароль
В строке — Редактировать. Логин не меняется. Можно сменить ФИО, email, тип, активность и задать новый пароль.
Смена своего пароля через эту форму сбрасывает токен и выкидывает из сессии (401). Свою строку нельзя выделить для удаления, деактивации или смены типа (self_action_denied). Последнего суперпользователя понизить или удалить нельзя.

Рисунок 12 — Окно редактирования пользователя и смены пароля
8. Журнал аудита
Настройки → Аудит (/settings/audit). Только администратор. Источник — GET /api/v1/audit/logs/.
Колонки: дата и время, пользователь, тип действия, IP, текст события. Новые записи сверху. Поиск по журналу, сортировка, бесконечная прокрутка.
Фильтр (панель Настройка фильтра):
- период: всё время, 24 часа, 30 дней, 1 год или свой диапазон дат;
- тип действия.
Типы событий: вход, выход, неуспешная авторизация, изменение прав и групп, запуск сканирования, запуск проверки данных, создание / изменение / удаление пользователя, смена пароля, произвольное действие.

Рисунок 13 — Журнал аудита
9. Данные, тома и резервное копирование
Тома compose:
| Том | Содержимое |
|---|---|
verdict_postgres_data | PostgreSQL |
verdict_mydatabase | Служебные данные Verdict |
verdict_media | Медиа и вложения |
verdict_files | Загруженные модели и файлы сканов |
verdict_logs | Логи |
drift_models | Веса RAG attack/defense |
docker compose down тома не удаляет. docker compose down -v — полный сброс данных.
Рекомендуемый бэкап (клиентская установка в каталоге verdict/):
cd verdict
# PostgreSQL
sudo docker compose --env-file .env exec -T verdict-db \
pg_dump -U verdict verdict > verdict-$(date +%F).sql
# копия .env (секреты!) и при необходимости архив Docker volumes
cp -p .env .env.bak.$(date +%F)
# тома файлов - архив каталога volumes хоста (путь зависит от Docker)
Перед обновлением версии сделайте дамп БД и копию verdict_media / verdict_files.
10. Диагностика
| Симптом | Что проверить |
|---|---|
| SPA не открывается | cd verdict && sudo docker compose --env-file .env ps, порт PORT, логи nginx; нет ли хостового nginx на том же порту |
| Логин / POST: CSRF Origin checking failed | DJANGO_ALLOWED_HOSTS = IP/DNS без порта; CSRF_TRUSTED_ORIGINS включает http(s)://хост:PORT; при TLS — BEHIND_HTTPS_PROXY=true |
502 / 504 на /api/ | контейнер verdict жив, логи verdict; не путайте внешний PORT с внутренним 13010 |
| 413 на загрузке модели | client_max_body_size у nginx поставки (в актуальном compose обычно 0) |
| Сидкар «не отвечает» | из контейнера verdict: curl на acoustic-poisoner:13011, modelscaner-fastapi:13012, model-drift-attack:9009, model-drift-defense:9010 |
| RAG не стартует / пустая коллекция | Qdrant развёрнут отдельно; QDRANT_IP / порт; RAG_HOST при необходимости |
| ModelScan / provenance timeout | сеть до PyPI / GitHub; PROVENANCEKIT_STRICT=0; кэш весов |
install.sh: образ не найден | логин в registry; верный TAG; доступ к registry.sdlplatform.ru |
| Мало места при pull | ≥ 40 ГБ свободно; сервис models ~16 ГБ |
| Неверный пароль admin | пароль из вывода установки / .env; после смены в UI строка DJANGO_SUPERUSER_PASSWORD уже не действует |
| Нет пункта «Настройки» | обычный пользователь; is_admin в GET /api/v1/me/ |
| 403 на пользователях / аудите | роль не администратор |
| Лицензия отклоняет скан | ключ, срок, квота домена |
