iT邦幫忙

2026 iThome 鐵人賽

DAY 17
0
AI Security

AI Agent 憑什麼動手?30 天拆解 Agent Identity、Delegation 與 Authorization系列 第 17 篇

Day 17|一個 MCP Server 暴露 20 個 Tools,Agent 都能叫嗎?

  • 分享至 

  • xImage
  •  

Core Question

MCP Server 如何避免把連線或 tool listing 的成功誤當成全部 Tool 的授權?

今天的問題

一個客服 Agent 連到 MCP Server,Server 列出 read_ticket、update_ticket、delete_ticket。連線已通過 OAuth,工程師便認為三者都可用。實際上,連線 authentication 只證明 caller 能到達受保護的 MCP resource;它不代表這個 Agent 在本 Task 能刪除任何 ticket。

為什麼這不是傳統 IAM 問題

這是 Agent-specific 的 protocol 邊界問題:模型根據動態 tool list 規劃多步行為,且同一個 session 可能代表不同 User 或 Task。Server 不能把 session 的成功當成所有未來 side effect 的永久 grant。

Threat / Failure Scenario

Alice 只獲准查詢 ticket。MCP Server 仍把三個工具列出,Agent 受 ticket 內容誘導呼叫 delete_ticket。若 server 只驗證 token signature,不驗證 tool name、resource 與 scope,刪除成功。反過來,若只過濾清單,攻擊者可直接送一個手工 JSON-RPC tools/call,繞過 UI 清單。

核心概念

截至 2026-08-14 查核的 MCP 2025-11-25 Authorization 規格指出:HTTP authorization optional;支援時 MCP Server 是 OAuth resource server,必須驗證 token 是發給自己的 resource,且不得接受或轉送其他 token。token scope 不足時可回 403 insufficient_scope。這些是 transport/resource 層要求,不是 per-tool 業務授權的替代品。

tools/list 是 discovery,tools/call 才是 execution。可採三層控制:連線/受眾驗證、清單動態過濾、每次 call 的 operation/resource/task decision。清單過濾降低誤用與模型暴露面,但 execution PEP 必須能拒絕手工 call。

Architecture Pattern

Naive / Unsafe Design

OAuth handshake 成功後把所有 tools 暴露;Server 只驗證 token 的 issuer/signature,或把 client token passthrough 給 downstream API。

Recommended Design

Gateway 驗證 MCP resource audience 與 actor/subject context。tools/list 依 task grant 過濾 read/update/delete;tools/call 再把 tool name、arguments、resource 與資料敏感度送到 PDP。MCP Server 不接受非自身 audience 的 token,也不把 token 原封不動轉送下游;下游使用受限的新 credential 或 server-side identity。

Trust Boundary

MCP Client/Agent、Gateway、MCP Server、PDP、下游 Tool/Resource 各自驗證。tool description 和 tool result 都是可能影響計畫的不可信資料。

Identity Flow

Client 以 canonical MCP Server URI 作 OAuth resource;Server 驗證 access token audience。Gateway 再保留 subject、actor、task_id 和 operation。MCP 規格要求每個 HTTP request 帶 Authorization header,不能把 token 放 query string。

Authorization Decision Point

PDP 對 tools/call(name="delete_ticket", arguments={"id":"T-9"}) 作決策。若 scope 只有 tickets:read,回 403;若 token 無效或 audience 錯誤,回 401。即使 delete_ticket 不在 list,也要對手工 call deny。

https://ithelp.ithome.com.tw/upload/images/20260921/201201513QDrYpYMff.png

小型 PoC

allowed = {"read_ticket"}
listed = [name for name in ["read_ticket", "update_ticket", "delete_ticket"] if name in allowed]

def call(name, token_audience, server_audience):
    if token_audience != server_audience:
        return 401
    if name not in allowed:
        return 403
    return 200

assert listed == ["read_ticket"]
assert call("read_ticket", "mcp://support", "mcp://support") == 200
assert call("delete_ticket", "mcp://support", "mcp://support") == 403
assert call("read_ticket", "mcp://other", "mcp://support") == 401
print("list-filter=ok call-allow=ok call-deny=ok audience-deny=ok")

今天得到什麼

  1. MCP authentication 建立通道,不授予所有 Tool。
  2. tools/list 過濾是 UX/減少暴露面控制,不是唯一 enforcement。
  3. 每個 tools/call 必須重新驗證 operation、resource、Task 與 scope。
  4. MCP Server 必須檢查自己的 audience,禁止 token passthrough。

下一篇

Day 18 進一步問:同一個 read_ticket 到底依固定 Role、動態 Context,還是本次 Task 來決定?

參考資料


上一篇
Day 16|Agent 有 Tool,不代表它有權使用 Tool
下一篇
Day 18|Agent 的權限應該依 Role、Context 還是 Task 決定?
系列文
AI Agent 憑什麼動手?30 天拆解 Agent Identity、Delegation 與 Authorization 共 23 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言