← Блог / Основы

Claude Code permissions: allow, ask, deny и безопасность

·7 мин

Один из первых рефлексов при работе с Claude Code — жать «Разрешить» на каждый запрос агента, не вчитываясь. Через неделю замечаешь, что агент сам пушит в репозиторий, читает .env и выполняет curl-запросы, которые ты не просил. Безопасность Claude Code — это архитектурное решение: настраивается один раз и избавляет от неприятных сюрпризов.

В этой статье разберём, как устроены Claude Code permissions на уровне конфигурации: три типа правил, где они хранятся, как закрыть секреты технически, и почему флаг --dangerously-skip-permissions опаснее, чем кажется.

Что такое permissions и зачем они нужны

Permissions — это контракт доверия между вами и агентом: где он действует сам, где спрашивает подтверждения, а что не делает никогда.

Как мы разбирали в статье про Claude Code, каждое реальное действие агента — это вызов инструмента: прочитать файл, запустить команду, записать изменения. Между «агент хочет вызвать инструмент» и «инструмент вызван» стоит слой разрешений. Без настройки этого слоя вы либо тормозите работу агента бесконечными подтверждениями, либо отдаёте ему слишком много свободы.

Permissions настраиваются в settings.json. Есть два уровня:

  • Проектный.claude/settings.json в корне репозитория. Коммитится в git, работает для всей команды.
  • Личный (глобальный)~/.claude/settings.json. Ваши настройки по умолчанию для всех проектов.

Три типа правил: allow, ask, deny

Каждый тип правил описывает инструмент и паттерн действия. Вот рабочий пример для проекта на NestJS + Next.js:

// .claude/settings.json
{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "permissions": {
    "allow": [
      "Bash(npm run lint)",
      "Bash(npm run test *)",
      "Bash(npm run start:dev)"
    ],
    "ask": [
      "Bash(git push *)"
    ],
    "deny": [
      "Bash(curl *)",
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)"
    ]
  }
}

Что означает каждый тип:

allow — выполнять без вопросов. Сюда идёт рутина, которую вы и так одобрили бы: запуск линтера, тестов, dev-сервера. Агент делает это в цикле без остановки, что нужно для нормальной TDD-работы.

ask — спросить подтверждение перед выполнением. Сюда — действия с необратимыми последствиями: git push, запуск миграций, операции с production-данными. Агент остановится и явно покажет, что именно собирается сделать.

deny — запрещено всегда, даже если агент получил инструкцию «прочитай .env». Deny — это техническая стена, не инструкция. Агент упрётся в запрет на уровне системы.

Принцип наименьших привилегий: разрешайте узко и конкретно. Bash(npm run test *) — хорошо. Bash(*) (всё подряд) — это отсутствие защиты. Чем шире правило, тем выше шанс, что агент сделает что-то неожиданное в его рамках.

Точный синтаксис паттернов может обновляться — сверяйтесь с актуальной документацией Claude Code.

Секреты и главная дыра новичков

Агент видит то, что попадает в контекст. Если он прочитает .env — токены, ключи API, строки подключения к БД — эти данные окажутся в контексте модели.

Это не гипотетический риск. Вот типичный сценарий: агент при отладке ошибки подключения сам предлагает «посмотреть конфигурацию» и тянется к .env. Без deny-правила это случится молча.

Чек-лист защиты секретов:

  1. Закрыть через deny: Read(./.env), Read(./.env.*), Read(./secrets/**) — как минимум это.
  2. .env — в .gitignore. Базовая гигиена, но при работе с агентом особенно важна: агент не коммитит то, чего нет в проекте.
  3. Опасные сетевые вызовы (curl *, wget *) — в deny или ask. Произвольные запросы наружу могут утянуть данные туда, куда вы не планировали.
  4. Деструктивные операции (удаление файлов, сброс данных) — только через ask, никогда через allow.
  5. Добавьте секцию «Чего НЕ делать» в CLAUDE.md: инструкция агенту работает в паре с технической стеной. Одно — ограничение на уровне инструмента, другое — на уровне понимания задачи.

Антипаттерн: —dangerously-skip-permissions

Флаг --dangerously-skip-permissions существует и задокументирован. Он отключает весь слой разрешений: агент выполняет любые действия без остановки.

Он нужен для строго изолированных сред — например, внутри Docker-контейнера без доступа к реальным данным и сети, в CI-пайплайне на одноразовом окружении. Это редкий, специализированный случай.

Почему это антипаттерн в обычной работе:

  • Слово «dangerously» в названии флага — не маркетинг. Это честное предупреждение.
  • На реальном проекте агент получает доступ ко всему: файлам, командам, сети.
  • Один неправильно понятый контекст — и агент может удалить файлы, запушить сломанный код или выполнить деструктивную команду.
  • Корпоративные политики безопасности часто запрещают этот флаг явно.

Если вы постоянно раздражаетесь от подтверждений — решение не в отключении разрешений, а в грамотном allow-списке для рутины.

Как это выглядит на практике: CoffeeCRM

Для сквозного проекта курса (CoffeeCRM, монорепо NestJS + Next.js + PostgreSQL) настройка permissions выглядит так:

// .claude/settings.json
{
  "permissions": {
    "allow": [
      "Bash(npm run lint)",
      "Bash(npm run test *)",
      "Bash(npm run start:dev)",
      "Bash(docker compose up -d)"
    ],
    "ask": [
      "Bash(git push *)",
      "Bash(npm run migration:run)"
    ],
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Bash(curl *)",
      "Bash(rm -rf *)"
    ]
  }
}

Агент запускает тесты в цикле без остановки — именно так работает TDD с агентом. При попытке запушить в репозиторий — явный стоп и подтверждение. Прочитать .env — стена.

Самый показательный момент: попросите агента «прочитай конфиг базы данных» на проекте с таким deny. Он попытается открыть .env и упрётся в запрет. Это и есть защита в действии, а не гипотетика.

Режимы работы и permissions

Claude Code поддерживает разные режимы — например, plan (агент только планирует, не выполняет) и acceptEdits (принимает правки без подтверждения). Режим по умолчанию задаётся через defaultMode в том же settings.json. Подробнее об этом — в статье про режимы Claude Code: plan и auto.

Режимы и permissions работают вместе: режим определяет общее поведение агента, permissions — точечные ограничения на конкретные инструменты.

Что делать прямо сейчас

  1. Откройте (или создайте) .claude/settings.json в вашем проекте.
  2. Добавьте deny на .env и секреты — это первый и обязательный шаг.
  3. Перенесите рутину (тесты, линт, dev-запуск) в allow.
  4. Всё, что затрагивает git или данные — в ask.
  5. Проверьте, что .env в .gitignore.

Permissions настраиваются один раз и работают тихо в фоне. После этого вы делегируете агенту рутину без тревоги — и именно это делает работу с агентом продуктивной, а не нервной.

Если хотите разобрать permissions, CLAUDE.md и всё остальное системно — на реальном проекте от нуля до деплоя — смотрите полный курс по Claude Code.

Курс

Освойте Claude Code системно

6 модулей, реальный fullstack-проект до деплоя, свои skills, MCP и агенты.

Смотреть программу курса