Dekita

承認設定の「default」、書き忘れたツールが承認なしで動いていた話

生成AI 日本語 AIエージェント セキュリティ

はじめに

Microsoft Agent Framework の Python 版(以下 Agent Framework)でローカルの MCP サーバーをつなぐ人向けの話です。ツールごとに承認を分けて運用する場合に、確認しておくとよい挙動です。

2026 年 10 月 30 日公開の 1.24.0 で、MCP ツールの承認設定に default という項目が加わりました。どちらのリストにも名前を書いていないツールの扱いが気になり、手元の環境で 5 条件を実際に走らせて確認しました。

この記事が答えるのは、日本の現場で「許可リストに無い操作は、デフォルトで承認を要する」と規程に書いた場合、Agent Framework の既定値がその規程と一致するのか、という問いです。結論から言うと、default を書かない限り一致しませんでした。

背景:default が加わったこと

Agent Framework の MCPStdioTool などのツールは、approval_mode に承認の条件を渡します。1.24.0 までの条件は2つだけでした。always_require_approval は常に承認を要するツールの名前、never_require_approval は承認を不要とするツールの名前です。

どちらのリストにも名前が出てこないツールの扱いが、1.24.0 で明文化されました。1.24.0 以前は、2つのリストに名前が出てこないツールは、追加の設定なしで承認を要しないまま動いていました。追加された default は "always_require" か "never_require" のどちらかをとり、None なら未設定という意味です。

確認した構成

MCP サーバーは Python で用意し、ツールは3つにしました。

読み取り系2つと削除系1つの組み合わせです。MCPStdioTool で接続し、接続後に生成される各関数の approval_mode の値を出力しました。承認の設定だけを 5 通りに変えます。

結果:B では削除ツールも承認なしでした

実測結果です。環境は Windows、Python 3.13、agent-framework-core 1.24.0、mcp 2.3.0、tenacity です。

| 条件 | delete_note の判定 | 備考 | |---|---|---| | A | 承認なし | 未指定の既定 | | B | 承認なし | FutureWarning が出る | | C | 承認が必要 | default が効いた | | D | 承認が必要 | always が命中 | | E | 承認が必要 | always が never より優先 |

条件 B は「読み取りは自動で通し、ほかは確認する」という意図に見えます。しかし、どちらのリストにも名前がない delete_note は承認なしで通りました。動作そのものは変わらず、出るのは FutureWarning だけです。

判定順

PR の説明と実測を合わせると、判定順は次の通りです。

  1. always_require_approval に名前が一致したら「承認が必要」
  2. いなければ never_require_approval を見て、一致したら「承認を不要」
  3. いなければ default の値を使う
  4. default がないなら「承認を不要」

E が always と never の両方に入っていても「承認が必要」になるのは、1 が先に判定されるためです。この順は、PR #9828 の実装コードと本稿の実測の両方で一致しました。

直し方:default を明示する

規程に「許可リストに無いツールは、承認を要する」とある場合、フレームワーク側でも同じ既定を揃えます。

approval_mode={
    "never_require_approval": ["read_note", "search_notes"],
    "default": "always_require",
}

こうすれば、設定時に挙げなかったツール、あるいは接続後に追加されたツールでも、名を挙げない限り承認が必要になります。default を "never_require" にすれば、「always に書いたツールのみ承認が必要」になります。

規程との差し替え

規程に「許可リストに無いツールは、承認を要する」と書いておきながら、コード側が既定で承認なしなら、規程が現実を守りません。差を埋めるには、次に書く2点を揃えます。

これらはコード1行と規程1行の差ですが、監査のときに見られるのは両方の一致です。片方だけ揃えても、確認した記録が残らない限り「揃った」状態にはなりません。

確認できていないこと

次の点は、今回の実測の範囲外です。

まとめ

never_require_approval に読み取り系だけを書いて「ほかは確認する」という設定は、1.24.0 の時点で想定と異なる挙動です。名前のないツールは承認なしで通ります。規程が「デフォルト拒否」なら、default を "always_require" で明示してください。

参考情報