WriteGuard:MCP 寫入控管與使用場景
這篇指南可以協助你為團隊的 AI Agent 建立一道安全防線:在保留 Agent 自動化效率的同時,防止它們誤刪資料、亂發信件或在 GitLab 任意合併程式碼。你可以利用 Cloudflare 研發的 WriteGuard 機制,在免修改既有 MCP server 程式碼的前提下,對 Agent 的寫入行為進行風險分級控管、加上身分標籤並同步記錄稽核追蹤軌跡。[1][2]
問題
當 AI Agent 開始具備調用工具(Tool Call)的能力,能存取 Jira、GitLab 或 Wiki 時,其產生的外部副作用(Side Effects)便帶來了顯著風險。[1]
主要問題在於:
- 難以識別的 Agent 行為:當工程師授權 Agent 操作系統時,下游系統通常只看得到該使用者的帳號(例如 Joe)。如果 Agent 寫了不良 Prompt 導致背景大量關閉 Ticket,事後稽核日誌只會顯示是 Joe 關閉的,團隊無法區分哪些是人手操作、哪些是 Agent 的失控行為。[1]
- 缺乏細粒度的寫入管控:AI 應用端內建的確認提示(Confirm Prompt)容易被使用者關閉或繞過。[1] 如果直接開放寫入權限,Agent 可能會執行高風險動作,例如將程式碼合併至正式環境或向客戶大量發送郵件。[1]
- 安全邊界的劃分與管理需求:
- 哪些 MCP 寫入需要管:所有會對下游系統狀態造成不可逆改變的動作(例如:GitLab 中的
merge_mr、部署觸發;Jira 中的大量關閉與刪除 Ticket;郵件/Slack 中的外部寄信與大量發訊;資料庫中的drop_table或 DML 異動)都必須受控。單純的唯讀動作(如get_merge_request)風險較低,可以直接放行。[1] - 哪些邊界由 Access/OAuth 處理:Cloudflare Access 與 OAuth 負責身分驗證與粗粒度的端點授權。Access 驗證「是誰在調用(例如 Joe)」,OAuth 則將該請求對應到下游系統(如 GitLab)的權限。如果 Joe 本身沒有 GitLab 合併權限,OAuth 自然會阻擋。然而,如果 Joe 擁有該權限,Access/OAuth 無法阻止 Agent 代替 Joe 執行不當的合併。這正是 WriteGuard 需要介入的微觀工具層級控制。[1][3]
原理
WriteGuard 作為政策、歸因與稽核層,接在 MCP server portal 上,包覆既有的 MCP server,無須重構或修改工具原始碼。[2][3]
當 Agent 發送工具呼叫(Tool Call)時,WriteGuard 會依據管理員設定的工具風險層級(Risk Level),引導請求走入三種處理路徑之一:[1]
- 放行 (Allow):通常適用於 Read Only 工具。呼叫直接送達 MCP server handler。[1]
- 放行並標註 (Allow with labeling):適用於受控寫入(Contained Write)。在寫入下游系統時,於指定欄位附加 Agent 歸因標籤(如標示特定 Client 與 Session),並非同步寫入已去敏感化的稽核日誌。[1][2]
- 擋下 (Block):針對高風險(Critical)或停用的工具,在 handler 執行前即刻阻擋,並將嘗試紀錄寫入稽核日誌。[1]
flowchart TB
A["Agent / MCP Client"] --> I["Access + OAuth identity"]
I --> W["MCP Portal + WriteGuard"]
W --> D{"Tool risk level"}
D -->|Read Only| M["MCP server handler"]
D -->|Contained Write| L["加入 Agent 標籤"]
L --> M
D -->|Critical / disabled| B["執行前阻擋"]
M --> S["下游系統"]
L --> U["Central audit log"]
B --> U
WriteGuard 的核心功能包含四項主要能力:[2]
- Agentic identity:將每次工具呼叫連結至特定的 Agent、Client 與 Session,並疊加於 Access 驗證的身分之上。
- Deny-by-default gating:寫入工具預設為關閉狀態,必須明確授權方可開啟。
- Visible labels:在目標系統的變更內容中,顯示明確的 Agent 標籤。
- Central audit:所有連接至 portal 的 MCP server,均共享一份中央稽核日誌。
Cloudflare 內部 portal 在 2026-04 接 13 台 MCP server,查核時寫的是 27 台,而且一開始全是唯讀。[1]
每個工具都有風險層級、開關、標籤設定。層級決定能不能執行,也決定稽核時的查核標準:[1]
| 風險層級 | 官方例子 | 工具例子 |
|---|---|---|
| Read Only | 搜尋 issue、讀 MR、看 pipeline | get_merge_request |
| Minimal Impact | 加 reaction、標已讀、訂閱 issue | — |
| Contained Write | 留言、開 MR、改 issue 欄位 | create_mr_note |
| Critical | 合併 MR、觸發正式部署、大量刪除 | merge_mr |
操作
團隊若要導入此機制,可以分為兩個主要階段:設定 MCP Portal 與配置 Client 連線。[3]
1. 團隊如何建立與連接 MCP Portal
前置條件為帳號內需有作用中的 Domain,且 Zero Trust 已與身分提供商(IdP)對接。[3]
新增 MCP Server 的步驟如下:[3]
- 登入 Cloudflare dashboard,導航至 Zero Trust → Access controls → AI controls。
- 啟用 MCP servers,並點選 Add an MCP server。
- 輸入名稱與可選的 Server ID。
- 在 HTTP URL 欄位輸入 MCP server 的完整位址(例如
https://docs.mcp.cloudflare.com/mcp)。 - 設定 Access 政策以限制可存取該 server 的人員。
- 點選 Save and connect server。若 server 支援 OAuth,需使用管理員帳號完成授權。
建立 Portal 的步驟如下:[3]
- 在同一頁面點選 Add MCP server portal。
- 輸入 Portal 名稱。
- 在 Custom domain 選擇帳號內的 Zone,亦可指定 Subdomain。
- 將前述設定的 MCP server 加進 Portal。
- 視需求關閉不希望暴露的 Tools 或 Prompts。
- 設定 Require user auth(預設為開啟,要求使用者以個人身分登入;關閉則使用 Admin 憑證)。
- 設定 Access 政策以限制可連線至 Portal URL 的人員。
- 點選 Add an MCP server portal。
使用者連線的終端點位址為:
https://<subdomain>.<domain>/mcp
請透過瀏覽器開啟首頁 https://<subdomain>.<domain>/ 進行登入。若直接以瀏覽器存取 /mcp 路徑,會因缺乏 MCP Client Token 而收到 invalid token 錯誤。[3]
2. 透過 Allowlist 預先關閉不當工具
Portal 預設會啟用 Server 上的所有 tools/prompts。管理員可透過配置 allowlist,在 server-to-portal mapping 中設定 default_disabled: true,並在 updated_tools 中明確啟用特定工具:[3]
{
"servers": [
{
"id": "example-server",
"default_disabled": true,
"updated_tools": [
{ "name": "search_documents", "enabled": true },
{ "name": "list_projects", "enabled": true }
]
}
]
}
3. 設定 Client 連線
- 本機 Client 設定:官方建議使用
mcp-remote@latest封裝連線,以確保 Session 順利建立。例如在 Claude Desktop 或 OpenCode 的config.json中配置:[3]
{
"mcpServers": {
"company-portal": {
"command": "npx",
"args": [
"-y",
"mcp-remote@latest",
"https://<subdomain>.<domain>/mcp"
]
}
}
}
- Playground 測試:
- 開啟 Workers AI Playground。[3]
- 於 MCP Servers 輸入
https://<subdomain>.<domain>/mcp並點選 Connect。[3] - 透過彈出視窗完成 Access 登入,並對需 OAuth 的上游 server 完成授權。[3]
- 機器對機器連線:使用 Access service token,並在標頭加入
CF-Access-Client-Id與CF-Access-Client-Secret。此時 Portal 與上游 Server 皆須配置 Service Auth 政策,且該 Server 的 Require user auth 必須關閉。[3]
4. 申請 WriteGuard beta
公開文件(2026-08-12 更新的 MCP Portal 頁)尚未包含 WriteGuard 設定欄位。3] 團隊可至 [WriteGuard closed beta 進行申請,未來幾個月將逐步對更多客戶開放。[2]
驗證
我們以 GitLab MCP server 的整合應用為例,驗證同一個使用者身分在執行三種不同動作時的行為差異:[1]
const sendEmailTool = {
tool: EmailMCP.sendEmailTool,
writeGuard: {
riskLevel: RiskLevel.CONTAINED_WRITE,
enabled: true,
labeling: {
field: "body",
supportedFormats: [
LabelFormat.PLAIN_TEXT,
LabelFormat.HTML,
],
},
},
};
上述程式碼展示了郵件工具的 WriteGuard 政策配置,其中 labeling.field 指定標籤寫入的欄位,supportedFormats 則用以相容下游應用的格式要求。[1]
依據上述原則,GitLab 工具的執行結果如下:
- 讀取 MR:Agent 呼叫
get_merge_request。WriteGuard 判定為READ_ONLY,直接放行。[1] - 在 MR 留言:Agent 呼叫
create_mr_note。此為CONTAINED_WRITE,WriteGuard 會在留言欄位中插入 Agent 歸因標籤,隨後將呼叫送至 handler,並非同步記錄一筆已清除敏感資訊的審計日誌。[1] - 合併程式碼:Agent 嘗試呼叫
merge_mr。由於該操作被歸類為CRITICAL且未被啟用,WriteGuard 會在 handler 執行前直接阻擋該請求,並將此嘗試記錄至審計日誌中。[1]
限制
- 服務狀態:截至 2026-08-15 查核,WriteGuard 仍處於 Private Beta 階段,尚未正式 GA。[1][2]
- 文件與介面限制:目前公開的 MCP Portal 文件中尚未包含 WriteGuard 的設定欄位,且 Beta 版本的設定畫面未在本次評估中進行帳號核對。[3]
- 權限與邊界限制:WriteGuard 的控制點建立在使用者已擁有的權限之上。如果使用者本身不具備某項操作的權限(例如無法關閉 Ticket),Agent 也無法執行該操作。WriteGuard 無法逾越 Access 與 OAuth 的底層身分防線,它僅能在使用者權限之內,針對 Agent 代替人執行的行為進行限縮與追蹤。[1]
- 旁路風險:若使用者繞過 Portal 直接連接上游 MCP server,將無法套用 WriteGuard 政策。官方建議將 Access 設為該 server 的唯一 OAuth 提供商以強制要求經由 Portal 轉發。[3]
- 稽核欄位限制:為保護敏感資訊,非同步稽核日誌會過濾掉 sensitive payload,因此可能無法提供完整的參數值。[1]
Sources
[1] https://blog.cloudflare.com/mcp-portal-writeguard-private-beta — WriteGuard: Fine-grained controls for MCP Servers [2] https://www.cloudflare.com/resource/writeguard-beta-landing-page — WriteGuard closed beta [3] https://developers.cloudflare.com/cloudflare-one/access-controls/ai-controls/mcp-portals — MCP server portals [4] https://developers.cloudflare.com/agents/model-context-protocol — Cloudflare Agents MCP docs
先把邊界講清楚,工具才能變成可靠流程。
Signals
Visits
--
Waiting for Cloudflare metrics.