Коротко (TL;DR)
settings.json — це конфігураційний файл Claude Code, де живуть дозволи (permissions), змінні середовища, хуки, модель і десятки інших ключів. На відміну від CLAUDE.md, який дає агентові поведінкові підказки, settings.json — це технічний примус: те, що записано в permissions, дотримується детерміновано, а не «на довірі».
- Коротко (TL;DR)
- settings.json і CLAUDE.md: різне призначення
- П’ять рівнів налаштувань та їхній пріоритет
- permissions: allow, ask і deny
- Sandbox і безпека: як пришвидшитися правильно
- Ризики: чому межі важливі
- Корисні ключі settings.json
- Швидкий старт: робочий settings.json за 5 хвилин
- Діагностика: коли налаштування не застосовується
- FAQ
Що важливо зрозуміти одразу:
- Налаштування лежать на п’яти рівнях із жорстким пріоритетом: managed (організація) → аргументи командного рядка → local → project → user.
- Масиви (наприклад,
permissions.allow) між рівнями не замінюються, а додаються — із двома винятками. - Правила permissions обчислюються в порядку deny → ask → allow: перший збіг вирішує результат.
- Увімкнений sandbox скорочує кількість запитів на підтвердження на 84% (внутрішня статистика Anthropic) — і це правильний спосіб пришвидшитися, а не
--dangerously-skip-permissions. - Коли «налаштування не застосовується», розібратися допомагає зв’язка
/status,/config,/permissionsі/doctor.
Нижче — як влаштована ієрархія, як налаштувати permissions і sandbox безпечно, які ключі корисні, які тут реальні ризики і як діагностувати конфіг, коли він поводиться не так.
settings.json і CLAUDE.md: різне призначення
Новачки часто плутають два файли й намагаються «налаштовувати» агента через CLAUDE.md. Офіційне розмежування просте: settings — для технічного примусу, CLAUDE.md — для поведінкових домовленостей. CLAUDE.md розповідає Claude, як влаштований проєкт і як у ньому заведено працювати; settings.json задає жорсткі рамки — що інструменту можна, а чого не можна, і це дотримується кодом.
Практичний висновок: правило «не читай .env» у CLAUDE.md — це побажання, яке можна обійти; те саме правило в permissions.deny — бар’єр. Усе, що критично (секрети, деструктивні команди), живе в settings.json. Тримайте цей поділ у голові — він пояснює половину запитань новачків «чому агент зробив те, що я заборонив».
П’ять рівнів налаштувань та їхній пріоритет
Claude Code збирає налаштування з кількох джерел. Пріоритет — від організації до особистих уподобань:Пріоритет Рівень Де лежить 1 (найвищий) Managed (організація) Системний шлях / MDM, ставить адмін 2 Аргументи командного рядка Прапорці під час запуску claude3 Local (особистий у межах проєкту) .claude/settings.local.json4 Project (командний) .claude/settings.json (у git)5 (найнижчий) User (особистий) ~/.claude/settings.json
Логіка така: ~/.claude/settings.json задає ваші глобальні вподобання для всіх проєктів; .claude/settings.json у репозиторії — спільні правила команди (їх комітять у git); .claude/settings.local.json — ваші особисті перевизначення для конкретного проєкту. Останній Claude Code сам додає до .gitignore під час створення, щоб особисті налаштування не витекли в спільний репозиторій. Managed-рівень стоїть над усіма: правило, задане адміністратором організації, локальним файлом перебити не можна — у цьому й полягає сенс корпоративного контролю.
Як складаються значення між рівнями
Тут є тонкість, яку майже ніхто не пояснює. Скалярні ключі (одне значення — наприклад, model) перевизначаються за пріоритетом: виграє вищий рівень. А от масиви (permissions.allow, permissions.deny і подібні) між рівнями конкатенуються й дедуплікуються, а не замінюються.
Розберемо на прикладі. Нехай у user-файлі стоїть "allow": ["Bash(git *)"], а в проєктному — "allow": ["Bash(npm *)"]. Агент отримає обидва дозволи: і git, і npm. Масиви не конкурують — вони підсумовуються. Те саме з deny: заборона, задана в managed-налаштуваннях, залишиться чинною, навіть якщо в проєктному файлі її немає. Це важливо розуміти, інакше легко здивуватися, звідки взявся дозвіл, якого немає у вашому поточному файлі.
Є винятки. fallbackModel не складається: його значення береться з одного рівня цілком. З availableModels тонше — він перестає зливатися, лише якщо його задає managed-джерело (політика організації): тоді застосовується саме цей список, а не сума. На звичайних рівнях (user, project, local) availableModels поводиться як будь-який інший масив — конкатенується й дедуплікується. Про це застереження не пише жоден популярний гайд, а поведінка неочевидна.
Ще деталь про надійність. Managed-налаштування парсяться толерантно: якщо в них потрапив запис, що не проходить схему, Claude Code виріже лише його й застосує решту. Користувацькі, проєктні та локальні файли, навпаки, суворі — одна помилка в JSON, і файл не застосується цілком. Тому після ручного редагування завжди перевіряйте, що JSON валідний: пропущена кома мовчки «вимкне» весь ваш settings.json.
permissions: allow, ask і deny
Ядро settings.json — блок permissions. Правила в ньому обчислюються в суворому порядку: deny → ask → allow. Перший збіг визначає результат, далі пошук не йде. Отже, deny завжди сильніший за allow: якщо дія підпадає під заборону, жоден дозвіл її не відкриє.
Розберемо на сценарії. Припустимо, у вас allow: ["Bash(git *)"], але водночас deny: ["Bash(git push *)"]. Команда git status пройде за allow, а git push упреться в deny — тому що deny перевіряється першим. Так будується модель «загалом працювати з git можна, але пушити — лише вручну».
Три типи правил:
allow— дозволити без запитань (наприклад,Read(src/**),Bash(npm test)).ask— завжди запитувати, навіть якщо щось інше це дозволяє.deny— заборонити жорстко, поверх усього.
Режим за замовчуванням задає defaultMode. Основні значення: default (запитувати в неоднозначних випадках), acceptEdits (приймати правки файлів без запитань), plan (лише планувати, нічого не виконувати), bypassPermissions (пропускати всі запити).
Ще важливий синтаксичний нюанс. «Голе» ім’я інструмента (Bash) у правилі стосується його цілком, а крапковий патерн (Bash(curl *)) — лише конкретної команди. Плутати їх — часта помилка: правило виходить або надто широким (заборонили весь Bash), або дірявим (закрили не те).
Про bypassPermissions — без ілюзій
bypassPermissions (він же прапорець --dangerously-skip-permissions) пропускає всі підтвердження, крім форсованих явними ask-правилами. Єдиний вбудований запобіжник — видалення кореня й домашньої теки (rm -rf / та rm -rf ~) він усе ж блокує. Усе інше — на ваш ризик, тому запускати його варто лише в контейнері чи ізольованому середовищі, а не на робочій машині. Якщо мета — просто менше клікати «дозволити», для цього є безпечніший інструмент, про нього нижче.
Патерн захисту секретів
Офіційно рекомендований спосіб закрити чутливі файли — зв’язка deny на читання секретів і на канал їх витоку:
{
"permissions": {
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)",
"Bash(curl *)"
]
}
}
Сенс саме в парі: закрити читання .env замало — потрібно перекрити й очевидний канал ексфільтрації (curl), інакше агент, прочитавши ключ іншим шляхом, зможе його «відправити». Це той випадок, коли одне правило без іншого створює хибне відчуття захисту.
Sandbox і безпека: як пришвидшитися правильно
Постійні запити на підтвердження дратують, і великою є спокуса вимкнути їх зовсім. Правильна відповідь — не bypassPermissions, а sandbox. За внутрішньою статистикою Anthropic, увімкнений режим пісочниці безпечно скорочує кількість запитів на 84%: агент працює в ізоляції — запис лише в робочу теку, обмеження мережі, — тому підтверджувати кожну дію вже не потрібно. Bash-sandbox підтримується на macOS, Linux і WSL2.
Ідея в розділенні: sandbox дає свободу дій усередині безпечної пісочниці, а deny-правила закривають те, що не повинно статися ніколи. Разом вони знімають майже весь потік запитів, не відчиняючи при цьому машину навстіж, як робить bypassPermissions.
Ризики: чому межі важливі
Розділ, який у туторіалах щодо settings.json зазвичай оминають. Налаштування прав — це не формальність: реальні інциденти показують, що стається, коли межі задані неакуратно.
- Інцидент Wolak (жовтень 2025). Розробник повідомив, що Claude Code виконав
rm -rf, видаливши домашню директорію, — на Ubuntu/WSL2, причому без--dangerously-skip-permissions. Публічний баг-репорт став одним із тригерів посилення запобіжників. - Інцидент із
~/(грудень 2025). Розгорнутий шляхrm -rf ~/призвів до видалення домашньої теки — класична пастка розгортання тильди оболонкою. - Баг успадкування у субагентів (липень 2026). Робочі субагенти не успадковували
allow-правила зsettings.local.jsonі запитували підтвердження на кожен виклик інструмента — приклад того, як тонкощі scope ламають очікувану поведінку прав. - Ін’єкція через документ (2026). Окремий, але спорідненої природи ризик: prompt injection через невидимий текст у
.docxпоказав, що модель permissions доводиться тримати в голові й під час роботи з чужими файлами, а не лише з командами.
Висновок не «Claude Code небезпечний», а «межі задаємо ми». Sandbox плюс акуратні deny-правила (секрети, деструктивні операції) знімають майже весь ризик, не перетворюючи роботу на нескінченне «дозволити?». Баланс, який варто тримати: за замовчуванням — заборона на небезпечне, свобода — всередині пісочниці.
Корисні ключі settings.json
Крім permissions, у settings.json є ключі, які варто знати:Ключ Що робить Застосовується modelМодель за замовчуванням (наприклад, Claude Sonnet 5 або Opus) Потрібен перезапуск сесії envЗмінні середовища для всіх сесій і підпроцесів На льоту hooksКоманди на події життєвого циклу агента На льоту apiKeyHelperЗовнішня команда, що віддає API-ключ (надсилається як заголовок) — companyAnnouncementsОголошення, що показуються під час старту —
Про перезавантаження: Claude Code стежить за файлами налаштувань і перечитує їх динамічно, коли їх змінюють, тож правки більшості ключів застосовуються до поточної сесії одразу. Виняток — ключі на кшталт model та outputStyle: вони потребують перезапуску.
Ключ env зручний, коли потрібно прокинути змінну в усі сесії й підпроцеси, — наприклад, задати проксі чи прапорець для інструмента. Тут є нюанс: змінні на кшталт NO_COLOR через env ідуть у підпроцеси, але не міняють кольори самого інтерфейсу Claude Code — для інтерфейсу таку змінну ставлять у shell до запуску claude. А hooks заслуговують на окрему згадку: оголошуються вони прямо в settings.json і вішають вашу shell-команду на подію життєвого циклу. Найпростіший приклад — сповіщення:
{
"hooks": {
"Notification": [
{ "matcher": "", "hooks": [ { "type": "command", "command": "notify-send 'Claude чекає на введення'" } ] }
]
}
}
Хуки — це те, що перетворює домовленості з побажань на гарантії: лінтер після кожної правки, блокування небезпечної команди до її виконання. Це тема окремого розбору, але знати, що хуки живуть саме в settings.json, важливо вже зараз: цей файл, на відміну від конфігів редакторів на кшталт Cursor, поєднує і права, і автоматизацію в одному місці.
Ще пара ключів, про які корисно знати заздалегідь. apiKeyHelper — це зовнішня команда, яку Claude Code запускає через системну оболонку, щоб отримати API-ключ; її вивід надсилається як заголовок авторизації. Прийом зручний, коли ключ не можна зберігати у відкритому вигляді: helper дістає його з менеджера секретів на льоту. А блок worktree.* керує фоновою роботою в ізольованих git-worktree (наприклад, worktree.baseRef — від якої гілки відгалужуватися): ці налаштування живуть за своїми правилами scope і не завжди зливаються за загальним пріоритетом, тож якщо ви ганяєте паралельні фонові сесії, їхню конфігурацію перевіряйте окремо. Знати про ці ключі заздалегідь корисно: натрапивши на них у чужому settings.json, ви не гадатимете, звідки взялася «магічна» поведінка.
Швидкий старт: робочий settings.json за 5 хвилин
Щоб теорія не лишилася теорією, ось мінімальний, але осмислений проєктний .claude/settings.json, з якого розумно почати майже будь-який репозиторій:
{
"model": "claude-sonnet-5",
"permissions": {
"allow": [
"Read(src/**)",
"Bash(npm run test)",
"Bash(npm run lint)",
"Bash(git status)",
"Bash(git diff *)"
],
"ask": [
"Bash(git push *)"
],
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)",
"Bash(curl *)"
]
},
"env": {
"NO_COLOR": "1"
}
}
Розберемо по рядках, що тут закладено і чому:
modelфіксує модель проєкту — щоб уся команда працювала на одній, а не на тій, що випадково обрана в чиїхось особистих налаштуваннях.allowвідкриває рутину без запитань: читати вихідний код, ганяти тести й лінт, дивитися статус і дифи git. Це ті дії, підтверджувати які щоразу — лише марнувати час.askлишає ручний контроль там, де ціна помилки висока:git pushзавжди запитає, навіть попри загальний дозвіл працювати з git. Це той самий порядок deny → ask → allow у дії.denyзакриває секрети й канал їх витоку — патерн, який ми розібрали вище.envпрокидає змінну в усі сесії й підпроцеси; тут для прикладу вимкнено колір у підпроцесах, так само задають проксі чи прапорці інструментів (на колір самого інтерфейсу Claude Code цей ключ не впливає).
Покладіть цей файл у .claude/settings.json, закомітьте — і вся команда отримає однакові правила. Особисті відхилення (наприклад, ви хочете дозволити собі ще пару команд) додавайте в .claude/settings.local.json, який не потрапить у git. Через пару тижнів роботи ви вже точково розширюватимете allow під звички проєкту — але стартовий каркас закриває 90% потреб.
Діагностика: коли налаштування не застосовується
Головний біль — «я поміняв settings.json, а нічого не змінилося». Ось робочий чек-лист.Команда Що показує /statusЯкі рівні налаштувань завантажені в сесію (рядок Setting sources) /configПоточні значення; з v2.1.181 можна міняти по одному: /config key=value/permissionsПідсумкові правила allow/deny після всіх злиттів /contextЩо реально потрапило в контекст /doctorЗагальна діагностика середовища
Порядок розбору зазвичай такий. Спершу /status — переконатися, що потрібний файл узагалі підхопився (часта причина — невалідний JSON у суворому user- чи project-файлі, який не застосувався цілком). Потім /permissions — подивитися, чи не перекрито ваш allow чиїмось deny з вищого рівня (згадуємо порядок deny → ask → allow). Якщо поведінка дивна і ви підозрюєте накопичені налаштування, запустіть Claude Code з чистим config-файлом у тимчасовій теці — через змінну CLAUDE_CONFIG_DIR, що вказує на порожній каталог. Так ви перевірите, чи відтворюється проблема «з нуля», чи її створює щось у ваших файлах. Цей прийом заощаджує години: він одразу відділяє «баг інструмента» від «моєї одруківки в JSON».
FAQ
Чим settings.json відрізняється від CLAUDE.md? settings.json — технічний примус (permissions, sandbox, hooks): дотримується детерміновано. CLAUDE.md — поведінкові підказки: поради, які можна обійти. Критичні обмеження — лише в settings.json.
Який рівень налаштувань головніший?
Порядок пріоритету: managed (організація) → аргументи командного рядка → local → project → user. Managed-налаштування адміна перебити не можна. Масиви при цьому складаються з усіх рівнів, а не замінюються (крім fallbackModel та availableModels).
Як безпечно прибрати постійні запити на підтвердження?
Увімкнути sandbox — він скорочує запити приблизно на 84% за рахунок ізоляції. Це безпечніше, ніж bypassPermissions/--dangerously-skip-permissions, який варто запускати лише в контейнері.
Як захистити .env і секрети?
Через permissions.deny: закрити і читання (Read(./.env*), Read(./secrets/**)), і канал витоку (Bash(curl *)). Одне без іншого діряве.
Чому правка settings.json не застосувалася?
Три часті причини: невалідний JSON (суворий файл не застосовується цілком), правило перекрито deny з вищого рівня, або ключ потребує перезапуску (model, outputStyle). Перевіряйте через /status і /permissions.
Що таке managed-налаштування і чи можна їх обійти? Це налаштування, які задає адміністратор організації на системному рівні (через MDM чи системний шлях). Вони стоять на вершині пріоритету — ані project-, ані local-, ані user-файл їх не переб’є. Саме так компанія централізовано закриває небезпечні дії на всіх машинах. На відміну від решти файлів, managed-налаштування парсяться толерантно: один невалідний запис не вимкне весь файл.
Чи потрібно комітити settings.json у git?
.claude/settings.json — так, це спільні правила команди, і тримати їх у репозиторії правильно: новий розробник клонує проєкт і одразу отримує ті самі дозволи й хуки. А .claude/settings.local.json — особисті перевизначення, Claude Code сам додає їх до .gitignore, щоб вони не потрапили в спільний репозиторій.
Курс «Claude Code з нуля до продакшену» · модуль «Конфіг, пам'ять, навички». Повна програма і два маршрути навчання — на сторінці курсу.
Попередній урок: CLAUDE.md: інструкція, яку агент читає · Наступний урок: Пам'ять Claude Code і memory rot
