Permissions у Claude Code: settings.json і менше permission-prompt-ів

Доступ до одного з трьох файлів: ~/.claude/settings.json (user), <repo>/.claude/settings.json (project, у git), .claude/settings.local.json (local, у gitignore). Знання базового JSON. Корисно мати jq для валідації.
Три рівні налаштувань
| Рівень | Файл | Скоуп | У git? |
|---|---|---|---|
| User | ~/.claude/settings.json | Усі сесії твого користувача | Ні (особисті dotfiles) |
| Project | <repo>/.claude/settings.json | Тільки цей репо, для всіх, хто клонує | Так, командний |
| Local | .claude/settings.local.json | Цей репо, тільки у тебе | Ні (gitignore обов'язково) |
Правила злиття: project переписує user, local переписує project. Тобто більш специфічний рівень виграє. Деякі ключі мерджаться як масиви (наприклад, permissions.allow), деякі — повністю замінюються.
Структура settings.json
{
"model": "claude-opus-4-7",
"permissions": {
"allow": ["Bash(git status:*)", "Read(*)", "Glob(*)"],
"deny": ["Bash(rm -rf:*)", "Bash(sudo:*)"],
"ask": ["Edit(src/**)"]
},
"hooks": { ... },
"mcpServers": { ... },
"env": { "DEBUG": "1" }
}
Ключові блоки:
permissions— правила доступу до tools.hooks— shell-команди на події («Hooks»).mcpServers— підключення MCP-серверів (спиця «MCP-сервери»).env— змінні середовища для CC-сесії.model— модель за замовчуванням.
Patterns у allowlist
Дозволи описуються як Tool(pattern). Кілька форматів:
Точкові команди Bash
"Bash(git status:*)" // git status з будь-якими аргументами "Bash(npm test)" // тільки точно npm test, без аргументів "Bash(npm run *)" // npm run з будь-яким скриптом "Bash(docker ps:*)" // docker ps...
Glob по шляхах
"Read(*.md)" // читання будь-яких .md "Read(src/**/*.ts)" // .ts у src/ "Edit(tests/**)" // редагування файлів у tests/ "Write(/tmp/**)" // запис у /tmp
MCP-tools
"mcp__claude_ai_Gmail__search_threads" "mcp__myserver__publish_post" "mcp__*" // будь-який MCP-tool (рідко вживаний)
Wildcards
Bash(*) — дозволяє ВСЕ. Це антипатерн (хіба що для cron з --dangerously-skip-permissions). Краще явні правила.
Скіл /fewer-permission-prompts
Це окремий built-in скіл (доступний як slash), який сканує транскрипт твоєї поточної сесії і пропонує додати у allowlist часті read-only речі — типу git status, git diff, git log, ls, cat. Корисно після першого тижня роботи у новому проекті.
Запуск: просто /fewer-permission-prompts. Скіл аналізує, які tools ти найчастіше дозволяв, і пропонує JSON-патч до твого settings.json з конкретним allowlist'ом.
Чого не запускати у sensitive-проєктах: для виробничого репо краще тримати allowlist руками — скіл може запропонувати правило, ширше за бажане.
Кейси
1. Базовий мінімум для офісного workflow
{
"permissions": {
"allow": [
"Read(*)", "Glob(*)", "Grep(*)",
"Bash(git status:*)", "Bash(git log:*)", "Bash(git diff:*)",
"Bash(git branch:*)", "Bash(git show:*)",
"Bash(ls:*)", "Bash(cat:*)", "Bash(head:*)", "Bash(tail:*)",
"Bash(npm test:*)", "Bash(npm run *)"
],
"deny": [
"Bash(rm -rf:*)", "Bash(git push --force:*)",
"Bash(sudo:*)"
]
}
}
~12 allow-правил покриває 90% повсякденних операцій. Deny — три ключові «незворотні дії» (force-push, rm -rf, sudo).
2. Production-rigid режим
{
"permissions": {
"allow": [
"Read(*)", "Glob(*)", "Grep(*)"
],
"ask": [
"Bash(*)", "Edit(*)", "Write(*)"
]
}
}
Все, окрім read-only, питає підтвердження. Корисно у production-репо, де модель не повинна нічого писати/виконувати без явного твого «так».
3. Skill-only режим — CC робить лише те, що покривають скіли
Цей патерн складніший: ти забороняєш всі небезпечні tools у налаштуваннях, але дозволяєш конкретні MCP-tools, які викликають твої скіли. Виглядає так:
{
"permissions": {
"allow": [
"Read(*)", "Glob(*)", "Grep(*)",
"mcp__publisher__publish_post",
"mcp__dle__list_posts"
],
"deny": [
"Bash(*)", "Edit(*)", "Write(*)"
]
}
}
CC не може стрибнути у shell або писати у файли — тільки читати і викликати специфічні MCP-tools. Корисно для «робочого профілю» агента, який крутиться як сервіс.
4. Project + Local mix
У <repo>/.claude/settings.json (для команди):
{
"permissions": {
"allow": ["Read(*)", "Bash(npm test:*)", "Bash(npm run lint)"],
"deny": ["Bash(rm -rf:*)", "Bash(npm publish:*)"]
}
}
У <repo>/.claude/settings.local.json (твій локальний доповнення):
{
"permissions": {
"allow": ["Bash(docker compose:*)", "Bash(./scripts/seed-db.sh)"]
}
}
Командна частина у git — для всіх. Локальна — твоя зручність (docker, локальні seeds), не вантажиться у репо.
Підводні камені
deny сильніший за allow. Порядок не має значення: якщо команда матчить deny і allow одночасно — deny виграє. Перевір це після додавання нових правил.
ask ≠ блок. Просто показує підтвердження користувачу. Для CI/cron — використовуй deny, інакше задача зависне на «чекаю відповіді користувача».
settings.local.json у git — це баг безпеки. Перевір .gitignore. Часто там credentials або шляхи до приватних серверів. git ls-files | grep settings.local має повертати порожнечу.
Wildcards у Bash небезпечні. Bash(*) = повна свобода. Краще Bash(git:*), Bash(npm:*) — широкі, але обмежені програми. Bash(* status) теж антипатерн (матчить rm status, kill status...).
Двокрапка у патерні має значення. Bash(git status) матчить тільки точно «git status». Bash(git status:*) — «git status» з будь-якими аргументами. Це різні правила.
MCP-tools потребують повного шляху. mcp__myserver__publish — не publish, не myserver__publish. Перевірити точне ім'я — у списку tools з slash /mcp.
/fewer-permission-prompts на проді — обережно. Скіл генерує allowlist на основі минулих сесій. Якщо у минулому ти підтвердив chmod 777 «один раз заради тесту», скіл може запропонувати додати його у allow. Завжди ревʼюти запропонований JSON руками перед apply.
Cross-refs
- Поряд з
permissionsу settings.json — hooks. - Allowlist для MCP-tools — спиця «MCP-сервери».
- Permissions у sub-агента — «Sub-агенти».
- Як скіл
/fewer-permission-promptsпрацює зсередини — «Власні скіли».
jq . settings.jsonне падає (JSON валідний).- Є хоча б 5 allow-правил для тих команд, що виконуєш щодня.
- Deny містить незворотні дії:
rm -rf,git push --force,sudo(мінімум). - Settings.local.json у gitignore (якщо існує).
- Жодних wildcard
Bash(*),Edit(*)у allow (за винятком підтверджених сценаріїв). - Перевірено в реальній сесії — клацань стало менше.
- Для команди — project-рівень спільний у git; локальні доповнення у settings.local.json.
Схема permissions у settings.json для CC станом на травень 2026. Anthropic може додати нові типи правил (наприклад, time-based або conditional). Перевіряти у release notes і через /permissions.