Политика инструментов AI-агентов: безопасность, MCP-серверы и секреты в self-hosted среде
Политика инструментов AI-агентов: безопасность, MCP-серверы и секреты в self-hosted среде
Когда в системе три AI-агента (Hermes, Codex, Claude Code), каждый со своим набором инструментов, вопрос безопасности перестаёт быть академическим. Он становится ежедневным: какой инструмент кому доступен, кто может читать логи, кто имеет право перезапускать сервисы, и где вообще лежат секреты, чтобы ни один агент случайно не вывалил API-ключ в ответ пользователю.
За несколько месяцев эксплуатации multi-agent системы на своём сервере я выработал набор правил, которые держат стек безопасным, не превращая его в бесполезную песочницу. Ниже — практическая политика инструментов: от секретов до MCP-серверов и бриджа между агентами.
Почему «просто не храни секреты в репозитории» недостаточно
Классический совет — «используй .env и не коммить секреты». Для AI-агентов этого мало. Проблема в том, что агент может прочитать секрет из файла, переменной окружения или лога и передать его дальше — в ответе пользователю, в сгенерированном коде, в заметке Obsidian или в отладочном выводе.
В моём vault действует жёсткое правило: никаких секретов в Markdown-заметках. Ни API-ключей, ни токенов Telegram, ни OAuth-кодов, ни SSH-приватных ключей, ни кук, ни сессионных файлов. Vault синхронизируется между агентами, читается инструментами поиска, индексируется — если туда попадёт секрет, его увидят все.
Что делать вместо этого:
- Секреты живут в отдельных файлах за пределами vault. В моём случае это
/opt/data/.secrets/с ограниченными правами (0600) и владельцем, отличным от UID контейнеров агентов. - Переменные окружения передаются через Docker Compose. Каждый контейнер получает только те переменные, которые нужны именно ему. Hermes не видит GitHub-токен Codex, и наоборот.
- Проверка vault на секреты — часть регулярного аудита. Команда
bronevik-vault-statusсреди прочего проверяет, что в vault нет путей, похожих на секреты. Если находит — алерт.
Это базовый слой. Без него всё остальное не имеет смысла.
MCP-серверы: принцип наименьших привилегий
Model Context Protocol позволяет агенту взаимодействовать с внешними системами через инструменты. Но каждый MCP-сервер — это поверхность атаки. Подключить «широкий» сервер, который отдаёт агенту всю файловую систему, git с правами на reset и force-push, или shell с bash -c — значит свести безопасность к надежде на то, что модель не ошибётся.
Правила, которые я применяю:
1. tools.include вместо широкого доступа
В конфигурации Hermes каждый MCP-сервер настраивается не через «включить все инструменты», а через явный allowlist:
mcp_servers:
bronevik-knowledge:
command: "..."
tools:
include:
- fs_read_text_file
- fs_search_files
- fs_list_directory
- fs_directory_tree
Агент видит ровно те инструменты, которые перечислены — не больше. Если нужен новый инструмент, он добавляется явно, с осознанным решением.
2. Разделение прав на чтение и запись
Obsidian vault и рабочие директории агентов — это разные зоны доверия:
- Vault (
/workspace/bronevik-knowledge): read-write для добавления знаний, но безmove_fileи без выхода за пределы vault. - Workspace (
/workspace/agent-workbench): read-write для временных файлов и сборки, но без доступа к секретам. - Хост (через maintenance bridge): строго ограниченный набор именованных действий.
Это не три отдельных MCP-сервера, а три разных политики доступа в рамках одной архитектуры.
3. По одному внешнему сервису за раз
Подключение Google Drive, базы данных, внешнего SaaS — каждое новое подключение добавляется отдельным MCP-сервером, с собственным токеном и только теми инструментами, которые реально нужны. Никаких «подключу всё сразу, потом разберусь». После каждого изменения — перезапуск Hermes, hermes mcp test, проверка списка инструментов и триггер бэкапа.
Agent Bridge: безопасная делегация между агентами
В моём стеке Hermes оркестрирует задачи, а Codex и Claude Code выполняют инженерную работу — правят код, чинят конфиги, анализируют логи. Коммуникация между ними идёт не через прямой shell, а через agent bridge — промежуточный слой с жёстко ограниченным набором действий.
Почему не прямой claude mcp serve или codex mcp-server? Потому что они отдают shell и запись файлов без контекстных ограничений. Агент может случайно или по неверной инструкции сделать то, что не должен.
Agent bridge работает в двух режимах:
- Audit bridge — read-only инструменты для инспекции: просмотр статуса, чтение логов, проверка бэкапов. Агент видит, но не трогает.
- Maintenance bridge — scoped-действия через allowlist: перезапуск конкретных сервисов, запуск бэкапа, перезагрузка Docker-контейнера. Не
systemctl restart *, а «можно рестартитьhermes-agent.serviceиttyd-codex-fast.service, и всё».
Ключевое правило: контекстные пути — только внутри /workspace. Никаких /etc, /root, /home или путей с секретами. Если агенту нужно прочитать конфиг сервиса, этот конфиг должен быть доступен в разрешённом пути или скопирован туда явно.
Web Shells: операторский доступ, не инструмент агента
Отдельная тема — ttyd web-терминалы для Codex и Claude Code. Это операторские поверхности для меня, человека, а не инструменты для Hermes.
Правила:
- Работают только
ttyd-codex-fast.serviceиttyd-claude-fast.service. - Оба слушают исключительно
127.0.0.1— никаких открытых портов в сеть. - Публичный доступ идёт через Cloudflare Tunnel + Cloudflare Access с аутентификацией.
- Hermes не имеет автоматического доступа к этим терминалам. Если Hermes нужно что-то передать Codex, это идёт через agent bridge, а не через программное управление web-шеллом.
Типичная ошибка — дать оркестратору возможность открывать shell в контейнере агента и печатать команды. Это стирает границу между оркестрацией и исполнением и создаёт риск неконтролируемой эскалации.
Мониторинг здоровья: проверка политики на практике
Политика инструментов бесполезна, если её нельзя проверить автоматически. У меня для этого есть bronevik-vault-status — скрипт, который проверяет:
- Чистоту vault:
git_dirty_count=0— все изменения закоммичены. - Целостность структуры: все обязательные заметки на месте,
.obsidianконфигурация присутствует. - Отсутствие битых wikilink’ов — если агент сослался на несуществующую заметку, это видно сразу.
- Отсутствие секретоподобных путей — если кто-то случайно сохранил ключ или токен в Markdown.
- Все файлы имеют frontmatter (кроме README), чтобы навигация и индексация работали предсказуемо.
Если overall=ok — система в порядке. Если нет — сначала чиним, потом работаем дальше.
Кроме vault, стоит проверять и конфигурацию инструментов. После любых изменений в MCP-серверах или agent bridge: рестарт Hermes → hermes mcp test → проверка hermes tools list — убедиться, что список инструментов соответствует политике, и никакие лишние не просочились.
Контроль версий и воспроизводимость
Безопасность инструментов — это ещё и воспроизводимость. Если агент обновился, список инструментов изменился, появилось новое поведение — нужно иметь возможность откатиться.
В моём стеке образы Docker закреплены на конкретных дайджестах:
nousresearch/hermes-agent@sha256:c6637f...— не:latest.ghcr.io/outsourc-e/hermes-workspace@sha256:2d2ba...— не плавающий тег.bronevik/agent-tools:2026-06-07— датированный тег, не:latest.
Версии CLI в agent-tools тоже зафиксированы: Codex CLI 0.137.0, Claude Code 2.1.167. Никаких автообновлений без ручного триггера и последующей проверки инструментов.
Что в итоге
Политика инструментов AI-агентов — это не разовая настройка, а непрерывная практика:
- Секреты живут отдельно от знаний. Vault и workspace не должны содержать ключей, токенов или приватных файлов.
- MCP-серверы настраиваются через allowlist. Каждый инструмент добавляется явно, с пониманием зачем.
- Agent bridge — узкий и проверяемый. Именованные действия вместо generic shell.
- Web-шеллы — только для человека. Агенты общаются через bridge, не через терминал.
- Регулярный аудит.
bronevik-vault-statusи проверка списка инструментов после изменений. - Закреплённые версии. Дайджесты и датированные теги вместо плавающих
latest.
Самое важное правило я сформулировал для себя так: если агент может что-то сломать случайно — он это когда-нибудь сломает. Задача политики инструментов не в том, чтобы запретить всё, а в том, чтобы случайная ошибка не превращалась в инцидент. Ограниченный набор проверенных инструментов, явные границы доступа и автоматическая проверка здоровья — этого достаточно, чтобы спать спокойно.
📬 Не пропускай новые статьи
Подпишись на Telegram-канал или RSS, чтобы получать уведомления о новых материалах