摘要: Cloudflare 更新 Cloudflare One 與 Gateway,用協定指紋和 logs 辨識 MCP 流量,讓企業能看見哪些 agent、server 與方法正在被呼叫。文章區分未核准的 shadow MCP 和已核准但繞過 Portal 的直接連線,並建議先取得能見度、再 onboarding、最後 enforcement。Zero Trust 客戶已可用 experimental.is_mcp selector 進行允許或封鎖。
企業在規劃資源權限時,預設的對象是人。資深工程師之所以能拿到部署 production、查詢敏感資料庫、撤銷他人存取權這類特權,靠的是兩個心照不宣的前提:他懂得在關鍵時刻用判斷力喊停,而且無論如何都快不過人類的速度。AI agent 一登場,這兩個前提同時失效——它的決策帶有 nondeterministic 性質,同一個工具呼叫還能反覆執行到無限次,既不會疲倦,也不需要停下來吃午餐。於是一個看似合理、實際錯誤的決定,可能在還沒有任何人注意到之前,就已經滾成上千個錯誤行動。
更棘手的地方在於:這類流量其實一直待在企業網路內部,只是從外表上完全看不出特徵。
接上一行設定就能用,犯錯的擴散速度也一樣快
要讓 agent 連上一個 MCP server,一行設定就夠了。員工自己就能把 Claude Code、Codex、Cursor、OpenCode、VS Code 或任何 AI harness 指向某個資安團隊沒核准過的 MCP server,中間沒有人需要簽核。MCP 的價值在於替 agent 提供一套統一介面,用來探索並呼叫藏在第三方 SaaS、內部應用與 API 後面的工具;但這份價值同時也是治理的缺口:真正被改變的並非權限本身,而是「每個決定由誰做出」,以及一個壞決定能以多快的速度向外擴散。
傳統權限模型背後的假設是:犯錯的人會遲疑、會停手。Agent 沒有這種反應。這也是為什麼過去圍繞「人」打造的 RBAC 設計,到了 agent 時代必須另外拉出一條截然不同的防線。
MCP 流量在外觀上沒有特徵,單看 URL 認不出來
資安團隊最直覺的反應是用 URL 做過濾,偏偏 MCP 既沒有固定保證的 hostname 慣例,路徑裡也不一定要出現 /mcp。一條 direct connection 在網路上的樣子,跟尋常的 HTTPS API call 並無二致,只盯著目的地根本得不到任何線索。
但協定本身其實留下了指紋。MCP 規範定義了若干識別欄位,會隨著每一個請求一併送出:
POST /mcp HTTP/1.1
Host: tools.example.com
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: get_weather
除了這些 headers,body 的部分是一則 JSON-RPC 2.0 訊息。hostname 與路徑負責指出目的地,而上述 protocol signals 則透露「這是一隻 agent 正在呼叫工具」。同一筆 MCP 請求,在 client 內部的身分是一個帶參數的工具呼叫決策,放到網路上是一則 HTTP 交易,抵達 server 之後又變成一次可能讀取資料、改動狀態的 handler 執行——三種形態,對應三個潛在控制點。
三個控制點之中,網路層為何最務實
理論上,安全團隊有三個可以出手的位置。第一個位於 MCP client 內部,但它取決於各個 harness 怎麼實作,要跨工具標準化並不容易。第二個落在裝置的網路邊界,麻煩在於 local VPN 能看到的只有單一裝置的流量,公司無法強制在每一台機器上部署。第三個則在 MCP server 真正呼叫工具之前,然而那已經是最後一跳,credential 早就跨網送出去了。
三個位置都存在各自的破口,最後的答案卻一致指向企業的網路層——那裡是不管使用者選了哪一種 client、流量要前往哪一個 server,都一定得經過的共同攔截面。
Cloudflare 的處理方式:讓流量先被看見
Cloudflare 這次的更新聚焦在 Cloudflare One 與 Gateway 上。目前這個階段,Gateway logs 已可藉由 hostname、path 以及 JSON-RPC 的 heuristics,從 inspected traffic 裡撈出疑似 MCP 的流量;下一步 HTTP policies 會納入 mcp_protocol_version、mcp_method、mcp_name 這三個 protocol selectors(發文當下為即將 GA,尚未正式上線),有了它們就能訂出「只有在 mcp_name 落於核可清單內時,才放行 tools/call」之類的規則。再配合 Cloudflare One dashboard 提供的 telemetry,管理員能看清楚哪些身分呼叫了哪些 server、各種 method 的呼叫量有多少,以及哪些目的地是繞過 portal 進來的。
這裡有一個很容易被混為一談的區別:shadow MCP 指的是 agent 連上一個從頭到尾都未被核准的 server;approved-path bypass 則是原本該走治理路徑的流量,直接連去 origin。面對前者要用的手段是 onboarding——把確實有需求的 server 收編進治理軌道;面對後者要用的則是 enforcement——把 direct route 封掉。兩件事混在一起處理,常見的下場就是全面封鎖,反而逼得使用者繞更遠的路。
此外,Cloudflare Zero Trust 的所有客戶現在都能在 Gateway HTTP logs 裡看到 MCP 流量的標記,並且透過一個新的 selector 明確決定封鎖或放行這類流量:
experimental.is_mcp == true
這個 selector 的型態是 boolean:當 Gateway 在經過 TLS 解密的請求裡偵測到 MCP-Protocol-Version header,它的值就會是 true,可以直接寫進 Allow 或 Block 政策,不需要自行維護一份「看起來像 MCP」的網域清單。
Portal 模式:把核准、稽核與強制串成一條線
MCP Server Portals 的作法,是替每一個核准的 MCP server 在 Cloudflare 網路上配一個 hostname,並附帶 access controls、logging 與 audit,agent 從此改走 portal,而不是直連。一旦發現 shadow server,可以直接把它 onboard 成 governed access,不必從零重建。實際情境往往長這樣:資安團隊先在 Gateway logs 裡注意到某個部門的 agent 長期直連某個第三方工具的 MCP server;確認用途正當之後,將它註冊進 portal、掛上存取政策與稽核,隔天流量就改走治理路徑,原本的影子風險轉為可管理的存取。portals 以往要求 OAuth,如今支援更多 server 認證方式,內部工具不需要 re-architecture 就能一併納入同一套治理;就算是躲在 private network 後面的 MCP server,也能透過 Cloudflare Tunnel 以同一種 portal 模式發布,取得相同的 policy 與 audit。Gateway policy 還能進一步要求 MCP 流量只准走 portal hostname——即使 agent 手上握有合法 credential,直連 origin 一樣會被封鎖。對應的 baseline 封鎖規則如下:
experimental.is_mcp == true and not traffic.onramp in ("mcp_portal")
Action: Block
凡是沒有經由 portal 進來的 MCP 流量都會被攔下,走 portal 的流量則完全不受影響;對於想先觀察一段時間再開始強制的團隊,也可以選擇只在 HTTP logs 裡持續監看,暫時不急著推出政策。
搭配的措施還涵蓋 Cloudflare Agents SDK 對新版 stateless MCP server model 的支援:一個 Worker 就能夠服務 tool calls,不必維持 long-lived sessions,在 Workers 環境下更容易擴展。
治理團隊的部署順序建議
這套能力適合依序上線,而不是一次全部打開。第一步是打開 visibility:先讓 Gateway logs 的 heuristics 跑上一兩週,觀察網路裡究竟有哪些 MCP 流量、由誰產生、流向何處。第二步進行 onboarding:把使用頻率高又屬正當的 server 收進 portal,讓使用者有一條合法的路可以走。第三步才輪到 enforcement:等 selectors GA 之後,再封鎖那些不經 portal 的直連路徑。
把順序顛倒過來的代價很具體——在合法路徑還不存在時就先行封鎖,agent 使用者只會轉向更隱蔽的出口,你反而丟掉剛剛才取得的 visibility。治理的關注焦點已經從「誰有權按下按鈕」移向「流量走的是哪條路」,而這條路必須先被建立出來,之後才談強制。
