factsClaude Codepermissions

stable4 日前 · 2026-08-09

Configure permissions

概要

Claude Code が何にアクセスし何をできるかを、ルール・モード・managed policy で細かく制御する仕組み。permission 設定はバージョン管理にチェックインして組織で共有でき、開発者ごとに個別調整もできる。

仕様

権限の階層

ツール種別承認の要否「Yes, don't ask again」の効果
Read-only(ファイル読み取り、Grep)作業ディレクトリと追加ディレクトリ内では不要該当なし
Bash コマンド組み込みの read-only コマンド集合を除き必要リポジトリとコマンドごとに恒久保存
ファイル変更(Edit / Write)必要セッション終了まで
  • 恒久保存される承認(Bash コマンドなど)は、git リポジトリルートの .claude/settings.local.json に保存される。worktree はメインの checkout に解決される。そのリポジトリ内のどこで始めたセッション(サブディレクトリや worktree を含む)にも適用される
  • git リポジトリ外、およびリポジトリルートがホームディレクトリの場合は、起動したディレクトリに保存される
  • v2.1.211 より前は常に起動ディレクトリに保存されていた
  • Bash / PowerShell の permission prompt で Ctrl+E を押すと、コマンドの説明(何をするか、なぜ実行するか、何が起こりうるか)が Low risk / Med risk / High risk のラベル付きで表示される。押したときにだけモデルへ送られる。表示しても実行はされない。もう一度押すと隠れる
  • このショートカットを切るには ~/.claude.jsonpermissionExplainerEnabledfalse にする

ルールの種類と評価順

  • Allow: 手動承認なしでツールを使える

  • Ask: 使おうとするたびに確認を求める

  • Deny: 使用を禁止する

  • 評価順は deny → ask → allow。この順で最初に一致したものが結果を決め、ルールの具体度は順序を変えない

  • Bash(aws *) のような広い deny ルールは、より狭い allow ルール Bash(aws s3 ls) に一致する呼び出しもブロックする。ask と allow の間も同様

  • 素のツール名(Bash)の deny ルールはツール自体を Claude のコンテキストから取り除く。ただし EndConversation は例外で、他のツールが残っている限り deny で取り除けず、ask でもプロンプトを出さない

  • Bash(rm *) のようなスコープ付きルールはツールを残し、一致する呼び出しをブロックする

  • permission ルールは Claude Code が強制するものであり、モデルが強制するものではない。プロンプトや CLAUDE.md の指示は Claude が何を試みるかを形作るが、Claude Code が何を許すかは変えない

  • /permissions で全ルールと、それぞれの出所となる settings.json を確認・管理できる

ルール構文

  • 形式は Tool または Tool(specifier)
  • 括弧なしのツール名はそのツールのすべての使用に一致する。Bash(*)Bash と等価

入力パラメータによる一致

  • deny と ask ルールは Tool(param:value) で任意のツールのトップレベル入力パラメータに一致できる(例: Agent(model:opus)Agent(isolation:worktree)Bash(run_in_background:true)
  • allow ルールはこの形式を使わず、各ツール固有の specifier 構文を使う
  • パラメータ名はツール入力の直接のフィールドでなければならない。オブジェクトや配列の中にネストしたフィールドは対象外
  • 1 ルールにつき 1 パラメータ。2 つを条件にするならルールを 2 つ書く
  • 値では * が任意の文字列にマッチする。* が無ければ完全一致
  • モデルが省略したパラメータには決して一致しない(Agent(model:*)model 未設定の呼び出しに一致しない)
  • 値は正規化前の Claude が送るリテラル入力と比較される。Agent(model:opus) はエイリアス opus に一致するが完全なモデル ID には一致しない
  • コロン前後の空白は無視される
  • ツールの主要コンテンツフィールドはこの方法で指定できない(Bash / PowerShell の command、Read / Edit / Write の file_path、Grep / Glob の path、NotebookEdit の notebook_path、WebFetch の url)。Bash(command:rm *) のようなルールは無視され起動時に警告が出る

ツール名のワイルドカード

  • deny と ask ルールはツール名の位置に glob を受け付ける。パターンはツール名全体に一致する必要がある。"*" は全ツール、"mcp__*" は全サーバーの全 MCP ツールに一致する
  • allow ルールは、リテラルの mcp__<server>__ 接頭辞の後にのみ glob を受け付ける。サーバー部分に glob は使えない。mcp__puppeteer__*mcp__github__get_* は有効。"*" / "B*" / "mcp__*" のような anchor されない allow glob は警告付きでスキップされ何も自動承認しない
  • 既知のツールに一致しない deny / ask ルールは起動時に警告が出る。_* を含むツール名はこのチェックの対象外
  • トランスクリプトや permission ダイアログのラベルは正規名と異なることがある(例: Stop Task の正規名は TaskStop)。permission ルールと hook matcher は正規名にのみ一致する

Bash ルール

  • * によるワイルドカードは先頭・中間・末尾のどこでも使える
  • 単一の * はスペースを含む任意の文字列に一致するため、1 つのワイルドカードが複数の引数にまたがる
  • 末尾のスペース付き *Bash(ls *))は語境界を強制し、接頭辞の後にスペースか文字列終端が必要。Bash(ls *)ls -la に一致するが lsof には一致しない。Bash(ls*) は両方に一致する
  • :* 接尾辞は末尾ワイルドカードと等価。Bash(ls:*)Bash(ls *) と同じ。:* はパターン末尾でのみ認識され、Bash(git:* push) のコロンはリテラル扱い
  • permission ダイアログで「Yes, don't ask again」を選ぶとスペース区切り形式が書かれる

複合コマンド

  • 認識される区切りは &&||;||&&、改行。ルールは各サブコマンドに独立して一致する必要がある
  • 複合コマンドを「Yes, don't ask again」で承認すると、承認が必要な各サブコマンドごとに別々のルールが保存される。サブディレクトリへの cd はそのパスの Read ルールを生成する。1 つの複合コマンドで最大 5 つのルールが保存される

ラッパー

  • Bash ルールの照合前に固定のラッパー集合が取り除かれる: timeouttimenicenohupstdbuf、シェル組み込みの commandbuiltin、zsh の noglob。クエリ形式の command -v と zsh の nocorrect は取り除かれない
  • 既知の安全な環境変数の先頭代入も取り除かれる(Bash(npm test *)NODE_ENV=test npm test に一致する)。それ以外の変数代入を越えて allow ルールは一致しない。deny / ask ルールは任意の先頭代入を越えて一致する
  • フラグ無しの xargs も取り除かれる。xargs -n1 grep pattern のようにフラグがある場合は xargs コマンドとして照合される
  • このラッパー一覧は組み込みで設定できない。direnv execdevbox runmise execnpxdocker exec などの環境ランナーは含まれない。Bash(devbox run *)run の後に来るもの(devbox run rm -rf . を含む)に一致してしまうため、Bash(devbox run npm test) のようにランナーと内側のコマンドを両方含む具体的なルールを書く
  • watchsetsidioniceflock のような exec ラッパーは常にプロンプトを出し、Bash(watch *) のような接頭辞ルールで自動承認できない。-exec-delete 付きの find も同様

read-only コマンド

  • 組み込みで read-only と認識され、すべてのモードでプロンプトなしに実行されるコマンド: lscatechopwdheadtailgrepfindwcwhichdiffstatducd、および git の read-only 形式など
  • この集合は設定できない。プロンプトを要求するには ask または deny ルールを追加する
  • すべてのフラグが read-only のコマンドでは引用符なしの glob が許される(ls *.tswc -l src/*.py

それでもプロンプトが出る場合:

  • 書き込み可能フラグを持つコマンドでの引用符なし glob: findsortsedgit など。glob が -delete のようなフラグに展開されうるため
  • 別 daemon を指す docker: -H--context、Podman の --url / --connection などのフラグがある場合
  • パスを開くフラグ付きの file: -m/--magic-file-f/--files-from
  • Windows のネットワークパス: \\server\share\file のような UNC パスを引数に含むコマンド。PowerShell ツールにも同じチェックが適用される
  • 解析できないコマンド: 完全に解析できない場合は承認を求める。10,000 文字を超えるコマンドは常にプロンプトを出す
  • 作業ディレクトリまたは追加ディレクトリ内への cd も read-only。cd packages/api && ls のような複合コマンドも各部分が単独で条件を満たせばプロンプトなしで動く
    • cdgit の組み合わせ: cd が別ディレクトリへ移動する場合はプロンプトを出す(新しいディレクトリで git を実行するとそのディレクトリの hook が動きうるため)。現在の作業ディレクトリに解決される cd は no-op でプロンプトを出さない
    • cd と出力リダイレクトの組み合わせ: cd 後にリダイレクト先がどのディレクトリに解決されるか判定できない場合はプロンプトを出す。リダイレクト先が /dev/null のみの場合は出さない

PowerShell ルール

  • Bash ルールと同じ形。* は任意位置、:* 接尾辞は末尾 * と等価、素の PowerShell / PowerShell(*) は全コマンドに一致
  • 一般的なエイリアスは照合前に正規化される。PowerShell(Get-ChildItem *)gcilsdir にも一致する。照合は大小文字を区別しない
  • PowerShell の AST を解析し、複合コマンドの各コマンドを独立に確認する。|;、PowerShell 7+ では &&|| がサブコマンドに分割する

Read と Edit ルール

  • Edit ルールはファイルを編集するすべての組み込みツールに適用される
  • Read ルールは Grep や Glob などファイルを読む組み込みツール、プロンプト内の @file メンション、接続した IDE が共有する選択範囲・開いているファイルのコンテキストにも best-effort で適用される
  • Read の deny ルールは同じパスに対する Edit ツール(新規ファイル作成を含む)もブロックする。Write と NotebookEdit は対象外なので、どのツールも変更してはならないパスには Edit の deny ルールを追加する。v2.1.208 以降
  • ファイル権限は Edit(path)Read(path) ルールに対してのみ照合される。Write / NotebookEdit / Glob / 旧 MultiEdit にパスルールを書いても参照されず、起動時に警告が出る(--allowedTools で渡した Glob ルールを除く)。v2.1.210 以降
  • Read と Edit の deny ルールは Claude の組み込みファイルツールと、Claude Code が認識する Bash のファイルコマンド(catheadtailsed など)に適用される。ファイルを自分で開く Python や Node のスクリプトのような任意のサブプロセスには適用されない。OS レベルで全プロセスをブロックするには sandbox を有効にする

パターンの種類(gitignore 構文):

パターン意味
//pathファイルシステムルートからの絶対パスRead(//Users/alice/secrets/**)
~/pathホームディレクトリからのパスRead(~/Documents/*.pdf)
/pathsettings のソースからの相対パスEdit(/src/**/*.ts)
path または ./path現在のディレクトリからの相対パスRead(*.env)
  • /Users/alice/file は絶対パスではない。先頭の 1 つのスラッシュは settings のソースに anchor する

/path の解決先:

ルールの定義場所/path の解決先
Project settings .claude/settings.json<project root>/path
Local settings .claude/settings.local.json<original cwd>/path
User settings ~/.claude/settings.json~/.claude/path
--settings <file> で渡したファイル<directory of file>/path
CLI フラグ、/permissions、セッションルール<original cwd>/path
  • Windows ではパスは照合前に POSIX 形式に正規化される。C:\Users\alice/c/Users/alice になるため、そのドライブ上の .env を対象にするには //c/**/.env、全ドライブなら //**/.env
  • 素のファイル名は gitignore のセマンティクスに従い任意の深さに一致する。Read(.env)Read(**/.env) は等価
  • 単一ディレクトリセグメントの相対パターンは、ルール種別で一致する深さが変わる
    • allow ルール: Edit(src/**)<cwd>/src とその配下のみに一致する。任意の深さを許可するには Edit(**/src/**)
    • deny / ask ルール: Read(secrets/**) は現在のディレクトリ配下の任意の深さの secrets ディレクトリに一致する
  • それ以外のパターン形状はどのルール種別でも同じ深さに一致する
  • 「Yes, don't ask again」でファイルパスを承認すると、そのパス内の gitignore パターン文字([]*)がエスケープされ、承認したリテラルパスにのみ一致するルールが生成される。自分で書いたルールはエスケープされない。v2.1.202 より前は未エスケープで保存されていた

symlink の扱い:

  • allow ルール: symlink のパスとその解決先の両方が一致するときのみ適用される。許可されたディレクトリ内の、外を指す symlink はプロンプトを出す
  • deny ルール: symlink のパスまたは解決先のいずれかが一致すれば適用される

WebFetch ルール

  • domain: 接頭辞を使い、リクエスト URL のホスト名に照合する。大小文字を区別せず、* ワイルドカードに対応し、ルールとホスト名の末尾の . を取り除く
  • WebFetch(domain:example.com)example.com に一致する
  • WebFetch(domain:*.example.com) は任意の深さのサブドメイン(api.example.coma.b.example.com)に一致するが example.com 自体には一致しない
  • WebFetch(domain:*) は全ドメインに一致し、素の WebFetch ルールと等価
  • 先頭の *. と素の * 以外の位置では、ワイルドカードは 2 つのドットの間のテキストにのみ一致する。WebFetch(domain:example.*)example.org に一致するが example.evil.com には一致しない

MCP ルール

  • mcp__puppeteerpuppeteer サーバーの任意のツールに一致する
  • mcp__puppeteer__* も同サーバーの全ツールに一致する
  • mcp__puppeteer__puppeteer_navigate は特定ツールに一致する
  • 組織が claude.ai connector のツールを ask に設定している場合、そのツールの allow ルールは効かず、autobypassPermissions モードでも毎回プロンプトが出る。dontAsk モードでは拒否される。connector ツールは mcp__claude_ai_<server>__<tool> として現れる

Agent(subagent)ルール

  • Agent(Explore)Agent(Plan)Agent(my-custom-agent) の形で、Claude が使える subagent を制御する
  • 無効化するには settings の deny 配列に追加するか --disallowedTools を使う

Cd ルール

  • /cd コマンドがセッションを移動できるディレクトリを制御する。Cd はモデルが呼べるツールではなく、ユーザーが /cd を実行したときにのみ適用される
  • 素の Cd deny ルールは /cd を完全に無効化する。Cd(<path-pattern>) deny ルールは一致する移動先をブロックする。deny ルールは symlink の各ホップを含め、移動先のあらゆる綴りを確認する
  • Cd の allow ルールを 1 つでも追加すると /cd は allowlist モードになり、解決後の移動先が allow ルールのいずれかに一致しなければ拒否される
  • Cd ルールが無い場合、/cd は既定の挙動(未知のディレクトリの trust を尋ねる)を保つ
  • パスパターンは Read / Edit の //~// の anchor を共有するが、照合は gitignore 形式ではなくディレクトリパス全体に anchor される。* はちょうど 1 セグメント、** は複数セグメントに一致する。末尾の /** は名前付きルート自体にも一致する
ルール一致する一致しない
Cd(~/code/*)~/code/app~/code/app/src, ~/code
Cd(~/code/**)~/code とその配下の任意のディレクトリ~/code の外
Cd(**/node_modules)任意の深さの node_modulesnode_modules/pkg

hook による拡張

  • PreToolUse hook は permission prompt の前に走る(EndConversation を除く全ツール)。hook 出力はツール呼び出しを拒否する、プロンプトを強制する、プロンプトを飛ばして進める、のいずれかができる
  • hook の判断は permission ルールを迂回しない。deny と ask ルールは hook の戻り値に関わらず評価される。組織が ask に設定した connector ツールと requiresUserInteraction の MCP ツールも、hook が "allow" を返してもプロンプトを出す
  • 終了コード 2 で終わるブロッキング hook は permission ルールの評価前にツール呼び出しを止めるため、allow ルールがあってもブロックが優先される

作業ディレクトリ

  • 既定では起動したディレクトリのファイルにアクセスできる
  • 拡張方法: 起動時の --add-dir <path>、セッション中の /add-dir、settings の additionalDirectories
  • 追加ディレクトリのファイルは元の作業ディレクトリと同じ permission ルールに従う
  • セッションの主作業ディレクトリ自体を変えるには /cd を使う(v2.1.169 以降)

追加ディレクトリは設定のルートにはならない

--add-dir フラグまたは /add-dir で追加したディレクトリからのみ、次の例外が読み込まれる。settings の permissions.additionalDirectories に列挙したディレクトリはファイルアクセスのみを与え、以下の設定は読み込まない。

設定--add-dir から読み込まれるか
.claude/skills/ の Skills読み込む(ライブリロードあり)
.claude/agents/ の Subagents読み込む
.claude/settings.json / .claude/settings.local.jsonenabledPluginsextraKnownMarketplaces キーのみ
CLAUDE.md、.claude/rules/CLAUDE.local.mdCLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 のときのみ。CLAUDE.local.md はさらに local の setting source が必要(既定で有効)
  • コマンドと output style は、現在の作業ディレクトリとその親、~/.claude/、managed settings から発見される
  • hooks とその他の .claude/settings.json のキーは、現在の作業ディレクトリの .claude/ から読み込まれ、親ディレクトリへのフォールバックは無い(加えて user の ~/.claude/settings.json と managed settings)
  • .claude/settings.local.json は git リポジトリルートから読み込まれる(サブディレクトリで起動しても同じ)。v2.1.211 より前は現在の作業ディレクトリのみだった。Agent SDK セッションは全バージョンで作業ディレクトリから読む

sandboxing との関係

  • Permissions: どのツールを使えるか、どのファイル・ドメインにアクセスできるかを制御する。全ツールに適用される
  • Sandboxing: OS レベルで Bash ツールのファイルシステム・ネットワークアクセスを制限する。Bash コマンドとその子プロセスにのみ適用される
  • sandbox のファイルシステム制限は sandbox.filesystem 設定と Read / Edit の deny ルールを統合して最終的な境界にする
  • ネットワーク制限は WebFetch の permission ルールと sandbox の allowedDomains / deniedDomains を統合する
  • sandboxing を有効にし autoAllowBashIfSandboxed を既定の true のままにすると、素の Bash ask ルール(および Bash(*))があってもサンドボックス化された Bash コマンドはプロンプトなしで動く
  • plan mode ではこの置き換えは行われない。v2.1.212 より前は plan mode でも置き換えが適用されていた
  • なお次のチェックは引き続き適用される: Bash(git push *) のような content-scoped な ask ルール、明示的な deny ルール、/・ホームディレクトリ・その他の重要システムパスを対象とする rm / rmdir(auto mode では classifier チェック。classifier への routing は v2.1.218 以降)

managed settings

管理者が配布する設定で、settings reference の precedence の例外を除き user / project settings で上書きできない。

managed settings からのみ読まれる設定:

設定説明
allowAllClaudeAiMcpstrue のとき、配布した managed-mcp.json の排他制御で抑止せず claude.ai connector も読み込む
allowedChannelPluginsメッセージを push できる channel plugin の allowlist。設定すると既定の Anthropic allowlist を置き換える。channelsEnabled: true が必要
allowManagedHooksOnlytrue のとき、managed hooks、SDK hooks、managed settings の enabledPlugins で強制有効化した plugin の hooks のみを読み込む
allowManagedMcpServersOnlytrue のとき、managed settings の allowedMcpServers のみを尊重する。deniedMcpServers は全ソースからマージされる
allowManagedPermissionRulesOnlytrue のとき、user / project settings が allow / ask / deny ルールを定義できなくなる
blockedMarketplacesmarketplace ソースの blocklist。ダウンロード前に確認されるためファイルシステムに触れない
channelsEnabled組織で channels を許可する
disableSideloadFlags起動時に --plugin-dir / --plugin-url / --agents / --mcp-config を拒否する。v2.1.193 以降
forceRemoteSettingsRefreshtrue のとき、リモートの managed settings を取得し終えるまで CLI 起動をブロックし、取得失敗時は終了する
pluginTrustMessageインストール前の plugin trust 警告に追記するカスタムメッセージ
sandbox.filesystem.allowManagedReadPathsOnlytrue のとき、managed settings の filesystem.allowRead のみを尊重する。denyRead は全ソースからマージされる
sandbox.network.allowManagedDomainsOnlytrue のとき、managed settings の allowedDomainsWebFetch(domain:...) allow ルールのみを尊重する。許可されないドメインはプロンプトなしで自動ブロックされる
strictKnownMarketplacesユーザーが追加・インストールできる plugin marketplace ソースを制御する
strictPluginOnlyCustomizationskills / agents / hooks / MCP サーバーを user・project ソースから禁止し、plugin か managed settings 由来のみにする。true で 4 つすべて、["skills", "hooks"] のような配列で指定分のみ
wslInheritsWindowsSettingsWindows の HKLM レジストリキーまたは C:\Program Files\ClaudeCode\managed-settings.jsontrue のとき、WSL が /etc/claude-code に加えて Windows のポリシーチェーンから managed settings を読む
  • disableBypassPermissionsMode は通常 managed settings に置くが、どのスコープでも機能する
  • bypassPermissionsauto の使用を防ぐには、いずれかの settings ファイルで permissions.disableBypassPermissionsMode / permissions.disableAutoMode"disable" にする

precedence

  • permission ルールは他の設定と同じ settings precedence に従い、managed settings が最上位。コマンドライン引数を含め他のレベルは managed の permission ルールを上書きできない
  • どのレベルであれ deny されたツールは、他のレベルで allow できない
  • user settings が allow、project settings が deny の場合は deny が勝つ。逆も同様(deny はどのスコープからでも allow より先に評価されるため)

project の allow ルールと workspace trust

  • project の .claude/settings.jsonpermissions.allowpermissions.additionalDirectories は capability を与えるため、そのワークスペースの workspace trust ダイアログを承認した後にのみ適用される。それまでルールは読まれるが適用されない
  • trust ダイアログは、そのフォルダが与える allow ルールと追加ディレクトリを一覧表示する
  • denyask ルールは制限のみなので影響を受けない
  • trust はワークスペース単位で保存され、キーは git リポジトリルート(リポジトリ外では起動ディレクトリ)。ホームディレクトリで起動した場合は現在のセッション限りでディスクに書かれない。親ディレクトリを信頼してもネストしたプロジェクトの allow ルールは適用されない
  • .claude/settings.local.json は自分のファイルなので通常 trust チェックの対象外。ただしリポジトリが供給しえた場合(git にコミットされている、.claude が symlink など)は project settings と同様に trust チェックを通る
  • 次の 2 つの場合は workspace trust なしでも .claude/settings.local.json の allow ルールと追加ディレクトリが適用される
    • 起動したディレクトリが git リポジトリの中でない
    • セッションが自分の設定ホーム(ホームディレクトリ、または CLAUDE_CONFIG_DIR.claude サブディレクトリを設定したディレクトリ)で動いている
  • v2.1.200 以降、親ディレクトリが既に信頼済みで trust ダイアログを一度も表示していないワークスペースでは、次に対話起動したときにダイアログが表示される。選択肢は Yes, I trust this folder(trust を保存し同一セッションでルールを適用)と No, continue without these permissions(ルールを無視して継続、次セッションで再表示)
  • -p の非対話モードではダイアログは出ず、ルールは無視されたままになる

設定

{
  "permissions": {
    "allow": [
      "Bash(npm run *)",
      "Bash(git commit *)",
      "Bash(git * main)",
      "Bash(* --version)",
      "Bash(* --help *)"
    ],
    "deny": [
      "Bash(git push *)"
    ]
  }
}
{
  "permissions": {
    "allow": [
      "PowerShell(Get-ChildItem *)",
      "PowerShell(git commit *)"
    ],
    "deny": [
      "PowerShell(Remove-Item *)"
    ]
  }
}
{
  "permissions": {
    "deny": ["mcp__*", "Agent(Explore)"]
  }
}

制約・注意点

  • コマンド引数を制約しようとする Bash の permission パターンは壊れやすい。Bash(curl http://github.com/ *) は、URL 前のオプション、別プロトコル、リダイレクト、変数展開、余分な空白などの変種に一致しない
    • より確実な URL フィルタリング: deny ルールで curl / wget などをブロックし、許可ドメインには WebFetch(domain:github.com) を使う / PreToolUse hook で URL を検証する / CLAUDE.md に記述する(強制力は無いので他と併用する)
    • WebFetch を使うだけではネットワークアクセスを防げない。Bash が許可されていれば curl などで任意の URL に到達できる

関連

  • facts/claude-code/permission-modes.md
  • facts/claude-code/settings.md
  • facts/claude-code/sandboxing.md
  • facts/claude-code/hooks.md
  • facts/claude-code/mcp.md
  • facts/claude-code/sub-agents.md
  • facts/claude-code/tools-reference.md
  • facts/claude-code/security.md
  • facts/claude-code/commands.md
  • facts/claude-code/worktrees.md