SDK権限

Claude Code SDKは、アプリケーション内でClaudeがツールを使用する方法を管理できる強力な権限制御を提供します。 このガイドでは、canUseToolコールバック、フック、およびsettings.json権限ルールを使用した権限システムの実装方法について説明します。完全なAPIドキュメントについては、TypeScript SDKリファレンスを参照してください。

概要

Claude Code SDKは、ツール使用を制御するための4つの補完的な方法を提供します:
  1. 権限モード - すべてのツールに影響するグローバル権限動作設定
  2. canUseTool コールバック - 他のルールでカバーされていないケースのランタイム権限ハンドラー
  3. フック - カスタムロジックによるすべてのツール実行の細かい制御
  4. 権限ルール (settings.json) - 統合されたbashコマンド解析を持つ宣言的な許可/拒否ルール
各アプローチの使用例:
  • 権限モード - 全体的な権限動作の設定(計画、編集の自動承認、チェックのバイパス)
  • canUseTool - カバーされていないケースの動的承認、ユーザーに権限を求める
  • フック - すべてのツール実行のプログラム的制御
  • 権限ルール - インテリジェントなbashコマンド解析を持つ静的ポリシー

権限フロー図

処理順序: PreToolUse フック → Askルール → Denyルール → 権限モードチェック → Allowルール → canUseTool コールバック → PostToolUse フック

権限モード

権限モードは、Claudeがツールを使用する方法のグローバル制御を提供します。query()を呼び出すときに権限モードを設定するか、ストリーミングセッション中に動的に変更できます。

利用可能なモード

SDKは4つの権限モードをサポートし、それぞれ異なる動作を持ちます:
モード説明ツール動作
default標準権限動作通常の権限チェックが適用される
plan計画モード - 実行なしClaudeは読み取り専用ツールのみ使用可能;実行前に計画を提示 (現在SDKではサポートされていません)
acceptEditsファイル編集の自動承認ファイル編集とファイルシステム操作が自動的に承認される
bypassPermissionsすべての権限チェックをバイパスすべてのツールが権限プロンプトなしで実行される(注意して使用)

権限モードの設定

権限モードは2つの方法で設定できます:

1. 初期設定

クエリ作成時にモードを設定:
import { query } from "@anthropic-ai/claude-code";

const result = await query({
  prompt: "このコードのリファクタリングを手伝って",
  options: {
    permissionMode: 'default'  // 標準権限モード
  }
});

2. 動的モード変更(ストリーミングのみ)

ストリーミングセッション中にモードを変更:
import { query } from "@anthropic-ai/claude-code";

// ストリーミング入力用の非同期ジェネレーターを作成
async function* streamInput() {
  yield { 
    type: 'user',
    message: { 
      role: 'user', 
      content: "デフォルト権限で始めましょう" 
    }
  };
  
  // 会話の後で...
  yield {
    type: 'user',
    message: {
      role: 'user',
      content: "今度は開発を速めましょう"
    }
  };
}

const q = query({
  prompt: streamInput(),
  options: {
    permissionMode: 'default'  // デフォルトモードで開始
  }
});

// モードを動的に変更
await q.setPermissionMode('acceptEdits');

// メッセージを処理
for await (const message of q) {
  console.log(message);
}

モード固有の動作

編集承認モード (acceptEdits)

編集承認モードでは:
  • すべてのファイル編集が自動的に承認される
  • ファイルシステム操作(mkdir、touch、rm等)が自動承認される
  • 他のツールは通常の権限が必要
  • Claudeの編集を信頼する場合の開発速度向上
  • 迅速なプロトタイピングと反復に有用
自動承認される操作:
  • ファイル編集(Edit、MultiEdit、Writeツール)
  • Bashファイルシステムコマンド(mkdir、touch、rm、mv、cp)
  • ファイル作成と削除

権限バイパスモード (bypassPermissions)

権限バイパスモードでは:
  • すべてのツール使用が自動的に承認される
  • 権限プロンプトが表示されない
  • フックは依然として実行される(操作をブロック可能)
  • 極めて注意して使用 - Claudeがシステムへの完全アクセスを持つ
  • 制御された環境でのみ推奨

権限フローでのモード優先度

権限モードは権限フローの特定のポイントで評価されます:
  1. フックが最初に実行 - 任意のモードをオーバーライド可能
  2. 拒否ルールがチェック - モードに関係なくツールをブロック
  3. bypassPermissionsモード - アクティブな場合、残りのすべてのツールを許可
  4. 許可ルールがチェック
  5. その他のモードが特定のツール動作に影響
  6. canUseToolコールバック - 残りのケースを処理
これは以下を意味します:
  • フックはbypassPermissionsモードでもツール使用を常にブロック可能
  • 明示的な拒否ルールはすべての権限モードをオーバーライド
  • bypassPermissionsモードは許可ルールとcanUseToolをオーバーライド

ベストプラクティス

  1. デフォルトモードを使用 通常の権限チェックによる制御された実行のため
  2. acceptEditsモードを使用 分離されたファイルやディレクトリで作業する場合
  3. bypassPermissionsを避ける 本番環境や機密データを持つシステムでは
  4. モードとフックを組み合わせる 細かい制御のため
  5. モードを動的に切り替える タスクの進行と信頼度に基づいて
モード進行の例:
// 制御された実行のためデフォルトモードで開始
permissionMode: 'default'

// 迅速な反復のためacceptEditsに切り替え
await q.setPermissionMode('acceptEdits')

canUseTool

canUseToolコールバックはquery関数を呼び出すときにオプションとして渡されます。ツール名と入力パラメータを受け取り、許可または拒否の決定を返す必要があります。 canUseToolは、Claude Codeがユーザーに権限プロンプトを表示する場合に発火します。例えば、フックと権限ルールがそれをカバーしておらず、自動承認モードでない場合です。 インタラクティブなツール承認の実装方法を示す完全な例:
import { query } from "@anthropic-ai/claude-code";

async function promptForToolApproval(toolName: string, input: any) {
  console.log("\n🔧 ツールリクエスト:");
  console.log(`   ツール: ${toolName}`);
  
  // ツールパラメータを表示
  if (input && Object.keys(input).length > 0) {
    console.log("   パラメータ:");
    for (const [key, value] of Object.entries(input)) {
      let displayValue = value;
      if (typeof value === 'string' && value.length > 100) {
        displayValue = value.substring(0, 100) + "...";
      } else if (typeof value === 'object') {
        displayValue = JSON.stringify(value, null, 2);
      }
      console.log(`     ${key}: ${displayValue}`);
    }
  }
  
  // ユーザー承認を取得(UIロジックに置き換えてください)
  const approved = await getUserApproval();
  
  if (approved) {
    console.log("   ✅ 承認\n");
    return {
      behavior: "allow",
      updatedInput: input
    };
  } else {
    console.log("   ❌ 拒否\n");
    return {
      behavior: "deny",
      message: "ユーザーがこのツールの権限を拒否しました"
    };
  }
}

// 権限コールバックを使用
const result = await query({
  prompt: "このコードベースの分析を手伝って",
  options: {
    canUseTool: async (toolName, input) => {
      return promptForToolApproval(toolName, input);
    }
  }
});

ツール制御のためのフックの使用

フックは、さまざまな段階でツール実行のプログラム的制御を提供します。フックはすべてのツール使用に対して呼び出され、権限パイプラインの完全な制御を提供します。

フック実装

import { query } from "@anthropic-ai/claude-code";

const result = await query({
  prompt: "このコードのリファクタリングを手伝って",
  options: {
    hooks: {
      PreToolUse: [{
        hooks: [async (input, toolUseId, { signal }) => {
          console.log(`ツールリクエスト: ${input.tool_name}`);
          
          // ツール入力を自分で解析・検証
          if (input.tool_name === "Bash") {
            const command = input.tool_input.command;
            if (command.startsWith("rm -rf")) {
              return {
                decision: "block",
                reason: "危険なコマンドがブロックされました"
              };
            }
          }
          
          return { continue: true };
        }]
      }],
      PostToolUse: [{
        hooks: [async (input, toolUseId, { signal }) => {
          console.log(`ツール完了: ${input.tool_name}`);
          // ツール結果をログまたは監査
          return { continue: true };
        }]
      }]
    }
  }
});

canUseToolとの主な違い

  • スコープ: フックはすべてのツール使用に対して呼び出される;canUseToolは権限ルールでカバーされていないケースを処理
  • 制御: フックは入力の解析と検証を自分で行う必要がある
  • イベント: フックは異なる段階で複数のイベント(PreToolUse、PostToolUse等)をサポート

権限ルール(settings.json)の使用

settings.jsonの権限ルールは、組み込みのbashコマンド解析を持つ宣言的制御を提供します。これらのルールはcanUseToolが呼び出される前に評価されます。設定の詳細については、Claude Code設定ドキュメントを参照してください。

設定構造

{
  "permissions": {
    "allow": [
      "Bash(npm run lint)",
      "Bash(npm run test:*)",
      "Read(~/.zshrc)"
    ],
    "deny": [
      "Bash(curl:*)",
      "Read(./.env)",
      "Read(./secrets/**)",
      "WebFetch"
    ],
    "ask": [
      "Bash(git push:*)",
      "Write(./production/**)"
    ]
  }
}

ルール構文

権限ルールはToolName(pattern)のパターンに従います
  • Bashルール: プレフィックスマッチングを使用(正規表現ではない)。例:Bash(npm:*)は「npm」で始まる任意のコマンドにマッチ
  • ファイルルール: globパターンをサポート。例:Read(./src/**/*.ts)はsrc内のTypeScriptファイルにマッチ
  • ツールのみルール: 括弧を省略してツール全体を制御。例:WebFetchはすべてのWeb取得をブロック

SDKでの使用

SDKではルールをプログラム的に設定することはま だできませんが、SDKが読み込まれるパスのsettings.jsonファイルから読み取られます。

権限評価順序

  1. 拒否ルールが最初にチェック - マッチした場合、ツール使用がブロック
  2. 許可ルールが次にチェック - マッチした場合、ツール使用が許可
  3. 問い合わせルールがチェック - マッチした場合、ユーザーにプロンプト
  4. canUseToolコールバックが残りのケースに対して呼び出される

Bashコマンド解析

SDKには、コマンド構造を理解する統合bashパーサーが含まれています:
  • パイプ、リダイレクト、コマンド置換を処理
  • rm -rfcurl | shなどの危険なパターンを認識
  • ワイルドカードとプレフィックスマッチングをサポート
bashパターンの動作例:
  • Bash(git:*) - 任意のgitコマンドにマッチ
  • Bash(npm run test) - 正確なコマンドにマッチ
  • Bash(npm run test:*) - npm run test:unit、test:integration等にマッチ

ベストプラクティス

  1. デフォルトモードで開始 標準権限チェックのため
  2. 権限ルールを使用 静的ポリシー、特にbashコマンドのため(権限設定を参照)
  3. フックを使用 すべてのツール使用のログ、監査、変換のため(フックタイプを参照)
  4. canUseToolを使用 カバーされていないケースの動的決定のため(CanUseToolタイプを参照)
  5. 防御を重層化 重要なアプリケーションでは、モード、ルール、フック、コールバックを組み合わせる