Claude Code permissions: allow, ask, deny и безопасность
Один из первых рефлексов при работе с 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-правила это случится молча.
Чек-лист защиты секретов:
- Закрыть через
deny:Read(./.env),Read(./.env.*),Read(./secrets/**)— как минимум это. .env— в.gitignore. Базовая гигиена, но при работе с агентом особенно важна: агент не коммитит то, чего нет в проекте.- Опасные сетевые вызовы (
curl *,wget *) — вdenyилиask. Произвольные запросы наружу могут утянуть данные туда, куда вы не планировали. - Деструктивные операции (удаление файлов, сброс данных) — только через
ask, никогда черезallow. - Добавьте секцию «Чего НЕ делать» в 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 — точечные ограничения на конкретные инструменты.
Что делать прямо сейчас
- Откройте (или создайте)
.claude/settings.jsonв вашем проекте. - Добавьте
denyна.envи секреты — это первый и обязательный шаг. - Перенесите рутину (тесты, линт, dev-запуск) в
allow. - Всё, что затрагивает git или данные — в
ask. - Проверьте, что
.envв.gitignore.
Permissions настраиваются один раз и работают тихо в фоне. После этого вы делегируете агенту рутину без тревоги — и именно это делает работу с агентом продуктивной, а не нервной.
Если хотите разобрать permissions, CLAUDE.md и всё остальное системно — на реальном проекте от нуля до деплоя — смотрите полный курс по Claude Code.
Курс
Освойте Claude Code системно
6 модулей, реальный fullstack-проект до деплоя, свои skills, MCP и агенты.
Смотреть программу курса