Initial commit: omnichannel-mcp — MCP-сервер управления платформой Omnichannel
ci / test (push) Successful in 2m22s
ci / lint (push) Successful in 4m31s

This commit is contained in:
Maksim Totmin
2026-10-07 20:13:23 +07:00
commit fdbd4a4fb6
54 changed files with 5672 additions and 0 deletions
+91
View File
@@ -0,0 +1,91 @@
# Безопасность
`omnichannel-mcp` даёт ассистенту право управлять платформой, поэтому
безопасность строится в несколько независимых слоёв: конфигурация модуля,
подтверждения, и ограничения на стороне `config_server`.
## Модель угроз
- **Ошибочный или злонамеренный вызов управляющего инструмента** (остановить
прод, залить чужой конфиг).
- **Утечка секретов** (пароли, токен GitLab) в логи, в контекст модели, в
репозиторий.
- **Доступ не туда** (SSRF, подмена хоста стенда).
- **Чрезмерные привилегии** (учётная запись только для чтения там, где нужен
мониторинг).
## Слои защиты
### 1. Учётные данные и секреты
- Пароли и токены — только из `${VAR}` окружения или `config.local.json`
(в `.gitignore`). В репозитории — лишь шаблон.
- `--check-config` печатает конфиг с маской секретов — можно безопасно проверять
настройку и выкладывать вывод в тикеты.
- Секреты не логируются: логи идут в stderr с маскированием, токен GitLab в
выводе не отражается.
### 2. Режим «только чтение»
- `read_only: true` (значение по умолчанию) запрещает все изменяющие инструменты.
- Для наблюдательных агентов поднимайте **отдельный инстанс** с `read_only: true`
и отдельной read-only учётной записью:
```json
{ "servers": [{ "alias": "prod", "base_url": "http://…",
"readonly_username": "${OMNI_RO_USER}",
"readonly_password": "${OMNI_RO_PASSWORD}" }],
"read_only": true }
```
- Если заданы `readonly_*`-креды, read-инструменты ходят именно под ними —
это least-privilege на стороне модуля.
### 3. Подтверждения (`confirm`)
Разрушительные операции требуют `confirm="true"`:
- `down`, `restore_compose`, `restore_env_version`, `update_front`,
`download_release`, `cleanup_old_versions`.
Это второй слой: даже при включённом `read_only=false` ассистент обязан явно
подтвердить опасное действие. Дополнительно настройте политику подтверждений
вашего MCP-клиента (человеческое «да/нет» на управляющие инструменты).
### 4. Изоляция сети (`allow_hosts`)
Если задан `allow_hosts`, `base_url` любого сервера обязан быть на этих хостах —
защита от опечаток и подмены адреса.
### 5. Файловый jail (`front_roots`)
`update_front` принимает только каталоги внутри `front_roots`; при проверке
разрешаются симлинки и отсекаются побеги (`..`, ссылки наружу). Пусто —
загрузка фронта запрещена полностью.
### 6. Ограничение нагрузки
- Таймауты (`timeout_sec`, `upload_timeout_sec`), лимиты вывода
(`max_output_bytes`) и размера загрузки (`max_upload_bytes`).
- Семафор мутаций (`max_concurrent_mutations`) предотвращает наложение операций.
- GET-запросы повторяются при сетевом сбое; **мутации не повторяются** — действие
не выполнится дважды.
## Что модуль НЕ делает
- Не работает с агентскими эндпоинтами `config_server`
(`/api/register`, `/api/tasks/<host>`) — только с пользовательским API.
- Не хранит состояние и не пишет секреты на диск.
- Не выполняет код на хостах: все действия выполняет агент `config_server`.
## Рекомендации оператору
1. Заведите **отдельные учётные записи**: read-only для мониторинга,
полную — только для деплой-агента.
2. Для мониторинга запускайте инстанс с `read_only: true`.
3. Держите секреты в окружении/`config.local.json`, не в `config.json`.
4. Включите подтверждения управляющих инструментов в MCP-клиенте.
5. Ограничьте сетевой доступ к `config_server` (VPN/private network); наружу
порт 5005 не публикуйте.
6. Об уязвимостях сообщайте в службу безопасности компании (не публикуйте в
общих трекерах).