跳到內容

使用 Exec Approvals 為 AI Agent 建立安全護欄

讓 AI Agent 自動幫你寫程式、跑指令確實很方便,但你心裡多少會有點擔心:萬一它在你的電腦上執行了危險指令怎麼辦?要把終端機的控制權交給一個 sandboxed agent,你一定需要一個既能自動化、又能隨時介入的安全機制。

Exec approvals 就是為了這個場景設計的。它就像是一個實體安全鎖,只有在 policy、allowlist 以及你的手動確認(選填)同時達成共識時,指令才會被允許執行。

  • OpenClaw Gateway 或 Node host(macOS companion app 或 headless node host)
  • 基礎的 JSON 修改能力
  • 對 ~/.openclaw/exec-approvals.json 路徑的存取權限

Exec approvals 是在 tools.exec policy 和 elevated gating 之外的額外防護。如果設定衝突,系統會採用最嚴格的標準。

Exec approvals 會在執行指令的主機上直接生效:

  • Gateway host: 由 Gateway 機器上的 openclaw 程序負責。
  • Node host: 由 node runner 負責(包含 macOS companion app 或 headless 模式)。

所有的核准規則都存在 ~/.openclaw/exec-approvals.json。你可以參考下面的 schema 來配置你的環境:

{
"version": 1,
"socket": {
"path": "~/.openclaw/exec-approvals.sock",
"token": "base64url-token"
},
"defaults": {
"security": "deny",
"ask": "on-miss",
"askFallback": "deny",
"autoAllowSkills": false
},
"agents": {
"main": {
"security": "allowlist",
"ask": "on-miss",
"askFallback": "deny",
"autoAllowSkills": true,
"allowlist": [
{
"id": "B0C8C0B3-2C2D-4F8A-9A3C-5A4B3C2D1E0F",
"pattern": "~/Projects/**/bin/rg",
"lastUsedAt": 1737150000000,
"lastUsedCommand": "rg -n TODO",
"lastResolvedPath": "/Users/user/Projects/.../bin/rg"
}
]
}
}
}

這套機制不只是簡單的開關,它還包含了一些聰明的保護:

  • 內容漂移保護:如果一個腳本在核准後、執行前被修改了,系統會偵測到內容變動(drifted content)並直接拒絕執行。
  • macOS 特殊路徑:在 macOS 上,node host service 會透過 local IPC 將 system.run 傳給 macOS app,由 app 負責執行並顯示 UI 確認視窗。
  • 指令被自動拒絕了:如果 companion app 的 UI 無法使用,任何需要你手動確認的請求都會直接觸發 ask fallback。預設情況下,這個值是 deny。
  • 腳本無法執行:檢查你的腳本內容是否在核准後發生過變動。Exec approvals 會綁定執行路徑與內容,一旦不一致就會攔截。

想要更快速地完成設定?可以試試 AI Setup Assistant。

處理遠端執行或自動化任務時,安全性總是最讓人頭痛的一環。你可能遇過這種情況:權限設太嚴,開發流程卡得要命;設太鬆,心裡又覺得毛毛的。

要在自動化便利性與系統安全之間找到平衡點,你需要一套靈活的控制開關。這就是 Policy Knobs 發揮作用的地方,讓你精確定義哪些指令可以跑、什麼時候該跳提醒。

在開始配置之前,請確保你已經準備好以下環境(依據源文件):

  • macOS app 或 headless node host
  • 運作中的 Gateway
  • 已安裝並預備執行的技能 (Skills)

你可以透過調整 exec 相關的配置來快速設定你的安全策略。

這是你的第一道防線,決定了 host exec 請求的基本處理方式:

  • deny: 拒絕所有 host exec 請求。
  • allowlist: 僅允許白名單中的指令。
  • full: 允許所有請求(等同於提升權限)。

決定什麼時候要彈出視窗問你:

  • off: 從不詢問。
  • on-miss: 只有在指令不在白名單時才詢問。
  • always: 每個指令都要詢問。

如果系統需要詢問你,但當下沒有 UI 可以顯示(例如遠端環境),你可以設定備案:

  • deny: 直接阻擋。
  • allowlist: 只有符合白名單時才允許。
  • full: 直接允許。

白名單是針對每個 agent 獨立設定的。如果你有多個 agent,記得在 macOS app 中切換你要編輯的對象。

這裡使用的模式是 case-insensitive glob matches(不區分大小寫的 glob 匹配)。請注意,規則必須解析為二進位檔案路徑,如果只寫檔名(basename-only)會被忽略。

範例:

  • ~/Projects/**/bin/peekaboo
  • ~/.local/bin/*
  • /opt/homebrew/bin/rg

每個白名單條目都會追蹤以下資訊:

  • id: 用於 UI 識別的穩定 UUID(選填)
  • last used: 最後使用時間戳
  • last used command: 最後使用的指令
  • last resolved path: 最後解析的路徑

當你開啟 Auto-allow skill CLIs 時,已知技能所引用的執行檔會被自動視為已加入白名單(無論是在 macOS node 或 headless node host)。

這個機制會透過 Gateway RPC 讀取 skills.bins 來獲取清單。如果你偏好嚴格的手動管理,請關閉此功能。

關於信任的重要提醒:

  • 這是一個隱式的便利白名單,與你手動輸入的路徑條目是分開的。
  • 它適用於 Gateway 與 node 處於相同信任邊界的受信任操作環境。
  • 如果你需要嚴格的顯式信任,請保持 autoAllowSkills: false 並僅使用手動白名單。

以下是配置時可能遇到的狀況:

  • 找不到舊的 agent 設定? 不用擔心,舊版的 agents.default 條目在載入時會自動遷移到 agents.main。
  • 白名單條目無效? 請檢查你的路徑設定。系統會忽略僅包含檔名(如 ls)的條目,你必須提供完整路徑或使用 glob 模式(如 /bin/ls)。

如果你在配置過程中遇到任何疑問,可以詢問 AI Setup Assistant 獲取即時協助。

你是否曾經在編寫自動化腳本時,覺得為了一個簡單的 jq 過濾或 head 指令就要去更新 allowlist 很麻煩?但如果直接開放所有權限,又擔心會留下安全隱患,讓系統暴露在風險中。

這種在「開發效率」與「安全性」之間的拉鋸戰是每個開發者的日常。Safe bins 的出現就是為了解決這個痛點,讓你能在安全的邊界內,快速執行特定的串流過濾任務。

  • tools.exec.safeBins 配置權限
  • 基礎的 shell 與 stdin 串流概念
  • openclaw CLI 工具(用於 audit 與 doctor 指令)
  1. 定義 Safe Bins:在你的設定檔中,透過 tools.exec.safeBins 定義一組僅限 stdin-only 的 binary 清單。
  2. 使用預設工具:系統預設已包含 jq, cut, uniq, head, tail, tr, wc。
  3. 執行過濾:這些工具在不帶有檔案路徑參數的情況下,可以直接運行而不需要額外的 allowlist 條目。
  4. 檢查安全性:執行 openclaw security audit 確保你的配置沒有風險。

tools.exec.safeBins 定義了一組極小的 stdin-only binary 清單。這些工具可以在 allowlist 模式下直接運行,不需要明確的 allowlist 條目。

Safe bins 會拒絕位置參數中的檔案路徑或類似路徑的 token,因此它們只能處理傳入的 stdin 串流。請記住,這是一個專為串流過濾設計的「窄路徑」,而不是通用的信任清單。

  • 禁止解釋器:絕對不要將 python3, node, ruby, bash, sh, zsh 等解釋器或 runtime 放到 safeBins 中。
  • 原則:如果一個指令設計上就能評估程式碼、執行子指令或讀取檔案,請使用明確的 allowlist 條目並保持審核提示(approval prompts)開啟。
  • 驗證方式:驗證是根據 argv 的形狀(shape)來決定的,不會檢查主機檔案系統是否存在。這可以防止透過 allow/deny 的差異來推測檔案是否存在。

預設的 safe bins 會禁用與檔案操作相關的選項。例如:

  • sort -o, sort --output, sort --files0-from
  • wc --files0-from
  • jq -f, jq --from-file
  • grep -f, grep --file

Safe bins 也會強制執行特定 binary 的旗標策略,防止破壞 stdin-only 行為。長選項(Long options)採用「失敗即關閉」(fail-closed)模式:任何未知的旗標或模糊的縮寫都會被拒絕。

各設定檔禁用的旗標清單:

  • grep: --dereference-recursive, --directories, --exclude-from, --file, --recursive, -R, -d, -f, -r
  • jq: --argfile, --from-file, --library-path, --rawfile, --slurpfile, -L, -f
  • sort: --compress-program, --files0-from, --output, --random-source, --temporary-directory, -T, -o
  • wc: --files0-from

Safe bins 會強迫將 argv tokens 視為字面文字 (literal text)。這意味著在執行時不會有 globbing(例如 *)或 $VARS 變數擴展,防止有人利用這些模式來讀取檔案。

此外,Safe bins 必須從受信任的目錄中解析。預設目錄只有 /bin 與 /usr/bin。如果你的工具安裝在 Homebrew 或其他路徑(如 /opt/homebrew/bin, /usr/local/bin),你需要將它們手動加入 tools.exec.safeBinTrustedDirs。

在 allowlist 模式下,Shell 鏈接(&&, ||, ;)只有在每個片段都符合 allowlist(包括 safe bins)時才被允許。目前仍不支援重定向(Redirections)。

  • 指令替換:$() 或反引號(backticks)在解析時會被拒絕。如果你需要字面上的 $(),請使用單引號。
  • macOS 審核:如果原始 shell 文字包含 &&, |, $, <, > 等符號,除非 shell binary 本身在 allowlist 中,否則會被視為未命中。
  • Dispatch 包裝器:對於 env, nice, nohup, timeout 等工具,系統會持續追蹤內部的執行路徑,而不是包裝器本身的路徑。
主題tools.exec.safeBinsAllowlist (exec-approvals.json)
目標自動允許窄小的 stdin 過濾器明確信任特定的執行檔
匹配類型執行檔名稱 + safe-bin argv 策略已解析的執行檔路徑 glob 模式
參數範圍受 profile 與字面 token 規則限制僅匹配路徑;參數由你自行負責
典型範例jq, head, tail, wcpython3, node, ffmpeg, 自定義 CLI
最佳用途Pipeline 中低風險的文字轉換任何具有廣泛行為或副作用的工具

你可以透過以下方式進行配置:

  • safeBins:來自 tools.exec.safeBins 或每個 agent 的獨立設定。
  • safeBinTrustedDirs:定義受信任的 binary 目錄。
  • safeBinProfiles:為自定義工具定義過濾規則。

如果你有自己的過濾工具 myfilter:

{
tools: {
exec: {
safeBins: ["jq", "myfilter"],
safeBinProfiles: {
myfilter: {
minPositional: 0,
maxPositional: 0,
allowedValueFlags: ["-n", "--limit"],
deniedFlags: ["-f", "--file", "-c", "--command"],
},
},
},
},
}
  • 解釋器警告:如果你將 python3 等工具加入 safeBins 且沒有定義 profile,openclaw security audit 會發出 tools.exec.safe_bins_interpreter_unprofiled 警告。
  • 配置修補:你可以使用 openclaw doctor --fix 來自動建立缺失的 safeBinProfiles.<bin> 條目(預設為 {}),之後再手動調整規則。
  • Grep 與 Sort:這兩個工具不在預設清單中。如果你手動加入,請記得 grep 在 safe-bin 模式下必須使用 -e/--regexp 來提供 pattern,否則會被拒絕。

如果你在設定過程中遇到任何問題,可以直接詢問你的 AI Setup Assistant。

每次讓 Agent 執行系統指令時,心裡總會有點不安?擔心它在你不注意的時候跑了什麼奇怪的 Script,或是動到不該動的檔案。手動審核是保護系統的最後一道防線,但如果設定太麻煩,反而會拖慢你的開發效率。

這篇指南會教你如何在 Control UI 中輕鬆管理這些權限,讓你既能享受自動化的便利,又能掌握最終的控制權。

  • Control UI 存取權限
  • 運作中的 Gateway 或 Node
  • 支援 system.execApprovals.get/set 的 Node Host(例如 macOS app 或 headless node host)

要在 UI 中編輯審核規則,請按照以下步驟操作:

  1. 找到 Control UI → Nodes → Exec approvals 卡片。
  2. 選擇 Scope:你可以選擇 Defaults(全域預設)或針對特定的 Agent 進行個別覆蓋。
  3. 調整 Policy:新增或移除 Allowlist(白名單)模式。
  4. 儲存設定:點擊 Save。UI 會顯示每個模式的 last used 紀錄,方便你清理不再需要的規則。

如果你偏好使用終端機,也可以透過 CLI 進行編輯:

Terminal window
openclaw approvals

這個指令同樣支援 Gateway 或 Node 的審核設定編輯,詳情可以參考 Approvals CLI。

當系統判斷需要審核時,Gateway 會向所有的 Operator Client 廣播 exec.approval.requested 事件。

  1. 解析請求:Control UI 或 macOS App 會透過 exec.approval.resolve 來處理這個請求。
  2. 轉發指令:一旦審核通過,Gateway 會將請求轉發給 Node Host。
  3. 權威執行:對於 host=node 的情況,Gateway 會使用 systemRunPlan 內的 payload(包含指令、cwd、session context)作為執行依據。
  4. 非同步追蹤:Exec 工具在請求發出後會立即回傳一個 approval id。你可以用這個 ID 來對應後續的系統事件,像是 Exec finished 或 Exec denied。

在確認對話框中,你會看到以下資訊:

  • 指令與參數 (command + args)
  • 工作目錄 (cwd)
  • Agent ID
  • 解析後的執行檔路徑
  • Host 與 Policy 元數據

你可以執行的動作包括:

  • Allow once:僅允許執行這一次。
  • Always allow:將此模式加入白名單並立即執行。
  • Deny:拒絕執行。
  • Node 沒有出現在編輯選項中? 如果 Node 尚未宣告支援 system.execApprovals.get/set,你將無法透過 UI 編輯它。這種情況下,請直接修改該 Node 上的本地設定檔:~/.openclaw/exec-approvals.json。
  • 請求被自動拒絕? 如果在設定的 Timeout 時間內沒有做出決定,系統會將其視為 approval timeout,並在結果中顯示為拒絕。

如果你在設定過程遇到任何問題,歡迎詢問 AI Setup Assistant。

每次執行敏感指令都要切換視窗點擊確認,真的會打斷開發節奏。如果你正忙著在 Slack 或 Discord 跟團隊溝通,卻還要跳回特定介面去點按鈕,這顯然不夠直覺。

你可以將 exec 的審核提示直接轉發到你常用的聊天頻道,並透過 /approve 指令即時處理,讓流程保持順暢。

  • Gateway
  • Node Service
  • Mac App (如果你在 macOS 環境)
  • 已配置好的聊天頻道(如 Slack, Telegram, Discord 或其他 plugin 頻道)

這項功能會透過標準的 outbound delivery pipeline 運作。你只需要在配置中定義轉發規則即可。

在你的設定檔中加入 approvals 區塊:

{
approvals: {
exec: {
enabled: true,
mode: "session", // 可選 "session" | "targets" | "both"
agentFilter: ["main"],
sessionFilter: ["discord"], // 支援子字串或 regex
targets: [
{ channel: "slack", to: "U12345678" },
{ channel: "telegram", to: "123456789" },
],
},
},
}

當審核請求跳出時,你可以在頻道中直接輸入以下指令:

/approve <id> allow-once
/approve <id> allow-always
/approve <id> deny

如果你是在 macOS 上執行,系統會遵循以下路徑:

Gateway -> Node Service (WS)
| IPC (UDS + token + HMAC + TTL)
v
Mac App (UI + approvals + system.run)

在安全設計上,我們採用了 Unix socket mode 0600,且 token 儲存在 exec-approvals.json 中。系統會進行 Same-UID peer 檢查,並透過 Challenge/response(nonce + HMAC token + request hash)搭配短時間的 TTL 來確保安全。

Exec 的生命週期會作為系統訊息呈現:

  • Exec running:僅在指令執行時間超過預設閾值時顯示。
  • Exec finished:執行完成。
  • Exec denied:請求被拒絕。

這些訊息會在 Node 回報事件後發送到 agent 的 session 中。如果是 Gateway-host 的審核,在指令結束時也會發出相同的生命週期事件。為了方便對照,審核 ID 會直接作為訊息中的 runId。

  • 指令無法執行? 審核僅適用於來自 authorized senders 的 host exec 請求。未經授權的發送者無法發起 /exec。
  • 想要完全封鎖 host exec? 如果你出於安全考量想徹底停用,請將 approvals security 設為 deny,或是透過 tool policy 直接禁用 exec 工具。
  • 跳過審核的問題: /exec security=full 是為了方便授權操作者提供的 session 等級捷徑,設計上會直接跳過審核。
  • full 模式權限極大,建議你盡量使用 allowlists。
  • ask 模式能讓你掌握狀況,同時保有快速核准的彈性。
  • 每個 agent 的 allowlist 是獨立的,這能防止某個 agent 的審核權限外洩到其他 agent。

如果你在設定過程遇到問題,可以詢問 AI Setup Assistant。

OpenClaw

OpenClaw Expert

還是卡住了?

如果這篇文件沒有解決你的情境,直接問 OpenClaw Expert,拿到可執行步驟。