Claude Code をチームに入れるとき、最初の関門になるのが権限設計です。何でも自動承認すれば速いけれど、rm -rf や本番への git push --force まで素通りさせるわけにはいきません。逆に毎回の操作で許可を求められると、エージェントの速度という最大の価値が削られます。

この記事では、Claude Code の権限モデル (allow / ask / deny) と settings.json の構成を、個人開発とチーム運用の両面から整理します。危険な操作は確実に止めつつ、安全な操作はプロンプトなしで通す。その境界をどこに引くかが設計の勘所です。FIXIT が実際のプロジェクトで詰めてきた判断基準を中心にまとめます。

権限モデルの全体像 — allow / ask / deny

Claude Code は、エージェントがツール (Bash・Edit・Write・WebFetch・MCP ツールなど) を呼び出すたびに、その操作を許可するかどうかを評価します。判定は 3 つのバケットで決まります。

  • allow に一致する操作は、確認なしで実行される
  • deny に一致する操作は、必ずブロックされる
  • ask に一致する操作は、その都度ユーザーに確認を求める
  • どれにも一致しない操作は、デフォルトのモード次第で ask 相当の挙動になる

優先順位は deny が最も強く、次に ask、最後に allow という順で評価されると考えておくと安全です。つまり「Bash 全般は許可したいが rm を含むものだけは止めたい」という場合、allow に広いルールを入れつつ deny に狭い例外を入れれば、deny が勝って意図どおりブロックされます。

ルールは「ツール名」と「引数のパターン」で書きます。たとえば Bash(npm run test:*) は npm のテストコマンド系を、Read(./src/**)src 配下の読み取りを表します。コロンの後の * は引数のプレフィックスマッチで、Bash(git diff:*) なら git diff で始まる任意のコマンドにマッチします。この粒度をどこまで細かくするかが、後述する allowlist 設計の中心になります。

権限まわりはこまめにブロックを差し込むより、危険なものを deny で確実に止め、安全圏を allow で広げ、判断に迷うものを ask に残すという三層構造で考えると破綻しません。

settings.json と settings.local.json の役割分担

Claude Code の設定は、複数のファイルが階層的にマージされます。実務で押さえておくべきは次の 3 つです。

  • ~/.claude/settings.json — ユーザー個人のグローバル設定。全プロジェクトに効く
  • <project>/.claude/settings.json — プロジェクト共有設定。リポジトリにコミットしてチームで共有する
  • <project>/.claude/settings.local.json — プロジェクト内の個人設定。.gitignore に入れてコミットしない

この 3 階層の使い分けが、チーム運用の土台になります。チーム全員に効かせたいルール (危険コマンドの deny や、プロジェクト共通の安全なコマンドの allow) はプロジェクト共有の settings.json に書いてコミットします。一方、個人の好みやマシン固有の事情で増やしたい許可は settings.local.json に置き、リポジトリを汚さないようにします。

// <project>/.claude/settings.local.json は必ず gitignore する
// .gitignore
.claude/settings.local.json

settings.local.json をコミットしてしまうと、各自が好き勝手に追加した allow が共有設定に混ざり、「誰がいつ何を許可したのか」が追えなくなります。これはガバナンス上の事故につながりやすいので、リポジトリ作成時点で .gitignore に入れておくのが安全です。マージの考え方としては、より広いスコープ (グローバル) を土台に、狭いスコープ (プロジェクト → ローカル) が上書き・追加していくイメージで捉えておくと混乱しません。

最初に deny / ask に入れるべきコマンド

新しいプロジェクトで真っ先にやるべきは、allow を増やすことではなく deny を固めることです。許可は後から足せますが、事故は取り返しがつきません。FIXIT で最初に入れることが多いのは次のあたりです。

// <project>/.claude/settings.json
{
  "permissions": {
    "deny": [
      "Bash(rm -rf:*)",
      "Bash(git push --force:*)",
      "Bash(git push -f:*)",
      "Bash(git reset --hard:*)",
      "Bash(:*curl*| sh*)",
      "Bash(:*| bash*)",
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./**/secrets/**)",
    ],
    "ask": [
      "Bash(git push:*)",
      "Bash(npm publish:*)",
      "Bash(gh pr merge:*)",
      "Bash(docker:*)",
    ],
  },
}

ポイントは 2 つあります。まず、deny には「復旧コストが極端に高い操作」と「秘密情報の読み取り」を入れます。.env や認証情報を含むファイルをエージェントに読ませない設定は、プロンプトインジェクションや意図しない情報漏洩への一次防御になります。パイプで外部スクリプトを実行する curl ... | sh 系も、サプライチェーン的なリスクが高いので止めておきます。

次に、ask には「実行してもよいが、人の意思決定を挟みたい操作」を入れます。本番への push、パッケージ公開、PR のマージなどは、エージェントが勝手に進めるべきではない一線です。deny ですべて塞ぐと開発フローが止まるけれど、無条件 allow は怖い。こういう操作は ask がちょうどよい着地点です。

deny のパターンは、シェルの裏道を意識して書くのがコツです。rm -rf を止めても find ... -delete は別物ですし、引数の順序を変えれば回避できることもあります。deny は万能ではないと理解した上で、致命的なものから優先的に塞ぐという姿勢が現実的です。深いガードが必要なら、後述のように hooks の PreToolUse を併用します。

プロジェクト共有設定とローカル設定の分け方

権限を「どこに書くか」は、その許可が誰にとって安全かで判断します。判断軸はシンプルで、チーム全員にとって安全だと言い切れるものだけを共有設定 (settings.json) に入れる、というものです。

共有設定に向くのは、プロジェクト固有で副作用がなく、誰が実行しても結果が同じになる操作です。

// <project>/.claude/settings.json
{
  "permissions": {
    "allow": [
      "Bash(npm run lint:*)",
      "Bash(npm run test:*)",
      "Bash(npm run build:*)",
      "Bash(npx tsc --noEmit:*)",
      "Read(./src/**)",
      "Read(./content/**)",
      "Bash(git status:*)",
      "Bash(git diff:*)",
      "Bash(git log:*)",
    ],
  },
}

lint・テスト・型チェック・ビルド・read 系・git の参照系は、何度実行しても破壊的な副作用がありません。これらをプロジェクト共有設定に入れておけば、チーム全員が同じ快適さで使えますし、レビューを通してコミットされるので変更履歴も残ります。

逆に、個人のマシンにしかないツールへのパスや、検証中で安全性を確信できていない許可は settings.local.json に置きます。「自分は使うけれど、他の人に押し付けるべきか分からない」許可は、まずローカルで運用し、チームで合意が取れたら共有設定へ昇格させる。この二段階の運用が、共有設定を安全に保ちながら個人の生産性も落とさないバランスになります。

設定ファイルの初期構築や、リポジトリに置く CLAUDE.md との連携については Claude Code の導入ガイド でも触れています。権限設定は CLAUDE.md と並んで、プロジェクトをチームで運用する際の土台になる部分です。

MCP ツールの権限を絞る設計

MCP (Model Context Protocol) サーバーを接続すると、Slack 投稿・データベース参照・外部 API 呼び出しなど、Bash 以外の強力なツールがエージェントから使えるようになります。便利な反面、ここが権限設計の盲点になりやすいところです。

MCP ツールの権限は mcp__<サーバー名>__<ツール名> の形式で指定します。考え方の基本は、参照系は allow、書き込み・送信・削除系は askdeny です。

// 例: backlog 系 MCP の権限を絞る
{
  "permissions": {
    "allow": [
      "mcp__backlog__get_issue",
      "mcp__backlog__get_issues",
      "mcp__backlog__get_pull_request",
    ],
    "ask": ["mcp__backlog__add_issue_comment", "mcp__backlog__update_issue"],
    "deny": ["mcp__backlog__delete_issue", "mcp__backlog__delete_project"],
  },
}

読み取り系を allow に入れておけば、エージェントは課題やコードの状況を自由に把握できます。一方でコメント投稿・ステータス更新といった外部に影響が出る操作は ask に残し、プロジェクトやデータの削除は deny で塞ぎます。MCP サーバーは提供するツール数が多いので、ワイルドカードで一括許可せず、ツール単位で意図的に許可していく方が安全です。とくに本番データベースや外部への送信を伴うサーバーは、最初は全ツール ask から始めて、安全と確認できたものだけ allow に移すくらいの慎重さがちょうどよいと考えています。

権限プロンプトを減らす allowlist の作り方

denyask を固めたら、次は逆方向の最適化、つまり「安全なのに毎回聞かれる操作」を allow に取り込んで、権限プロンプトを減らしていきます。これがエージェントの速度を取り戻す作業です。

実践的なやり方は、いきなり網羅的な allowlist を書こうとしないことです。まず最小限の allow で運用を始め、頻繁に確認を求められる操作をログとして眺めます。Claude Code は確認を求めるたびに、その操作を allow に追加するか尋ねてくれるので、安全だと判断できるものをその場で許可していけば、自然と allowlist が育ちます。

allowlist を太らせるときの判断基準は一貫して「べき等で副作用がないか」です。

  • 何度実行しても状態が変わらない参照系・チェック系か
  • 失敗しても簡単に元に戻せるか
  • ネットワーク越しに外部へ影響を与えないか

この 3 つを満たすものは積極的に allow へ。一方で、引数によって破壊的にも安全にもなる git のようなコマンドは、Bash(git:*) のような広すぎる許可を避け、Bash(git status:*) Bash(git diff:*) のようにサブコマンド単位で絞ります。広い許可は楽ですが、その分だけ事故の窓口も広がります。

許可だけでは防ぎきれない深いガード (たとえば引数を解析して特定パターンだけ止める、コミット前に必ずテストを走らせる) が必要になったら、hooks の出番です。PreToolUse でコマンドを検査してブロックする、PostToolUse で自動フォーマットをかけるといった制御は権限設定では書けないため、Claude Code の hooks 実用パターン で扱うような仕組みと組み合わせると、安全と速度の両立がぐっと現実的になります。権限設定が「何を許すか」のフィルタなら、hooks は「許した上でどう振る舞わせるか」の制御だと整理すると分かりやすいはずです。

チーム導入時のガバナンスと監査の観点

個人で使う分には権限設定は好みの問題ですが、チームで使うとガバナンスの問題になります。誰が何を許可したのか、危険な許可が紛れ込んでいないかを、組織として把握できる状態を保つ必要があります。

実務で効くポイントを整理します。共有の settings.json は必ずレビューを通してマージする、という運用を徹底するのが 1 つ目です。権限の追加は通常のコード変更と同じく PR で行い、allowdeny の差分を人の目で確認します。これだけで「いつの間にか危ない許可が入っていた」という事故の大半は防げます。

2 つ目は、settings.local.json を確実に .gitignore に入れること。前述のとおり、個人設定がリポジトリに混ざると監査が成立しなくなります。

3 つ目は、組織全体に効かせたい禁止事項をマネージド設定で管理することです。Claude Code はシステム管理者が配布するマネージドポリシー (managed settings) を持ち、これは個人やプロジェクトの設定では上書きできません。本番環境への破壊的操作や、秘密情報へのアクセス禁止といった「組織として絶対に譲れない deny」は、ここに置くことで全員に強制できます。プロジェクト設定は緩めても、組織のガードレールは外れない、という二層構造を作れるわけです。

最後に、権限設計は一度書いて終わりではなく、運用しながら育てるものだと捉えてください。新しいツールを導入したら deny を見直し、繰り返し聞かれる安全な操作は allow に取り込む。この継続的なメンテナンスを回せるかどうかが、チームで Claude Code を安全かつ高速に使い続けられるかの分かれ目になります。組織横断でこのガードレールを設計・運用する体制づくりは、FIXIT の AI 開発ツール導入支援 でも重点的に扱っている領域です。

まとめ

Claude Code の権限設計は、deny で致命的な操作を確実に止め、ask で意思決定を挟みたい操作を残し、allow で安全圏を広げる三層構造で考えると破綻しません。設定は settings.json (チーム共有) と settings.local.json (個人・gitignore) に役割を分け、MCP ツールは参照系と書き込み系で扱いを変える。そして共有設定は PR レビューで管理し、組織の禁止事項はマネージド設定で強制する。この設計が、安全性と生産性を両立させる土台になります。

危険を止めつつ速度を落とさない設定は、最初の一手を間違えなければ後からいくらでも育てられます。まずは deny を固めるところから始めてみてください。

Claude Code・Cursor の権限設計やチーム導入のガバナンスでお困りでしたら、FIXIT の AI 開発ツール導入支援サービスをご覧ください。→ /services/ai-dev-tool-adoption/