6
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Claude Codeのsettings.jsonに新構文Tool(param:value)が加わった ── 何ができるようになったのか解説

6
Last updated at Posted at 2026-06-29

はじめに

Claude Code の settings.json には、ツール単位で「許可する/確認する/拒否する」を細かく決める permissions という仕組みがあります。

この記事では、permissions のルール構文を公式ドキュメントに沿って読み解きます。

特に、ツールの入力パラメータで照合する Tool(param:value) 形式と、従来からある Bash(npm run *) のような構文の違いに焦点を当てます。

この記事で得られること

  • permissions のルール構文(ToolTool(specifier))の読み方
  • Bash(npm run *)Bash(npm run:*) の違い、空白とワイルドカードの落とし穴
  • Tool(param:value) がどのツール・どのリスト(allow / deny / ask)で使えるか
  • Read / Edit のパス指定(gitignore 準拠)と WebFetch のドメイン指定
  • 誤許可・抜け穴を作りにくい permissions の組み立て方

対象読者

  • Claude Code を業務やチームで使っていて、設定で挙動を絞りたい方
  • 「とりあえず全部許可」から一歩進んで、権限を設計したい方
  • AIエージェントへの委譲を、人間のレビューを挟みつつ安全に回したい方

前提・実行環境

  • Claude Code v2.1 系(Tool(param:value) 構文は 2026年6月のアップデートで追加されました)
  • 設定ファイルは settings.json.claude/settings.json など)
  • 本文中のパスやコマンドは説明用に一般化した例です

おことわり

  • permissions の挙動は Claude Code 本体が解釈します。CLAUDE.md やプロンプトの指示では変わりません。本記事もこの前提に立っています。
  • 掲載した settings.json は公式ドキュメントの記法に沿って組んだ概念例です。実際の運用では /permissions で挙動を確認してから採用することをおすすめします。
  • 本記事は公式ドキュメント(settings / permissions)と公開情報をもとに整理したものです。バージョンによって挙動が変わる可能性があるため、最終的な確認は公式ドキュメントでお願いします。
  • 「permissions の組み立て方」の節は、筆者がAIエージェントへの委譲スコープを設計するなかで意識している観点です。唯一の正解ではなく、状況に応じて調整してください。

permissions の全体像

permissions は3つのリストで構成されます。

  • allow: 確認なしでツールを使わせる
  • ask: 使うたびに確認を求める
  • deny: 使わせない

ここで最初に押さえたいのが評価順です。

公式ドキュメントは次のように述べています。

Rules are evaluated in order: deny, then ask, then allow. The first match in that order determines the outcome, and rule specificity doesn't change the order.

出典: Configure permissions - Claude Code Docs

つまり deny → ask → allow の順で、最初にマッチしたルールが結果を決めます。

ルールの「具体度」は順番に影響しません。

この性質は誤許可を防ぐうえで重要です。

広い deny は、より具体的な allow があっても勝ちます。

公式ドキュメントの例で確認します。

A broad deny rule like Bash(aws *) blocks every matching call, including calls that also match a narrower allow rule like Bash(aws s3 ls), so a deny rule can't carry allowlist exceptions.

出典: Configure permissions - Claude Code Docs

Bash(aws *) を deny に入れると、Bash(aws s3 ls) を allow に入れていてもブロックされます。

deny は「例外つきの許可リスト」を表現できません。

「基本は禁止、ここだけ許す」をやりたいときは、deny を広げすぎないことが設計のコツになります。

ルール構文の基本

permissions のルールは次の2つの形を取ります。

  • Tool(ツール名だけ)
  • Tool(specifier)(ツール名+丸かっこの指定子)

ツール名だけで全マッチ

ツール名だけを書くと、そのツールのすべての利用にマッチします。

ルール 効果
Bash すべての Bash コマンド
WebFetch すべての Web 取得
Read すべてのファイル読み取り

Bash(*)Bash と同じ意味で、すべての Bash コマンドにマッチします。

ひとつ知っておきたい挙動があります。

deny でツール名だけ(または Bash(*))を書くと、そのツールは Claude のコンテキストから丸ごと外れます。

一方 Bash(rm *) のようにパターンで絞った deny は、ツール自体は残したまま、マッチした呼び出しだけを止めます。

指定子で絞り込む

丸かっこの中に指定子を書くと、特定の使い方だけにマッチします。

{
  "permissions": {
    "allow": [
      "Bash(npm run build)",
      "Read(~/.zshrc)",
      "WebFetch(domain:example.com)"
    ]
  }
}
  • Bash(npm run build)npm run build という完全一致のコマンド
  • Read(~/.zshrc) はホームディレクトリの .zshrc の読み取り
  • WebFetch(domain:example.com)example.com への取得

ここまでが、permissions を読むときの土台です。

Bash ルールとワイルドカードの落とし穴

Bash のルールは * によるワイルドカードに対応しています。

* はコマンドのどの位置にも置けます。

公式ドキュメントの例を引きます。

  • Bash(npm run build)npm run build に完全一致
  • Bash(npm run test *)npm run test で始まるコマンド
  • Bash(npm *)npm で始まる任意のコマンド
  • Bash(* install) install で終わる任意のコマンド
  • Bash(git * main)git checkout maingit log --oneline main にマッチ

* ひとつで空白を含む任意の文字列にマッチするため、ワイルドカード1個が複数の引数にまたがります。

空白の有無で挙動が変わる

ここが最初のつまずきどころです。

* の直前に空白があるかどうかで、単語境界の扱いが変わります。

公式ドキュメントの説明です。

The space before * matters: Bash(ls *) matches ls -la but not lsof, while Bash(ls*) matches both.

出典: Configure permissions - Claude Code Docs

つまり次のようになります。

  • Bash(ls *)ls -la にマッチするが lsof にはマッチしない
  • Bash(ls*)ls -lalsof もマッチする

lsof を意図せず許可してしまうのは、たいてい空白を省いたときです。

意図したコマンドだけに絞りたいなら、空白つきの Bash(ls *) を使うのが安全です。

:* は末尾ワイルドカードの別表記

permissions には :* という書き方も登場します。

これは末尾の * と同じ意味です。

The :* suffix is an equivalent way to write a trailing wildcard, so Bash(ls:*) matches the same commands as Bash(ls *).

出典: Configure permissions - Claude Code Docs

Bash(npm run:*)Bash(npm run *) は同じコマンド群にマッチします。

ただし注意が要ります。

:* は末尾でだけ有効です。

末尾以外のコロンは、ただの文字として扱われます。

たとえば Bash(git:* push): はリテラル文字なので、git コマンドにはマッチしません。

末尾の :* 以外でコロンを使うときは、意図どおりに動くか /permissions で確認することをおすすめします。

引数を絞る Bash ルールは壊れやすい

Bash ルールで「引数まで」を縛ろうとすると、抜け道ができやすいです。

公式ドキュメントは curl の例で警告しています。

Bash permission patterns that try to constrain command arguments are fragile. For example, Bash(curl http://github.com/ *) intends to restrict curl to GitHub URLs, but won't match variations like:

  • Options before URL: curl -X GET http://github.com/...
  • Different protocol: curl https://github.com/...

出典: Configure permissions - Claude Code Docs

オプションの位置、プロトコル違い、リダイレクト、変数展開、余分な空白などで簡単にすり抜けます。

URL でアクセス先を縛りたいなら、Bash の curl / wget を deny で塞ぎ、WebFetch 側で WebFetch(domain:...) を使うほうが堅牢です。

これは「ツールごとに役割を分けて縛る」という設計の典型例だと感じています。

新しい Tool(param:value) 構文を読み解く

ここからが本題です。

2026年6月のアップデート(v2.1.178)で、ツールの入力パラメータで照合する Tool(param:value) 構文が追加されました。

これは従来の「コマンド文字列やパスで照合する」やり方とは別の軸です。

どんな構文か

公式ドキュメントの「Match by input parameter」を引きます。

Deny and ask rules can match a top-level input parameter on any tool with Tool(param:value). The rule matches when Claude calls the tool with that parameter set to that exact value.

出典: Configure permissions - Claude Code Docs

ツールのトップレベルの入力パラメータが、指定した値と一致したときにマッチします。

公式ドキュメントの例です。

ルール マッチする呼び出し
Agent(model:opus) Opus モデルを要求する Agent 呼び出し
Agent(isolation:worktree) git worktree を要求する Agent 呼び出し
Bash(run_in_background:true) バックグラウンド実行の Bash 呼び出し

たとえば Agent(model:opus) を deny に入れると、サブエージェントを Opus で起動する呼び出しだけを止められます。

ツール単位ではなく、パラメータ単位で許可・拒否を切り分けられるのがポイントです。

allow には使えない(重要な制約)

ここが見落としやすい制約です。

Tool(param:value)deny と ask でのみ使えます。

allow には使えません。

公式ドキュメントの理由が明快です。

An allow rule for one parameter value wouldn't establish that the call is safe overall, so allow rules continue to use each tool's own specifier syntax.

出典: Configure permissions - Claude Code Docs

「あるパラメータの値がひとつ一致した」だけでは、その呼び出し全体が安全だとは言えません。

だから allow は、各ツール固有の指定子(Bash(...) のコマンド照合、Read(...) のパス照合など)を使い続けます。

このルールは、設計思想として筋が通っていると感じます。

許可は「全体として安全」を担保したいので慎重に、禁止は「この条件に当たったら止める」で軽く書ける、という非対称になっています。

パラメータ照合の細かいルール

Tool(param:value) にはいくつか把握しておきたい規則があります。

公式ドキュメントの要点を整理します。

  • パラメータ名はツール入力の直下のフィールドであること。オブジェクトや配列の中にネストしたフィールドは対象外
  • 1ルールにつき1パラメータ。modelisolation を両方縛るなら Agent(model:opus)Agent(isolation:worktree) の2ルールに分ける
  • 値は * をワイルドカードとして使える。Agent(isolation:*) は明示された任意の isolation 値にマッチする
  • モデルが省略したパラメータはマッチしない。Agent(model:*)model 未設定の呼び出しにはマッチしない
  • 値は正規化前の入力と比較される。Agent(model:opus) はエイリアス opus にはマッチするが、完全なモデルIDにはマッチしない
  • コロン前後の空白は無視される

--verbose で実行すると、各ツール呼び出しの実際のパラメータ名と値が見られるので、ルールを書く前の確認に使えます。

コマンド・パス・URL は param 照合の対象外

もうひとつ大事な制約があります。

ツールが独自の正規化ルールで照合しているフィールドは、Tool(param:value) では照合できません。

具体的には次のフィールドです。

  • Bash / PowerShell の command
  • Read / Edit / Write の file_path
  • Grep / Glob の path
  • NotebookEdit の notebook_path
  • WebFetch の url

理由は安全性です。

公式ドキュメントの説明を引きます。

A rule like Bash(command:rm *) would be bypassable by a compound command, so Claude Code ignores it and emits a startup warning. Use Bash(rm *), Read(./path), or WebFetch(domain:host) instead.

出典: Configure permissions - Claude Code Docs

Bash(command:rm *) は複合コマンドで回避できてしまうので、Claude Code は無視して起動時に警告を出します。

コマンドを縛りたいなら Bash(rm *)、パスを縛りたいなら Read(./path)、URL を縛りたいなら WebFetch(domain:host) を使う、という住み分けです。

「param 照合は新しいけれど、何でもこれで書けるわけではない」という点は最初に押さえておくと混乱しません。

Read / Edit のパス指定(gitignore 準拠)

ファイル系のルールは、パスの起点(アンカー)の理解が肝心です。

Read と Edit のルールは gitignore の仕様に従い、4つのパターンタイプがあります。

パターン 意味
//path ファイルシステムのルートからの絶対パス Read(//Users/alice/secrets/**)
~/path ホームディレクトリからのパス Read(~/Documents/*.pdf)
/path プロジェクトルートからの相対パス Edit(/src/**/*.ts)
path または ./path カレントディレクトリからの相対パス Read(*.env)

ここで一番間違えやすいのが /path です。

/path は絶対パスではありません。

公式ドキュメントが明示しています。

A pattern like /Users/alice/file isn't an absolute path. It's relative to the project root. Use //Users/alice/file for absolute paths.

出典: Configure permissions - Claude Code Docs

/Users/alice/file は絶対パスではなく、プロジェクトルートからの相対パスです。

絶対パスを書きたいときは //Users/alice/file のようにスラッシュ2本で始めます。

機密ファイルを deny で守るつもりが、アンカーを間違えて別の場所を指していた、という事故はここで起きます。

.env を確実に塞ぐ書き方

よくある「.env を読ませない」を例にします。

{
  "permissions": {
    "deny": [
      "Read(.env)",
      "Read(.env.*)",
      "Read(./secrets/**)"
    ]
  }
}

Read(.env) は gitignore 準拠で、カレントディレクトリ以下の任意の深さの .env にマッチします。

公式ドキュメントによれば Read(.env)Read(**/.env) は等価です。

ファイルシステム全体の .env を塞ぎたいなら Read(//**/.env) を使います。

このアンカーの違いが、deny の届く範囲を決めます。

WebFetch のドメイン指定

WebFetch は domain: プレフィックスで、リクエスト先のホスト名と照合します。

  • WebFetch(domain:example.com)example.com への取得
  • WebFetch(domain:*.example.com) は任意の深さのサブドメイン(api.example.com など)にマッチするが、example.com 自体にはマッチしない
  • WebFetch(domain:*) はすべてのドメインにマッチし、WebFetch だけと等価

ワイルドカードの位置にも仕様があります。

先頭の *. か単独の * 以外では、* はドット2つの間のテキストだけにマッチします。

公式ドキュメントの説明です。

WebFetch(domain:example.*) matches example.org, where * becomes org, but not example.evil.com, where * would have to become evil.com and cross a dot.

出典: Configure permissions - Claude Code Docs

example.*example.org にマッチしますが、example.evil.com にはマッチしません。

* がドットをまたげない仕様により、攻撃者が登録しうるドメインへの誤マッチを防いでいます。

なお、WebFetch を allow しただけではネットワークアクセスを止めたことにはなりません。

Bash が許可されていれば curl などで任意の URL に到達できます。

URL を縛るなら、前述のとおり Bash のネットワークツールを deny で塞ぐところまでセットで設計する必要があります。

MCP ツールのルール

MCP のルールは、Claude Code に設定したサーバー名を使い、必要に応じてツール名を続けます。

  • mcp__puppeteerpuppeteer サーバーの任意のツール
  • mcp__puppeteer__* も同サーバーの全ツール
  • mcp__puppeteer__puppeteer_navigate は特定のツール

allow と deny でワイルドカードの扱いが違う点に注意します。

deny と ask はツール名の位置にグロブを使えます。

mcp__* はすべての MCP ツールにマッチします。

{
  "permissions": {
    "deny": [
      "mcp__*"
    ]
  }
}

一方 allow は、mcp__<server>__ という具体的なサーバー接頭辞の後ろでしかグロブを使えません。

"*""mcp__*" のような起点のない allow グロブは、警告とともにスキップされ、何も自動許可しません。

ここでも「禁止は広く書ける/許可は具体的に」という非対称が一貫しています。

permissions の組み立て方(自分の観点)

ここからは公式仕様そのものではなく、筆者がAIエージェントへの委譲スコープを設計するときに意識している観点です。

唯一の正解ではないので、参考程度に受け取ってください。

deny を最優先で薄く広く

評価順が deny → ask → allow なので、止めたいものは deny に入れれば確実です。

ただし広い deny は allow の例外を潰します。

そこで筆者は「絶対に触らせたくないもの(鍵・秘密・破壊的コマンド)」だけを deny に置き、それ以外は ask / allow で調整するようにしています。

{
  "permissions": {
    "deny": [
      "Read(.env)",
      "Read(.env.*)",
      "Read(~/.ssh/**)",
      "Bash(rm -rf *)",
      "Bash(curl *)",
      "Bash(wget *)"
    ]
  }
}

この例は概念例です。

実際には自分の環境で /permissions を見ながら調整してください。

破壊的操作・外部送信は ask に寄せる

「やってもよいが、人間に一声かけてほしい」操作は ask が向いています。

{
  "permissions": {
    "ask": [
      "Bash(git push *)",
      "Bash(git commit *)"
    ]
  }
}

ask はツール単位だけでなく Tool(param:value) でも書けます。

たとえばバックグラウンド実行だけ確認させたいなら Bash(run_in_background:true) を ask に入れる、という絞り方ができます。

allow は具体的に、param 照合に頼りすぎない

allow には Tool(param:value) が使えません。

つまり「全体として安全」と言い切れる粒度で書く必要があります。

筆者は allow を Bash(npm run lint) のように、コマンド単位まで具体化することを基本にしています。

Bash(npm *) のように広げると、npm の任意のサブコマンドを許すことになるため、何を許したのか後から追いにくくなります。

サブエージェントのモデルや隔離を縛る

Tool(param:value) の追加で、サブエージェント運用の縛り方が増えました。

たとえば次のような使い分けが書けます。

{
  "permissions": {
    "deny": [
      "Agent(model:opus)"
    ],
    "ask": [
      "Agent(isolation:worktree)"
    ]
  }
}

コスト管理の観点で高コストモデルでのサブエージェント起動を deny する、隔離環境の作成は ask で確認する、といった粒度です。

これは委譲スコープを「ツール単位」から「実行条件単位」へ一段細かくできる変化だと受け止めています。

まとめ

permissions のルールは ToolTool(specifier) の2形式で、deny → ask → allow の順に最初のマッチで決まります。

2026年6月に追加された Tool(param:value) は、ツールの入力パラメータで照合する新しい軸です。

ただし allow では使えず、コマンド・パス・URL のフィールドも対象外という制約があります。

許可は具体的に、禁止は条件で軽く書く、という非対称を理解すると、誤許可や抜け穴を作りにくい設計に寄せられます。

最後は概念で終えず、/permissions--verbose で実際の挙動を確認してから採用することをおすすめします。

異論や補足があればコメントで教えていただけるとうれしいです。

参考文献

6
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?