09 · Channel 與安全:誰能進來、能做什麼
從 OpenClaw 官方安全模型出發,拆清 Channel 路由、DM 配對、群組門控、工具許可權、沙箱和 Gateway 暴露。
OpenClaw 的安全問題不能只問“模型聰不聰明”。真正要問的是三件事:
誰能觸發 Agent?Agent 能呼叫哪些工具?這些工具在哪裡執行?
這三件事分別落在 Channel access、Tool policy、Sandbox / Elevated 上。系統提示詞和 prompt injection 防禦只能降低風險,不能替代這些硬邊界。
這一篇的核心判斷:安全邊界不在模型嘴上,而在 Gateway 入口、Session 隔離、Tool policy、Sandbox 和網路暴露面上。
flowchart LR
Sender["外部傳送者"] --> Access["Channel access<br/>誰能進來"]
Access --> Route["Routing<br/>進哪個 Agent"]
Route --> Context["Session / Context<br/>看到哪些上下文"]
Context --> Policy["Tool policy<br/>能呼叫哪些工具"]
Policy --> Sandbox["Sandbox / Elevated<br/>在哪裡執行"]
Sandbox --> Host["Gateway host<br/>真實資源"]
style Access fill:#fef3c7,stroke:#f59e0b,stroke-width:2px
style Route fill:#dbeafe,stroke:#3b82f6,stroke-width:2px
style Context fill:#dbeafe,stroke:#3b82f6,stroke-width:2px
style Policy fill:#dcfce7,stroke:#22c55e,stroke-width:2px
style Sandbox fill:#fee2e2,stroke:#ef4444,stroke-width:2px
style Host fill:#f3f4f6,stroke:#6b7280,stroke-width:2px
1. 官方安全模型:先定 trust boundary
OpenClaw 官方安全文件明確把預設模型定義為個人助理部署:一個 Gateway 對應一個可信 operator boundary,可以有多個 Agent,但不把同一個 Gateway 當成多個敵對租戶之間的強隔離邊界。
這句話要先理解:一個 shared gateway 不適合承載互不信任的敵對使用者。
如果你要讓陌生人、客戶、外部使用者共享一個能跑工具的 Agent,不應該只靠 prompt 或 allowlist。更穩妥的拆法是:
- Gateway 控制面:分 Gateway。
- 憑據和 channel token:分 credentials。
- OS 級資源:分 OS user、host 或 VPS。
- 工具執行能力:每個 Agent 只拿自己需要的 sandbox 和 tool policy。
如果多個不可信使用者能給同一個 tool-enabled Agent 發訊息,官方建議把他們視為共享了這個 Agent 的 delegated tool authority。也就是說:他們不是彼此隔離的安全主體。
shared Gateway 可以是個人助理系統,不應該被誤當成強多租戶隔離平臺。
2. Channel 只負責訊息入口和迴路
Channel 是訊息入口抽象。Telegram、WhatsApp、Discord、Slack、Signal、iMessage、LINE、IRC、Google Chat 以及擴充套件渠道進來的訊息,會被 Gateway 標準化,再進入 Agent。
但不要誤解為“模型自己決定發回哪裡”。官方 Channel Routing 文件說得很清楚:
回覆回到原訊息來源;模型不選擇 channel;路由由 host configuration 決定。
幾個關鍵詞:
Channel:訊息平臺,例如 telegram、whatsapp、discord、slack;安全上看平臺入口是否允許。AccountId:同一 channel 下的賬號例項;安全上看多賬號預設賬號是否明確。AgentId:獨立 workspace + session store;安全上看訊息最終進哪個 Agent。SessionKey:上下文桶;安全上看是否串上下文、是否影響工具執行姿態。
多賬號場景要設定明確預設賬號,例如 channels.telegram.defaultAccount 或 accounts.default。否則 fallback routing 可能拿到第一個 normalized account id,這在安全審計裡很難解釋。
3. 路由是確定性的,不是模型猜的
OpenClaw 選擇 Agent 的順序是確定規則:
| 優先順序 | 匹配規則 | 用途 |
|---|---|---|
| 1 | Exact peer match | 精確傳送者或會話繫結 |
| 2 | Parent peer match | thread inheritance |
| 3 | Discord guild + roles match | Discord 角色分流 |
| 4 | Discord guild match | Discord 伺服器分流 |
| 5 | Slack team match | Slack team 分流 |
| 6 | Account match | 同一平臺多賬號分流 |
| 7 | Channel match | 按平臺預設分流 |
| 8 | Default agent | 兜底 Agent |
Session key 形態也由來源決定:
- Direct DM:
agent:agentId:mainKey。 - Group:
agent:agentId:channel:group:id。 - Room/channel:
agent:agentId:channel:channel:id。 - Slack thread:base key 後追加
thread:threadId。 - Telegram topic:group key 內包含
topic:topicId。
注意:DM 預設可能落入 main session,但外部 DM 的 sandbox 和 tool policy 會使用派生 runtime key,不會被當成本地 main-session run 處理。這個細節是為了避免“外部渠道訊息看起來像本機主會話”的安全錯覺。
路由確定性是安全資產。能解釋一條訊息為什麼進某個 Agent,後續才談得上審計和收緊。
4. DM access:pairing 是預設安全起點
所有當前支援 DM 的渠道都有 DM policy。它在訊息被處理前先擋住入站 DM。
四種策略:
dmPolicy | 行為 | 風險判斷 |
|---|---|---|
pairing | 預設。未知傳送者拿到短碼,owner approve 前訊息不會被處理 | 私人 Agent 的預設安全起點 |
allowlist | 只允許 allowFrom 或 pairing allow-store 中的傳送者 | 適合固定聯絡人 |
open | 允許所有入站 DM,必須顯式 allowFrom: ["*"] | 只適合非常受限的工具能力 |
disabled | 忽略所有入站 DM | 適合關閉外部私信入口 |
Pairing 的官方細節:
- 配對碼:8 位、大寫、避開易混字元
0O1I。 - 過期時間:1 小時。
- 同一 sender:約每小時只會建立一次新請求。
- pending 數量:每個 channel 預設最多 3 個 pending requests。
- approve 前:未知 sender 的訊息不會進入 Agent。
審批命令:
openclaw pairing list telegram
openclaw pairing approve telegram PAIRCODEDM 配對狀態在 Gateway host 上,預設路徑:
預設檔案包括 ~/.openclaw/credentials/channel-pairing.json、~/.openclaw/credentials/channel-allowFrom.json 和 ~/.openclaw/credentials/channel-accountId-allowFrom.json。
這些檔案是訪問控制資料,按敏感檔案處理。
5. DM isolation:不要把多人 DM 放進一個上下文
DM access 解決“誰能說話”。DM isolation 解決“誰和誰共享上下文”。
如果只有你一個人用私人 Agent,session.dmScope: "main" 可以保持連續性。
如果多個人能 DM:
{
"session": {
"dmScope": "per-channel-peer"
}
}官方的 shared inbox quick rule:
- 多人可 DM:用
per-channel-peer。 - 多賬號 channel:用
per-account-channel-peer。 - 固定聯絡人:保持
dmPolicy: "pairing"或嚴格 allowlist。 - shared inbox + 工具能力:不要和 broad tool access 放在一起。
這仍然不是敵對多租戶隔離。它只是把 cooperative shared inbox 做得更穩。
dmPolicy 管“誰能進來”,dmScope 管“誰和誰共享上下文”。這兩個必須一起看。
6. Group access:allowlist 先於 mention
群組比 DM 更危險,因為訊息來源更多,歷史上下文更雜。
官方 Groups 文件的預設行為:
groupPolicy預設allowlist:群組不是預設全開放入口。- 群組回覆預設需要 mention:不被 @ 時通常不應主動回覆。
- Heartbeat 會跳過 group sessions:週期提醒不應自動打擾群組。
群組訊息的判斷順序:
- 先看
groupPolicy是disabled、allowlist還是open,決定群組入口是否進入處理鏈路。 - 再看 Group allowlists 是否允許這個群、房間或 sender。
- 最後看
requireMention/ activation 是否允許觸發回覆。
groupPolicy 和 mention gating 是兩件事:
groupPolicy決定這個群組或房間能不能進入處理鏈路。requireMention決定是否必須 @ 到 bot 才觸發回覆。
安全預設:
{
"channels": {
"whatsapp": {
"groupPolicy": "allowlist",
"groupAllowFrom": ["+15551234567"],
"groups": {
"*": { "requireMention": true }
}
}
}
}DM pairing approval 不等於 group authorization。批准某人私信,只是讓他能 DM;不代表他能在群裡觸發命令。
7. Context visibility:觸發許可權不等於上下文過濾
官方安全文件把兩件事分開:
- Trigger authorization 問“誰能觸發 Agent”,例如 sender、group、room 是否 allowlisted。
- Context visibility 問“哪些補充上下文進入模型輸入”,例如 quote、thread history、forward metadata。
補充上下文包括 reply body、quoted text、thread history、forwarded metadata。預設 contextVisibility: "all" 會盡量保持正常聊天體驗,但這不代表所有 quoted/history 內容都經過了同等 allowlist 過濾。
可選模式:
contextVisibility | 行為 | 適合場景 |
|---|---|---|
all | 預設,按收到的上下文保留 | 私人或可信群組 |
allowlist | 只保留 active allowlist 允許 sender 的補充上下文 | 更強上下文過濾 |
allowlist_quote | 類似 allowlist,但保留顯式 quote/reply 例外 | 需要回復引用上下文,但仍要收緊 |
這對群聊尤其重要:一個非 allowlisted sender 不能觸發 Agent,不代表他的歷史訊息永遠不會以 thread/quote context 形式被模型看到。需要強邊界時,把 contextVisibility 配到 channel 或具體 room/conversation。
觸發許可權不是上下文過濾。能不能讓 Agent 開口,和哪些歷史內容進入模型,是兩條不同的安全鏈路。
8. 工具安全分三層
OpenClaw 有三個相關但不同的控制:
- Sandbox:決定工具在哪裡執行,比如 host、Docker、SSH、OpenShell;這是執行環境邊界。
- Tool policy:決定哪些工具存在、可呼叫;這是能力邊界。
- Elevated:決定 sandboxed exec 是否有出沙箱逃生口;隻影響
exec。
Sandbox mode:
| Sandbox mode | 行為 | 適合場景 |
|---|---|---|
off | 全部工具在 host 上執行 | 只適合可信個人入口 |
non-main | 只有 non-main sessions sandboxed | 群組、channel、外部入口常見選擇 |
all | 所有 session 都 sandboxed | 更嚴格的預設隔離 |
Tool policy 規則:
deny永遠優先:明確禁止不能被後續 allow 覆蓋。allow非空時,沒列入的工具都被 blocked:allowlist 是收緊模式。/exec不能覆蓋被 tool policy deny 的exec:使用者命令不能越過硬 policy。- Provider-specific policy 可覆蓋:可以按 provider 或 provider/model 定製。
- Sandbox tool policy 只在 sandboxed 時生效:要先確認 session 是否真的 sandboxed。
Elevated 規則:
on/ask:出沙箱但保留 approvals,需要人工確認。full:出沙箱並跳過 exec approvals,風險最高。- 未啟用或 sender 未 allowlisted:不允許 elevated,預設更穩。
Elevated 不授予額外工具,不覆蓋 tool allow/deny;它只在 agent sandboxed 且影響 exec 時改變執行位置。
除錯實際生效規則:
openclaw sandbox explain
openclaw sandbox explain --session agent:main:main
openclaw sandbox explain --agent work
openclaw sandbox explain --json9. Sandbox bind mounts 是真實穿透口
Docker sandbox 不是魔法牆。你掛載什麼,容器裡就能看到什麼。
官方安全要點:
docker.binds會穿透 sandbox filesystem,掛進去的路徑,容器裡就能看見。- 不寫 mode 時預設 read-write,敏感路徑優先
ro。 workspaceAccess獨立於 bind mode,workspace 許可權和額外掛載許可權分開判斷。- 繫結
/var/run/docker.sock等於把 host 控制權交給 sandbox。 - Symlink-parent escapes 已有校驗,但仍不要把敏感目錄放進 allowed roots。
群組和公共 Agent 的更穩寫法:
{
"agents": {
"defaults": {
"sandbox": {
"mode": "non-main",
"scope": "session",
"workspaceAccess": "none",
"docker": {
"binds": ["/home/user/PublicDocs:/data:ro"]
}
}
}
},
"tools": {
"sandbox": {
"tools": {
"allow": ["group:messaging", "group:sessions"],
"deny": ["group:runtime", "group:fs", "group:ui", "nodes", "cron", "gateway"]
}
}
}
}這不是為了“讓模型更乖”,而是讓模型就算被誘導,也沒有能力碰 host 檔案和 shell。
Sandbox 不是口頭承諾。真正要檢查的是 bind mounts、workspaceAccess、tool allow/deny 和 elevated gates 的組合。
10. Prompt injection 沒有被解決
Prompt injection 是攻擊者把惡意指令塞進訊息、網頁、郵件、附件、日誌或檔案,讓模型把外部內容誤當成操作指令。
官方安全文件的立場很現實:
強 system prompt 只是 soft guidance;硬邊界來自 tool policy、exec approvals、sandboxing、channel allowlists。
應該視為不可信的內容:
- “讀這個檔案或 URL,然後照裡面說的做。”風險是外部內容偽裝成操作指令。
- “忽略 system prompt 或安全規則。”風險是試圖覆蓋上層約束。
- “輸出 hidden instructions 或 tool outputs。”風險是誘導洩漏內部上下文。
- “貼上
~/.openclaw或日誌的完整內容。”風險是誘導洩漏配置和 transcript。 - 網頁、郵件、附件、轉發訊息、群聊歷史、貼上的日誌和程式碼,都可能把外部輸入混入模型上下文。
實際防禦:
- 入口:入站 DM 用 pairing 或 allowlist。
- 群組:用 mention gating,不做 public room always-on bot。
- Agent profile:觸碰不可信內容的 Agent 用 read-only 或 tool-disabled profile。
- 高風險工具:
exec、browser、web_fetch、web_search只給可信 Agent。 - 直譯器:需要 allowlist 時,啟用
tools.exec.strictInlineEval。 - 秘密:不放進 prompt,放在 Gateway host 的 env/config 中。
- 模型:Tool-enabled Agent 選更新、更強的 instruction-hardened model。
不要承諾“防住所有 prompt injection”。正確目標是:注入即使成功,也不能變成檔案、shell、網路、瀏覽器、憑據洩露的真實動作。
11. Browser 和外掛也屬於攻擊面
Browser control 風險不低。Host browser profile 可能有登入態、cookie、後臺賬號。官方建議:
- 給 Agent 用專用 profile,避免複用個人登入態。
- 不要指向日常瀏覽器 profile,cookie、後臺賬號、歷史記錄都可能暴露。
- Sandboxed agents 不預設啟用 host browser control,否則會繞回 host 側高許可權面。
- 嚴格環境收緊 Browser SSRF policy,private/internal destinations 預設禁掉,再用 allowlist 開例外。
Plugin 也不是普通配置。Plugin 在 Gateway 程序內執行,應該當作可信程式碼:
- 只裝可信來源,因為 Plugin 在 Gateway 程序內執行。
- 用
plugins.allow做顯式 allowlist,避免隨意載入。 - 安裝和更新前看清配置,配置本身可能擴大許可權。
- 更新 plugin 後重啟 Gateway,確保載入狀態一致。
- 謹慎使用
dangerously-force-unsafe-install,只作為 false positive 的 break-glass。
12. Gateway 暴露面:預設 loopback,不要裸奔
Gateway 預設埠是 18789,WebSocket 和 HTTP 共用這個埠。HTTP surface 包括 Control UI、canvas host 等。
安全規則:
gateway.bind: "loopback"是預設值,只允許本地客戶端連線。"lan"、"tailnet"、"custom"都會擴大攻擊面。- 非 loopback bind 必須配 Gateway auth、真實 firewall、可信反代或 Tailscale 方案。
- Tailscale Serve 優先於 LAN bind。
- 必須 LAN bind 時,firewall 只允許極小 source IP 集合。
- unauthenticated
0.0.0.0不應出現。
最小安全基線:
{
"gateway": {
"mode": "local",
"bind": "loopback",
"auth": {
"mode": "token",
"token": "replace-with-long-random-token"
}
},
"session": {
"dmScope": "per-channel-peer"
},
"tools": {
"profile": "messaging",
"deny": ["group:automation", "group:runtime", "group:fs", "sessions_spawn", "sessions_send"],
"fs": { "workspaceOnly": true },
"exec": { "security": "deny", "ask": "always" },
"elevated": { "enabled": false }
},
"channels": {
"whatsapp": {
"dmPolicy": "pairing",
"groups": {
"*": { "requireMention": true }
}
}
}
}13. 日誌、transcripts、配置都是敏感資料
即使訪問控制正確,日誌和 transcript 也會洩露資訊。
官方提醒的敏感位置:
~/.openclaw/openclaw.json:Gateway、channel、tool、auth 配置。~/.openclaw/agents/agentId/sessions/sessions.json:session 路由和狀態。~/.openclaw/agents/agentId/sessions/*.jsonl:transcript、工具呼叫和結果。~/.openclaw/sandboxes/:sandbox 執行產物。/tmp/openclaw/openclaw-YYYY-MM-DD.log:日誌和排障資訊。
建議:
~/.openclaw目錄許可權保持700,限制本機其他使用者讀取。openclaw.json保持600,避免配置洩露。- 保持
logging.redactSensitive: "tools",對工具輸出脫敏。 - 增加
logging.redactPatterns,遮蓋內部域名、token、hostnames。 - 對外排障優先給
openclaw status --all,避免直接貼 raw logs。 - 清理舊 transcripts 和 logs,降低歷史洩露面。
- 共享 host 用專用 OS user 跑 Gateway,限制橫向讀取。
14. 安全審計和應急
改配置、開新 channel、暴露網路面之後,跑:
openclaw security audit
openclaw security audit --deep
openclaw security audit --json--fix 只做窄修復:收緊常見 open group policies、恢復敏感日誌脫敏、修 state/config/include-file 許可權等。不要把它當成全自動安全加固。
如果懷疑暴露或洩露:
- Contain:停 Gateway,臨時改回
gateway.bind: "loopback",DM/group 改disabled或 require mention,並移除"*"allow-all。 - Rotate:換
gateway.auth.token或OPENCLAW_GATEWAY_PASSWORD,換 remote client token/password,換 channel tokens、model keys、auth-profiles、encrypted secrets。 - Audit:查 Gateway logs、相關 session transcripts 和近期 config diff,再重跑
openclaw security audit --deep。
15. 給 Agent 的實踐任務
把這組要求發給 OpenClaw Agent,讓它審計自己的入口安全:
- 只讀審計當前 OpenClaw Gateway 的 Channel 與安全配置,不要直接修改檔案。
- 執行
openclaw security audit --deep,並按 critical / warn / info 分類總結。 - 檢查
gateway.bind、gateway.auth、gateway.port,說明是否存在非 loopback 暴露或弱認證。 - 檢查所有 channels 的
dmPolicy、allowFrom、groupPolicy、groups、groupAllowFrom、requireMention。 - 檢查
session.dmScope;如果多使用者 DM 仍然使用main,指出風險。 - 檢查
contextVisibility是否適合群聊或公開頻道。 - 執行
openclaw sandbox explain --json,說明 sandbox mode、workspaceAccess、tool allow/deny、elevated gates。 - 檢查是否給公共或群組 Agent 開了
exec、browser、web_fetch、web_search、gateway、cron、sessions_send、sessions_spawn。 - 檢查日誌、transcripts、credentials、pairing store 的許可權和敏感資訊暴露風險。
- 輸出最小修復建議,按“必須修 / 建議修 / 可觀察”分組。
16. 本章自檢
讀完這一章,你應該能回答:
- OpenClaw 為什麼不把一個 shared Gateway 當成敵對多租戶隔離邊界?
- Channel routing 為什麼是確定性的?
dmPolicy: "pairing"和session.dmScope分別解決什麼問題?- 為什麼 DM pairing approval 不等於 group authorization?
groupPolicy、group allowlist、mention gating 的判斷順序是什麼?- Trigger authorization 和 context visibility 的區別是什麼?
- Sandbox、tool policy、elevated 分別控制什麼?
- 為什麼
deny比allow優先? - Prompt injection 為什麼不能靠 system prompt 徹底解決?
- 為什麼 Gateway 預設應該保持 loopback?
過關標準:能把一次外部訊息拆成“入口授權 → 路由 → 上下文可見性 → 工具策略 → 執行環境 → 日誌與配置保護”六層檢查。
17. 接下來去哪
10 · 設計覆盤
把 Channel、Session、Memory、Tools 和安全邊界收束成一次架構評審。
08 · Session 與 Heartbeat
回到上一篇,理解 session、task、heartbeat 和 schedule 的上下文邊界。
官方教程:遠端與安全
繼續看 Gateway 暴露、認證、遠端控制和執行邊界的官方配置口徑。