Day 23 的工具都是自己定義的函式,參數 schema 已知、回傳格式受控。MCP(Model Context Protocol)改變了這件事:agent 連上一個 MCP server,server 告訴 agent 它有哪些工具、每個工具的描述、參數 schema——這些全部是 server 說的,而 server 可能是第三方的。
這帶來三個 Day 23 沒有的攻擊面:
這是 ASI04(Agentic Supply Chain)的具體樣子,Day 1 標為「不覆蓋」——護欄擋不住你選了一個惡意 server。但連上之後的內容流,護欄還是有事可做。
Agent ──(1) tools/list ──▶ MCP server
◀── tool descriptions ──┘ ← 攔截點 A:描述掃描
Agent ──(2) tools/call(args) ──▶ MCP server ← 攔截點 B:參數(同 Day 23)
◀── result content ───────┘ ← 攔截點 C:回傳(同 Day 23,逐欄位)
攔截點 B、C 是 Day 23 的延伸。A 是新的:tools/list 回來的每一個工具描述,在進入模型 context 前先過 input rails,並且快照存檔——下次 tools/list 回來如果描述變了,觸發告警(rug pull 偵測)。
Model Armor 對 MCP 流量的防護,最乾淨的接法是把 MCP 流量也導過閘道:Apigee 可以作為 MCP proxy,在 proxy 上對 tools/list 的回應與 tools/call 的請求/回應套用 Day 14 的 policy。ADK 端則用 Day 23 的 callback,加上一個 tools/list 後的描述掃描。
# agent/mcp_guard.py
async def load_mcp_tools(session):
tools = await session.list_tools()
snapshot = load_snapshot(session.server_id)
for t in tools:
if ma.sanitize_prompt(t.description).blocked:
raise GuardBlocked(f"mcp_tool_description:{t.name}")
if snapshot and snapshot.get(t.name) != hash_desc(t):
alert(f"MCP tool description changed: {session.server_id}/{t.name}")
save_snapshot(session.server_id, tools)
return tools
同樣的三個攔截點,在 LiteLLM 閘道旁多一個 MCP proxy 容器:agent 不直接連 MCP server,連 proxy;proxy 做描述掃描、快照比對、參數與回傳的 L1/L2 掃描,再轉發。
Agent ──▶ mcp-proxy ──▶ 第三方 MCP server
│
├─ tools/list:描述掃描 + 快照比對
├─ tools/call:參數 L1 範圍 + L2 語意
└─ result:逐欄位 L1/L2,灰色地帶送 L3
這些不是護欄能解決的,但接 MCP 時一定要做,否則護欄是在幫一個已經淪陷的環境擦屁股:
Day 25:驗證方法論。Week 4 後半轉進驗證:PINT、JailbreakBench 的正確跑法、常見的陷阱(用訓練過的資料考自己、只報攔截率不報誤判、拿 safety 成績證明 security),以及對抗性改寫下攔截率會掉多少。
Instagram @aid3fend。
更多 AI 資安筆記:aid3fend.com