Claude Code в проде может утечь в Slack, WordPress и .env: 10 базовых guardrails, которые нужно включить до первого запуска
Я — Denis Shokhirev, Agentic AI Systems Architect из Freiburg im Breisgau, Germany, и в DennisCraft AI Studio я запускаю production AI-системы для DACH B2B на Claude, Supabase, n8n, Doppler и self-hosted Postgres. Самый неприятный инцидент в таких системах обычно не выглядит как “взлом”: агент просто читает не тот файл, публикует не тот текст в WordPress или отправляет в Slack фрагмент из .env, потому что никто не задал ему границы до первого запуска. Когда Claude Code получает доступ к репозит
Я — Denis Shokhirev, Agentic AI Systems Architect из Freiburg im Breisgau, Germany, и в DennisCraft AI Studio я запускаю production AI-системы для DACH B2B на Claude, Supabase, n8n, Doppler и self-hosted Postgres. Самый неприятный инцидент в таких системах обычно не выглядит как “взлом”: агент просто читает не тот файл, публикует не тот текст в WordPress или отправляет в Slack фрагмент из .env, потому что никто не задал ему границы до первого запуска.
Когда Claude Code получает доступ к репозиторию, shell, CMS, базе и мессенджеру, утечка становится не теоретическим риском, а вопросом маршрута данных. OWASP в 2025 году отдельно выделяет sensitive information disclosure и excessive agency в списке рисков для LLM-приложений: https://genai.owasp.org/llm-top-10/. Ниже — 10 guardrails, которые я ставлю до первого production run, если агент может писать код, запускать команды и публиковать результат наружу.
1. Сначала урежьте область видимости, потом давайте инструменты
Первая ошибка — дать Claude Code доступ ко всему workspace и надеяться на prompt discipline. Я делаю наоборот: отдельный рабочий каталог, отдельный service account, отдельные credentials под конкретную задачу. Если агент генерирует changelog, ему не нужен доступ к billing, HR-документам и корневому .env.
Guardrail 1: отдельный workspace
Запускайте агент только в выделенном каталоге или контейнере. Не монтируйте home directory, SSH-ключи и общие volumes. Особенно если рядом есть WordPress themes, backup-файлы или старые SQL dump.
Guardrail 2: allowlist на инструменты и пути
Дайте read/write только на те директории, которые реально нужны. Для shell-команд — allowlist, а не blacklist. В проде blacklist почти всегда пропускает неожиданный обход.
#!/usr/bin/env bash
set -euo pipefail
export WORKDIR="/srv/agent-task"
mkdir -p "$WORKDIR/out"
allowed_cmds=("python3" "pytest" "git" "ls" "cat")
cmd="${1:-}"
if [[ ! " ${allowed_cmds[*]} " =~ " ${cmd} " ]]; then
echo "blocked command: $cmd" >&2
exit 1
fi
cd "$WORKDIR"
exec "$@"2. Секреты не должны попадать в контекст модели
Я до сих пор вижу один и тот же паттерн: агенту дают доступ к репозиторию, в нем лежит .env, дальше модель “для диагностики” читает его, а потом пересказывает фрагменты в Slack или в generated content. Это не баг модели, это ошибка конструкции.
Guardrail 3: secrets только через runtime injection
Doppler, переменные окружения процесса, временные токены — нормальный путь. Файлы .env в рабочем каталоге агента — плохой путь. Даже если файл “только read-only”, он все равно может утечь в вывод.
Guardrail 4: pre-run secret scanning
Перед каждым запуском прогоняйте gitleaks по рабочему каталогу и падайте при совпадениях. Это дешево и ловит то, что разработчик “временно положил рядом”.
#!/usr/bin/env bash
set -euo pipefail
gitleaks detect \
--source /srv/agent-task \
--no-banner \
--exit-code 1 \
--redact
echo "No secrets detected in workspace"3. Публикации наружу должны идти через policy layer
Slack и WordPress опасны не потому, что они “небезопасны”, а потому что это внешние каналы, куда агент пишет без человеческой паузы. Если модель ошиблась в классификации текста, наружу уходит либо секрет, либо непроверенная информация, либо текст с персональными данными. Для DSGVO этого уже достаточно, чтобы получить проблему на ровном месте.
Guardrail 5: двухступенчатая публикация
Агент не публикует напрямую. Он создает draft в Postgres или Supabase, затем отдельный процесс проверяет policy и только потом отправляет в Slack webhook или WordPress API.
Guardrail 6: content filter по шаблонам риска
Я ставлю проверку на e-mail, API keys, JWT, строки вида password=, connection strings и куски .env. Это не заменяет DLP, но закрывает базовые production-ошибки.
import re
RISK_PATTERNS = [
r"AKIA[0-9A-Z]{16}",
r"-----BEGIN [A-Z ]+ PRIVATE KEY-----",
r"postgres(ql)?://[^\\s]+",
r"(?i)password\\s*=",
r"(?i)api[_-]?key\\s*[:=]",
r"[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+"
]
def is_publishable(text: str) -> bool:
return not any(re.search(pattern, text) for pattern in RISK_PATTERNS)
sample = "draft text for Slack"
if not is_publishable(sample):
raise ValueError("Blocked by content policy")4. Генерируемый код проверяйте как код, а не как “ответ модели”
Claude Code может сгенерировать рабочий фрагмент, который пройдет happy path и все равно занесет вам SQL injection, shell injection или небезопасную обработку файлов. Semgrep и Bandit здесь полезнее любого “будь осторожен” в system prompt.
Guardrail 7: static analysis на каждый generated diff
Semgrep хорошо ловит типовые паттерны в Python, JavaScript и YAML. Bandit — простой слой для Python. Если агент пишет n8n workflow JSON или SQL migration, добавьте отдельные проверки под эти артефакты.
Guardrail 8: policy на dangerous sinks
Запретите generated code без review, если он использует subprocess с shell=True, raw SQL через string interpolation, запись в .env, прямой outbound webhook или массовый update/delete без where.
| Артефакт | Инструмент | Что ловить |
|---|---|---|
| Python | bandit, semgrep | shell injection, небезопасные tempfile, weak crypto |
| JS/TS | semgrep | eval, command execution, SSRF patterns |
| Secrets | gitleaks | токены, ключи, connection strings |
| Policies | OWASP checklist | excessive agency, data exposure, tool misuse |
version: "3"
tasks:
scan:
cmds:
- semgrep --config p/owasp-top-ten .
- bandit -r . -q
- gitleaks detect --source . --no-banner --exit-code 1 --redact
silent: true5. Runtime guardrails важнее красивого prompt
Anthropic в документации по tool use прямо показывает, что модель должна работать через описанные инструменты и структурированные вызовы, а не через свободный доступ ко всему окружению: https://docs.anthropic.com/. Это правильная идея: чем меньше неявных прав у агента, тем меньше площадь ошибки.
Guardrail 9: журналируйте каждое tool invocation
Мне нужен лог: какой prompt, какой tool, какие аргументы, какой ответ инструмента, какой side effect. Иначе после инцидента вы не поймете, куда именно ушли данные: в Slack, WordPress, Supabase или shell.
Guardrail 10: kill switch и budget limits
У агента должен быть лимит на число tool calls, время выполнения и стоимость. Если цепочка пошла не туда, вы останавливаете run автоматически, а не спустя 20 минут после того, как он уже опубликовал мусор в 4 канала.
type ToolEvent = {
tool: string;
args: Record;
timestamp: string;
};
const MAX_CALLS = 12;
const events: ToolEvent[] = [];
export function recordToolCall(tool: string, args: Record) {
if (events.length >= MAX_CALLS) {
throw new Error("tool budget exceeded");
}
events.push({ tool, args, timestamp: new Date().toISOString() });
console.log(JSON.stringify(events[events.length - 1]));
}FAQ
Достаточно ли хорошего system prompt?
Нет. Prompt помогает модели интерпретировать задачу, но не ограничивает файловую систему, сеть и внешние публикации. В проде ограничения должны жить вне модели.
Нужен ли human approval перед каждой публикацией?
Не всегда. Для low-risk задач можно обойтись policy checks и draft-слоем. Но все, что касается персональных данных, финансовых операций или внешних заявлений от имени бренда, я обычно ставлю на approval.
Что важнее: sandbox или static analysis?
Это разные классы защиты. Sandbox сдерживает последствия во время выполнения, static analysis ловит опасные паттерны в generated code до запуска. В production нужны оба слоя.
Как это связано с DSGVO и регуляторикой ЕС?
Если агент может вывести персональные данные в Slack, CMS или лог, это уже вопрос обработки данных и контроля доступа. Для DACH-клиентов я документирую эти потоки отдельно, чтобы было видно, где модель видит данные и куда может их отправить.
С чего начать, если система уже работает?
С карты инструментов и каналов выхода. Выпишите, какие tool calls есть у агента, какие директории он читает, куда может писать, и только потом ставьте allowlist, secret scanning и publish gate.
На каком этапе у вас сейчас ловится больше всего проблем: при static analysis generated diffs, на runtime policy checks или уже после публикации в Slack и CMS? Мне правда интересно сравнить это с тем, что я вижу в проде у DACH B2B команд. Я провожу бесплатный 30-минутный stack audit для DACH founders, которые строят AI в regulated markets. Напишите мне в LinkedIn или в @ger_dennis_ai.
Такие агенты я делаю для бизнеса в Германии и ЕС.
Опишите в двух предложениях, что отнимает у команды время, — отвечу в течение суток.
Превратить процесс в систему, которая работает
Продакшн-качество, а не демо.