【Claude Code】外部アクセス以外はほぼ自動承認!settings.jsonで快適に手放しする書き方

概要

今回はClaude Codeで「外部アクセス以外はほぼ自動承認」を実現するsettings.jsonの書き方について紹介していきます。

Claude Codeを真面目に使い始めると、毎回y/nを押すのがだんだんしんどくなってくるんですよね(- -;

かといって全部フルオートにすると、rm -rfgit push --forceみたいな取り返しのつかない事故が怖い。
PCのデータが消えるのは勘弁です…

そこで、「広くallowして、危険なパターンだけdenyで具体的に塞ぐ」という設計でsettings.jsonを書いてみたら、思いのほか快適に運用できたので共有します。

合わせて、「WebFetchやWebSearchの外部アクセスだけは都度承認したい」という保守寄りパターンも併記します。
自分の作業スタイルに合わせて、どちらかをベースに育てていくのがお勧めです(^^b

それではやっていきましょう!

ここで紹介する設定は完璧でない可能性があります。
理解し調べてから使用するようにしてください!
何かあったときの責任はとれないので、あくまで自己責任での実施をお願いします。

目次

なぜ「自動承認」の設計を考えたか

都度承認のしんどさ

Claude Codeをデフォルト設定のまま使うと、ファイル編集・Bashコマンド・WebFetchなど、ほぼすべての操作で確認プロンプトが出ます。

最初のうちは「安全でいいな」と思うんですが、ブログ執筆や軽い検証作業を回しているとすぐに気づきます。
「もうAIだけでよくね??」と

<都度承認のつらいところ>
  • テストやビルドのループで何度も止まる
  • 同じコマンドで何回も同じy/nを押す
  • 思考が中断されるので作業のテンポが死ぬ
  • そのうち脳死でyを押すようになり、承認の意味が薄れる

最後のやつが一番まずいですよね。
慣れで全部yを押すなら、最初から自動承認で設計したほうがマシです。

かといってフル自動も怖い

じゃあ全部許可にすればいいかというと、それはそれで怖い。

Claude Codeには起動オプションの--dangerously-skip-permissionsや、settings.jsonのdefaultMode: "bypassPermissions"という設定で、確認プロンプトを全部すっ飛ばすモード(いわゆるデンジャラスモード、通称YOLOモード)が用意されてはいます。
ただし公式がdangerouslyと名乗っているレベルでハイリスクで、rm -rf ~git push --forceも問答無用で走ってしまう世界です(- -;

rm -rf ~を一発で食らったり、git push --forceを本番ブランチに撃ち込まれたら泣くしかありません。
npm publishを意図せず叩かれて、内製ライブラリが世界に公開されちゃうのもまずい。

そこで今回紹介するのは、デンジャラスモード(bypassPermissions)を使わずに、settings.jsonのallow/denyの設計だけで「ほぼ自動承認」に近づける方法です。
ほしいのはあくまで、「日常作業は止めずに走らせるけど、取り返しのつかない操作だけは手で止められる」という設計で、これをsettings.jsonでうまく表現してあげればOK、というのが今回の発想です。

設計思想:広く allow → 危険な穴だけ deny で塞ぐ

defaultMode は acceptEdits

まずdefaultModeacceptEditsにしておきます。
これでファイルのEdit/Writeは自動的に通るようになります。

ここをbypassPermissionsにしてしまうと前述のデンジャラスモード相当になって、denyリストすら効かない完全フリーパス状態になります。
なので、あえてacceptEdits止まりにしておくのが今回の肝です。
Bashコマンドなどの実行系は、引き続きallow/denyの評価を通して制御する作戦になります。

defaultModeに指定できる主な値は次の3つです。
default:すべて都度承認(標準)
acceptEdits:ファイル編集は自動承認、Bashなどは個別ルール評価
bypassPermissions:全許可(デンジャラスモード相当、本記事では使わない)

allow と deny の2段構え

Claude Codeのpermissionsは、ざっくり次のルールで動きます。

<評価の優先度>
  1. denyにマッチ → 即拒否
  2. allowにマッチ → 自動承認
  3. どちらにも当てはまらない → 都度確認

つまりdenyが最優先なので、allowを広めに書いても、deny側に書いた危険パターンはちゃんと止まってくれます。

この性質を使って、

  • allow: Bash, WebFetch, WebSearchをまるごと許可
  • deny: 具体的な危険コマンドのパターンだけ明示的に拒否

という、いわば「ホワイトリスト + ピンポイントブラックリスト」のハイブリッド構成にします。

A案:オフライン作業重視(広く allow + deny で穴塞ぎ)

まずはメインで使っているパターン、A案を紹介します。
ローカル中心で作業していて、Web調査も気軽にやらせたいタイプ向けです。

settings.json 全文

これが実際に使っている.claude/settings.jsonの中身です。

.claude/settings.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
{
"permissions": {
"defaultMode": "acceptEdits",
"allow": [
"Bash",
"WebFetch",
"WebSearch"
],
"deny": [
"Bash(rm -rf /)",
"Bash(rm -rf /*)",
"Bash(rm -rf ~)",
"Bash(rm -rf ~/*)",
"Bash(rm -rf ~/)",
"Bash(rm -rf $HOME*)",
"Bash(rm -rf /home*)",
"Bash(rm -rf /Users*)",
"Bash(rm -rf /c)",
"Bash(rm -rf /c/*)",
"Bash(rm -rf /c/Users*)",
"Bash(rm -rf /c/Windows*)",
"Bash(rm -rf /c/Program*)",
"Bash(rm -rf c:)",
"Bash(rm -rf c:/)",
"Bash(rm -rf c:/*)",
"Bash(rm -rf C:*)",
"Bash(rm -rf /mnt*)",
"Bash(rm -rf /usr*)",
"Bash(rm -rf /etc*)",
"Bash(rm -rf /var*)",
"Bash(rm -rf /bin*)",
"Bash(rm -rf /opt*)",
"Bash(rm -rf /root*)",
"Bash(rm -rf ../*)",
"Bash(rm -rf ..)",
"Bash(sudo *)",
"Bash(shutdown *)",
"Bash(reboot *)",
"Bash(mkfs*)",
"Bash(dd if=*)",
"Bash(dd of=/dev*)",
"Bash(chmod 777 /*)",
"Bash(chown * /*)",
"Bash(git push --force *)",
"Bash(git push -f *)",
"Bash(git reset --hard *)",
"Bash(git clean -fd /*)",
"Bash(format *)",
"Bash(del /f /s /q C:*)",
"Bash(rmdir /s /q C:*)",
"Bash(powershell Remove-Item *)",
"Bash(rm -rf %USERPROFILE%*)",
"Bash(rm -rf %APPDATA%*)",
"Bash(npm publish*)",
"Bash(curl * | sh)",
"Bash(curl * | bash)",
"Bash(wget * | sh)",
"Bash(wget * | bash)"
]
}
}

allowはBash/WebFetch/WebSearchの3行しかありませんが、これで実際の作業時間の9割は自動承認で流れてくれます。

deny に何を入れているか

denyに並べているコマンドは、ざっくり4つのカテゴリに整理できます。

<①ファイル破壊系>
  • rm -rf / / rm -rf ~ / rm -rf $HOME*などの典型パターン
  • Windows系のdel /f /s /q C:* / rmdir /s /q C:*
  • powershell Remove-Item *
  • %USERPROFILE%* / %APPDATA%*へのrm -rf
  • 親ディレクトリ遡上のrm -rf ../* / rm -rf ..

ローカルやホームディレクトリを一掃するパターンを、Linux/Windowsの両系統でつぶしています。
パスを少し変えれば回避できてしまうんですが、「うっかり」事故の大半はここで止まるのでコスパは良いです。

<②権限昇格・システム変更系>
  • sudo * / shutdown * / reboot *
  • mkfs* / dd if=* / dd of=/dev*
  • chmod 777 /* / chown * /*

OSやハードウェアに手を伸ばすコマンドはまるごとdeny。
個人開発でこれが必要になることはまずないので、止めて問題ないですね。

<③Gitの取り返しがつかない操作>
  • git push --force * / git push -f *
  • git reset --hard *
  • git clean -fd /*

ここが地味に重要です。
Claude Codeはたまに気を利かせてgit reset --hardを提案してくることがあるんですが、ローカルの未コミット変更を吹き飛ばされると本気で泣くやつなので、必ず手で承認したい操作です。

<④外部に影響を与える操作>
  • npm publish*(パッケージ公開)
  • curl * | sh / curl * | bash(ネット経由のシェル実行)
  • wget * | sh / wget * | bash

この4つ目が、今回のテーマである「外部アクセス以外は自動承認」の肝になる部分です。
ネットから持ってきたスクリプトをそのままシェルに食わせるパターンは、サプライチェーン攻撃の温床なので絶対に手で確認したい。
npm publishも意図しない公開は完全に取り返しがつかないので、deny必須です。

この案が向いている人

A案はこんな人にお勧めです。

<A案が向いている人>
  • ローカルでの開発・ブログ執筆・スクリプト生成がメイン
  • Web検索や公式ドキュメントの参照をClaude Codeに頻繁に投げる
  • 「危険コマンドだけ止まればOK」と割り切れる
  • テンポ重視で作業したい

実際この設定で運用していますが、半日Claude Codeを走らせて承認プロンプトが出るのは1〜2回あるかないか、という感じで、かなり快適です(^^

B案:外部アクセスは承認制(WebFetch/WebSearchを allow から外す)

A案だとWebFetch/WebSearchも自動承認されてしまうので、「外部に出る通信は念のため手で止めたい」という人向けに、もう1パターン用意しておきます。

A案との差分

変えるのはallowの中身だけです。
WebFetchWebSearchを外して、Bashだけ残します。

denyリストはA案と全く同じでOKです。

差分版 settings.json

allowの差し替え部分だけ抜粋するとこうなります。

.claude/settings.json(差分のみ)

1
2
3
4
5
6
7
8
9
10
11
{
"permissions": {
"defaultMode": "acceptEdits",
"allow": [
"Bash"
],
"deny": [
// ... A案と同じ
]
}
}

これだけで、Claude Codeが外部URLを取りに行こうとしたり、Web検索を打とうとしたタイミングで毎回承認プロンプトが出るようになります。

WebFetchについては`WebFetch(domain:example.com)`のようにドメイン単位で許可することもできます。
「自社のドキュメントサイトだけは自動承認したい」みたいな運用なら、allowに該当ドメインを足してあげると無駄な確認が減って便利です。

この案が向いている人

B案はこんな人にお勧めです。

<B案が向いている人>
  • 業務コードや機密情報を扱うリポジトリで使う
  • プロンプトインジェクション経由で外部URLに情報が漏れるのを警戒したい
  • オフライン中心で、Web検索の頻度が高くない
  • セキュリティチームの目を意識する立場

外部に出る系は1テンポ遅れますが、「どこにアクセスしようとしているか」が毎回見えるのは精神衛生上かなり良いです。
仕事用リポジトリのプロジェクト直下に置く.claude/settings.jsonはB案、個人ブログのリポジトリはA案、みたいに使い分けるのもアリですね。

運用してみた所感

メリット

半年ほどA案ベースで運用してみた感想として、こんな良さがあります。

<メリット>
  • y/n地獄から解放されて作業のテンポが取り戻せる
  • denyに具体的なパターンが並んでいるので「何が止まるか」を読んで把握できる
  • 危険コマンドが提案された時だけプロンプトが出るので、逆に「お、何かやらかそうとしてるな」と気づきやすい
  • チームでsettings.jsonを共有すれば、ガードラインを言語化したまま配れる

最後のやつはチーム開発なら大きいですよね!
denyリストって、そのままセキュリティポリシーの記録になるんですよね。

注意点(denyパターンの過信は禁物)

ただし、過信は禁物です。

denyのパターンはglob/前方一致ベースなので、回避手段はいくらでもあります。
例えば`rm -rf C:*`はdenyされても、`rm -rf "C:\Users\foo"`のようにクォートを変えたり、シェル変数経由にすると素通りする可能性があります。
あくまで「うっかり事故防止のガードレール」であって、悪意あるエージェントから守る仕組みではない、という前提で使ってください。

なので運用するときは、

  • 重要なリポジトリは常にコミット済みの状態にしておく
  • 本番に近い操作(DBマイグレーションとか)は別途確認を挟む癖をつける
  • denyリストは作業の中で「これも入れときたいな」と思ったら都度追記する

このあたりをセットで意識するのが現実的です。

まとめ

今回はClaude Codeで「外部アクセス以外はほぼ自動承認」を実現するsettings.jsonの書き方を、A案/B案の2パターンで紹介しました。

ポイントをおさらいすると以下のとおりです。

<まとめ>
  • defaultMode: acceptEdits + allowを広めに、denyで危険コマンドをピンポイント拒否、というハイブリッド構成が快適
  • denyは「ファイル破壊」「権限昇格」「Git取り返しNG」「外部影響」の4カテゴリで整理しておくと抜け漏れが減る
  • WebFetch/WebSearchまでallowに入れるかどうかは、扱うリポジトリの性質で使い分けるのが現実的
  • denyは「うっかり事故」へのガードレール、悪意ある回避までは守れないので過信しない

「設定で守れるところは設定で守って、人間は本質的な判断に集中する」のがClaude Codeとの正しい付き合い方かなと思っています。

settings.jsonは作業しながら少しずつ育てていけるので、まずはA案かB案をコピーして、自分のリポジトリで「これも止めたい」と思った瞬間にdenyを足していくのがお勧めです(^^b

以上となります。
もうAIだけでよくない?って思うたタイミングが多い今日この頃
それではお疲れさまでした!