Среда - это контекст: аудит безопасности для рабочих станций с AI-агентами
Мы тщательно проектируем промпты и инструменты, но почти не проверяем среду, в которой агент реально работает. Sentinel делает это измеримым.
Мы много говорим о промптах, инструментах и оценках. Но почти никто не аудирует среду, в которой AI-агент реально работает.
Агент видит ваши .env файлы. Ваши .mcp.json с токенами. Ваш settings.json с "permissions": "allow". Ваши плагины, хуки, конфиги. Всё это - операционный контекст, и он напрямую влияет на то, что агент может сделать. Если API-ключ лежит в plaintext - агент его прочитает. Если PreToolUse хук не настроен - любая Bash-команда выполнится без фильтрации. Если .claudeignore отсутствует - агент прочитает любой файл в проекте.
Это не гипотетические риски. Это конфигурация по умолчанию.
Поверхность атаки, которую никто не измеряет
Проведите мысленный аудит своей рабочей станции:
Секреты. Сколько .env файлов в ваших проектах? Они в .gitignore? Есть ли секреты в истории git? Когда вы запускаете Claude Code, shell уже содержит ANTHROPIC_API_KEY, AWS_SECRET_ACCESS_KEY, GITHUB_TOKEN - агент может выполнить printenv и увидеть всё.
MCP-серверы. Откройте .mcp.json. Токены прямо в JSON? Версии серверов не зафиксированы? Нет allowedTools для ограничения доступных инструментов? Каждый MCP-сервер - это child process, наследующий все переменные окружения.
Хуки. Есть ли PreToolUse хук, фильтрующий опасные Bash-команды? А для субагентов? Claude Code не наследует хуки родительского процесса в субагентах - это задокументированный баг, а не фича.
Доверие. Есть .claudeignore? Режим разрешений - default или acceptEdits? Сколько плагинов установлено и какие из них имеют hooks?
Каждый из этих вопросов бинарный: да или нет, безопасно или нет. Их можно проверить детерминированно, без LLM, без интерпретации.
Среда как контекст
В контекстной инженерии мы превращаем неявное в явное. Промпты, инструкции, инструменты - всё становится структурированным контекстом, который формирует поведение агента.
Но среда выполнения - это тоже контекст. Когда агент запускается в shell с direnv-загруженными секретами, он получает доступ к ним не потому что вы так спроектировали, а потому что никто это не проверил. Когда MCP-сервер запускается без allowedTools, агент получает доступ ко всем инструментам не потому что это нужно, а потому что это поведение по умолчанию.
Security posture рабочей станции - это implicit context. И пока он неявный, им нельзя управлять.
Sentinel: детерминированный аудит
Sentinel - плагин для Claude Code, запускающий 18 проверок в шести категориях:
| Категория | Проверок | Что ищет |
|---|---|---|
| secrets | 5 | Plaintext-ключи, .env без .gitignore, секреты в git history, runtime env vars, dotfiles |
| mcp | 3 | Токены в .mcp.json, отсутствие allowedTools, непинованные версии серверов |
| plugins | 3 | Дрифт реестра, утечка scope, непроверенные плагины |
| hooks | 2 | Отсутствие PreToolUse гарда, пробел в хуках субагентов |
| trust | 3 | Нет .claudeignore, широкие разрешения, поверхность для инъекций |
| config | 2 | Небезопасные значения по умолчанию, устаревшие сессии |
Каждая проверка - отдельный POSIX sh скрипт, выдающий JSON. Никакого LLM. Никакой эвристики. grep находит plaintext-токен в .mcp.json или не находит. stat проверяет права доступа: 600 или нет. Результат воспроизводим.
LOAD → VALIDATE → PLAN → RUN → NORMALIZE → ASSESS → PERSIST → RENDER
На выходе - JSON-отчёт и терминальный scorecard:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
sentinel audit - run_20260311T120000Z
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Category Score Checks
secrets 40/100 ██░░░░░░░░ 2/5 pass
mcp 67/100 ██████░░░░ 2/3 pass
plugins 100/100 ██████████ 3/3 pass
hooks 0/100 ░░░░░░░░░░ 0/2 pass
trust 60/100 ██████░░░░ 2/3 pass
config 50/100 █████░░░░░ 1/2 pass
Total: 47/100 Verdict: FAIL
Reliability: 1.00 (18/18 checks ran)
Два независимых показателя: score (0-100) - security posture, reliability (0.0-1.0) - сколько проверок реально выполнилось. Score 95 при reliability 0.4 не заслуживает доверия.
Что я обнаружил
Первый запуск sentinel на моей рабочей станции показал 47 из 100. Реальные находки:
- 8 plaintext
.envфайлов с API-ключами в 4 рабочих контекстах ANTHROPIC_API_KEY,OPENAI_API_KEYи ещё 12 секретов доступны черезprintenvв текущем shell- 3 MCP-сервера с токенами в
.mcp.json - Ни одного
PreToolUseхука - любая Bash-команда выполняется без фильтрации - Отсутствует
.claudeignoreв нескольких проектах
Ни одна из этих проблем не была случайностью. Это результат стандартной настройки: поставил Claude Code, добавил MCP-серверы, начал работать. Безопасность среды - не то, о чём думаешь при установке.
Remediation: не только находить, но и чинить
/sentinel-fix <run_id> проходит по каждому FAIL/WARN finding и показывает:
- Что - описание проблемы с redacted evidence
- Почему - объяснение риска
- Как - конкретная команда для исправления
Команды берутся из реестра проверок, не генерируются LLM. sentinel-fix никогда не выполняет команды автоматически, только предлагает. Risk badge для каждого действия: safe, caution, dangerous.
После исправления можно запустить /sentinel-diff для сравнения отчётов. Каждая находка имеет стабильный finding_id (SHA-256 от check_id|category|evidence_paths), что позволяет отслеживать: новые проблемы, решённые проблемы, изменения статуса.
Что это значит для контекстной инженерии
Мы тратим усилия на то, чтобы агент получил правильный системный промпт, правильные инструменты, правильную документацию. Но среда выполнения - это такой же контекст, только неуправляемый. Plaintext-секрет в .env - не проблема безопасности в вакууме. Это implicit context, определяющий, что агент может сделать, помимо того, что ему положено делать.
Security audit для AI-рабочей станции - не паранойя. Это та же практика, что и проверка зависимостей, линтинг, CI-пайплайн. Просто пока для нового класса рисков не было инструмента.
Установка
claude plugin add heurema/sentinel
Затем:
/sentinel # полный аудит
/sentinel --deep # аудит + объяснение рисков от LLM
/sentinel-fix <run_id> # пошаговое исправление
/sentinel-diff # сравнение с предыдущим аудитом