執行核准
執行核准是配套應用程式 / 節點主機的防護機制,用於控制沙箱化代理在真實主機(gateway 或 node)上執行指令。可以想成安全連鎖裝置:只有在策略 + 允許清單 +(可選的)使用者核准全部同意時,指令才會被允許執行。執行核准是在工具策略和提權門檻之外的額外層(除非提權設為 full,此時會跳過核准)。有效策略取 tools.exec.* 和核准預設值中較嚴格的一方;如果核准欄位省略,則使用 tools.exec 的值。
如果配套應用程式 UI 不可用,任何需要提示的請求會由 ask 後備處理(預設:拒絕)。
適用範圍
執行核准在執行主機上本地執行:
- Gateway 主機 → Gateway 機器上的
openclaw程序 - 節點主機 → 節點執行器(macOS 配套應用程式或無頭節點主機)
信任模型注意事項:
- 經 Gateway 驗證的呼叫者是該 Gateway 的受信任操作者。
- 已配對的節點將該受信任操作者的能力延伸到節點主機上。
- 執行核准降低意外執行風險,但不是逐使用者的驗證邊界。
- 核准的節點主機執行會綁定正規執行上下文:正規 cwd、確切 argv、存在時的 env 繫結,以及適用時的固定執行檔路徑。
- 對於 shell 腳本和直接的直譯器 / 執行環境檔案呼叫,OpenClaw 也會嘗試綁定一個具體的本地檔案運算元。如果該綁定檔案在核准後但執行前發生變更,執行會被拒絕而非執行已變更的內容。
- 這種檔案綁定是刻意的盡力而為,不是每個直譯器 / 執行環境載入路徑的完整語義模型。如果核准模式無法精確辨識出一個具體的本地檔案來綁定,它會拒絕產生核准支持的執行,而非假裝完整覆蓋。
macOS 架構:
- 節點主機服務透過本地 IPC 將
system.run轉發到 macOS 應用程式。 - macOS 應用程式執行核准邏輯並在 UI 上下文中執行指令。
設定和儲存
核准存放在執行主機上的本地 JSON 檔案中:
~/.openclaw/exec-approvals.json
範例結構:
{
"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"
}
]
}
}
}
策略控制項
Security(exec.security)
- deny:阻擋所有主機執行請求。
- allowlist:僅允許在允許清單中的指令。
- full:允許所有(等同提權)。
Ask(exec.ask)
- off:從不提示。
- on-miss:僅在允許清單不符時提示。
- always:每次指令都提示。
Ask 後備(askFallback)
需要提示但沒有 UI 可連線時,由後備決定:
- deny:阻擋。
- allowlist:僅在允許清單符合時允許。
- full:允許。
允許清單(每個代理)
允許清單是按代理分別管理的。如果有多個代理,在 macOS 應用程式中切換要編輯的代理。模式為不區分大小寫的 glob 比對。模式應解析為二進位檔路徑(僅有基本名稱的條目會被忽略)。舊版 agents.default 條目在載入時會遷移到 agents.main。
範例:
~/Projects/**/bin/peekaboo~/.local/bin/*/opt/homebrew/bin/rg
每個允許清單條目追蹤:
- id 穩定的 UUID,用於 UI 識別(選填)
- 最後使用時間戳
- 最後使用的指令
- 最後解析的路徑
自動允許技能 CLI
啟用自動允許技能 CLI 時,已知技能引用的可執行檔在節點(macOS 節點或無頭節點主機)上會被視為已列入允許清單。這透過 Gateway RPC 的 skills.bins 取得技能的二進位檔清單。如果需要嚴格的手動允許清單,請停用此功能。
重要信任注意事項:
- 這是一個隱含的便利允許清單,與手動路徑允許清單條目分開。
- 適用於 Gateway 和節點在同一信任邊界內的受信任操作者環境。
- 如果需要嚴格的明確信任,保持
autoAllowSkills: false並僅使用手動路徑允許清單條目。
安全二進位檔(僅限 stdin)
tools.exec.safeBins 定義了一小組僅限 stdin 的二進位檔(例如 jq),可在 allowlist 模式下無需明確允許清單條目即可執行。安全二進位檔會拒絕位置引數檔案和路徑型 token,因此只能操作輸入串流。把它當成串流篩選器的窄通道快速路徑,而非通用信任清單。不要將直譯器或執行環境的二進位檔(例如 python3、node、ruby、bash、sh、zsh)加入 safeBins。如果一個指令本身就能評估程式碼、執行子指令或讀取檔案,請使用明確的允許清單條目並保持核准提示啟用。自訂的安全二進位檔必須在 tools.exec.safeBinProfiles.<bin> 中定義明確的設定檔。驗證僅從 argv 結構進行確定性判斷(不做主機檔案系統存在性檢查),以防止允許 / 拒絕的差異洩漏檔案存在資訊。預設安全二進位檔的檔案導向選項會被拒絕(例如 sort -o、sort --output、sort --files0-from、sort --compress-program、sort --random-source、sort --temporary-directory/-T、wc --files0-from、jq -f/--from-file、grep -f/--file)。安全二進位檔也對破壞僅限 stdin 行為的選項執行明確的每個二進位檔旗標策略(例如 sort -o/--output/--compress-program 和 grep 的遞迴旗標)。長選項在安全二進位檔模式下以失敗關閉方式驗證:未知旗標和模糊的縮寫會被拒絕。安全二進位檔各設定檔被拒絕的旗標:
grep:--dereference-recursive,--directories,--exclude-from,--file,--recursive,-R,-d,-f,-rjq:--argfile,--from-file,--library-path,--rawfile,--slurpfile,-L,-fsort:--compress-program,--files0-from,--output,--random-source,--temporary-directory,-T,-owc:--files0-from
安全二進位檔也會強制將 argv token 在執行時視為字面文字(無 globbing 和無 $VARS 展開)用於僅限 stdin 的區段,因此 * 或 $HOME/... 之類的模式無法被用來偷渡檔案讀取。安全二進位檔也必須從受信任的二進位檔目錄解析(系統預設加上選用的 tools.exec.safeBinTrustedDirs)。PATH 條目永遠不會自動受信任。預設受信任的安全二進位檔目錄刻意最小化:/bin、/usr/bin。如果你的安全二進位檔位於套件管理器 / 使用者路徑(例如 /opt/homebrew/bin、/usr/local/bin、/opt/local/bin、/snap/bin),請明確加入 tools.exec.safeBinTrustedDirs。Shell 串聯和重導向在 allowlist 模式下不會自動允許。
Shell 串聯(&&、||、;)在每個頂層區段都滿足允許清單(包括安全二進位檔或技能自動允許)時是允許的。重導向在 allowlist 模式下仍不支援。指令替換($() / 反引號)在允許清單解析時會被拒絕,包括雙引號內的;如果需要字面 $() 文字,請使用單引號。在 macOS 配套應用程式核准上,包含 shell 控制或展開語法(&&、||、;、|、`、$、<、>、(、))的原始 shell 文字會被視為允許清單未命中,除非 shell 二進位檔本身已列入允許清單。對於 shell 包裝器(bash|sh|zsh ... -c/-lc),請求範圍的 env 覆寫會被縮減為一小組明確的允許清單(TERM、LANG、LC_*、COLORTERM、NO_COLOR、FORCE_COLOR)。對於 allowlist 模式下的永久允許決定,已知的分派包裝器(env、nice、nohup、stdbuf、timeout)會持久化內部可執行檔路徑而非包裝器路徑。Shell 多工器(busybox、toybox)也會為 shell applet(sh、ash 等)進行解包裝,讓內部可執行檔被持久化而非多工器二進位檔。如果包裝器或多工器無法安全解包裝,不會自動持久化允許清單條目。
預設安全二進位檔:jq、cut、uniq、head、tail、tr、wc。
grep 和 sort 不在預設清單中。如果你選擇加入,請為它們的非 stdin 工作流程保留明確的允許清單條目。對於安全二進位檔模式下的 grep,請使用 -e/--regexp 提供模式;位置模式形式會被拒絕,以防止檔案運算元被偽裝為模糊的位置引數。
安全二進位檔與允許清單的比較
| 主題 | tools.exec.safeBins | 允許清單(exec-approvals.json) |
|---|---|---|
| 目標 | 自動允許窄範圍的 stdin 篩選器 | 明確信任特定的可執行檔 |
| 比對類型 | 可執行檔名稱 + 安全二進位檔 argv 策略 | 解析後的可執行檔路徑 glob 模式 |
| 引數範圍 | 受安全二進位檔設定檔和字面 token 規則限制 | 僅路徑比對;引數的部分由你自行負責 |
| 典型範例 | jq、head、tail、wc | python3、node、ffmpeg、自訂 CLI |
| 最佳用途 | 管線中低風險的文字轉換 | 任何行為較廣或有副作用的工具 |
設定位置:
safeBins來自設定(tools.exec.safeBins或每個代理的agents.list[].tools.exec.safeBins)。safeBinTrustedDirs來自設定(tools.exec.safeBinTrustedDirs或每個代理的agents.list[].tools.exec.safeBinTrustedDirs)。safeBinProfiles來自設定(tools.exec.safeBinProfiles或每個代理的agents.list[].tools.exec.safeBinProfiles)。每個代理的設定檔 key 覆寫全域 key。- 允許清單條目存放在主機本地的
~/.openclaw/exec-approvals.json中的agents.<id>.allowlist底下(或透過控制 UI /openclaw approvals allowlist ...)。 openclaw security audit會在直譯器 / 執行環境二進位檔出現在safeBins中但缺少明確設定檔時發出tools.exec.safe_bins_interpreter_unprofiled警告。openclaw doctor --fix可以為遺失的自訂safeBinProfiles.<bin>條目建立{}骨架(之後請檢視並收緊)。直譯器 / 執行環境二進位檔不會被自動建立骨架。
自訂設定檔範例:
{
tools: {
exec: {
safeBins: ["jq", "myfilter"],
safeBinProfiles: {
myfilter: {
minPositional: 0,
maxPositional: 0,
allowedValueFlags: ["-n", "--limit"],
deniedFlags: ["-f", "--file", "-c", "--command"],
},
},
},
},
}
控制 UI 編輯
使用控制 UI → Nodes → Exec approvals 卡片來編輯預設值、每個代理的覆寫和允許清單。選擇一個範圍(Defaults 或某個代理),調整策略,新增 / 移除允許清單模式,然後儲存。UI 會顯示每個模式的最後使用元資料,方便你保持清單整潔。
目標選擇器可選 Gateway(本地核准)或 Node。節點必須公告 system.execApprovals.get/set(macOS 應用程式或無頭節點主機)。如果節點尚未公告執行核准功能,請直接編輯其本地 ~/.openclaw/exec-approvals.json。
CLI:openclaw approvals 支援 Gateway 或節點的編輯(請參閱 Approvals CLI)。
核准流程
需要提示時,Gateway 會向操作者客戶端廣播 exec.approval.requested。控制 UI 和 macOS 應用程式透過 exec.approval.resolve 回應,然後 Gateway 將核准的請求轉發給節點主機。
對於 host=node,核准請求包含正規的 systemRunPlan payload。Gateway 在轉發核准的 system.run 請求時使用該計畫作為權威的指令 / cwd / 工作階段上下文。
直譯器 / 執行環境指令
核准支持的直譯器 / 執行環境執行刻意保守:
- 確切的 argv/cwd/env 上下文始終綁定。
- 直接 shell 腳本和直接執行環境檔案形式盡力綁定到一個具體的本地檔案快照。
- 仍能解析到單一直接本地檔案的常見套件管理器包裝形式(例如
pnpm exec、pnpm node、npm exec、npx)會在綁定前解包裝。 - 如果 OpenClaw 無法為直譯器 / 執行環境指令精確辨識出一個具體的本地檔案(例如套件腳本、eval 形式、執行環境特有的載入鏈或模糊的多檔案形式),核准支持的執行會被拒絕,而非聲稱未具備的語義覆蓋。
- 對於這些工作流程,建議使用沙箱化、獨立的主機邊界,或明確的受信任允許清單 / full 工作流程,由操作者接受更廣泛的執行環境語義。
需要核准時,exec 工具會立即回傳並附帶核准 id。使用該 id 關聯後續的系統事件(Exec finished / Exec denied)。如果在逾時前沒有收到決定,請求會被視為核准逾時並顯示拒絕原因。
確認對話框包含:
- 指令 + 引數
- cwd
- 代理 id
- 解析後的可執行檔路徑
- 主機 + 策略元資料
操作:
- 允許一次 → 立即執行
- 永遠允許 → 加入允許清單 + 執行
- 拒絕 → 阻擋
核准轉發到聊天頻道
你可以將執行核准提示轉發到任何聊天頻道(包括外掛頻道),並用 /approve 進行核准。這使用一般的外發投遞管線。
設定:
{
approvals: {
exec: {
enabled: true,
mode: "session", // "session" | "targets" | "both"
agentFilter: ["main"],
sessionFilter: ["discord"], // 子字串或正則表達式
targets: [
{ channel: "slack", to: "U12345678" },
{ channel: "telegram", to: "123456789" },
],
},
},
}
在聊天中回覆:
/approve <id> allow-once
/approve <id> allow-always
/approve <id> deny
內建聊天核准客戶端
Discord 和 Telegram 也可以作為明確的執行核准客戶端,各有頻道特定的設定。
- Discord:
channels.discord.execApprovals.* - Telegram:
channels.telegram.execApprovals.*
這些客戶端為可選啟用。如果頻道未啟用執行核准,OpenClaw 不會僅因對話發生在該頻道就把它當成核准介面。
共通行為:
- 僅設定的核准者可以核准或拒絕
- 請求者不需要是核准者
- 啟用頻道投遞時,核准提示會包含指令文字
- 如果沒有操作者 UI 或已設定的核准客戶端能接受請求,提示會後備到
askFallback
Telegram 預設傳送到核准者的私訊(target: "dm")。你可以切換為 channel 或 both,讓核准提示同時出現在來源 Telegram 聊天 / 主題中。對於 Telegram 論壇主題,OpenClaw 會保留核准提示和核准後後續訊息的主題。
請參閱:
macOS IPC 流程
Gateway -> Node Service (WS)
| IPC (UDS + token + HMAC + TTL)
v
Mac App (UI + approvals + system.run)
安全性注意事項:
- Unix socket 模式
0600,token 儲存在exec-approvals.json中。 - 同一 UID 的對等檢查。
- 挑戰 / 回應(nonce + HMAC token + 請求雜湊)+ 短 TTL。
系統事件
執行生命週期以系統訊息呈現:
Exec running(僅在指令超過執行通知門檻值時)Exec finishedExec denied
這些會在節點回報事件後發布到代理的工作階段。Gateway 主機的執行核准在指令完成時發出相同的生命週期事件(以及可選的超過門檻值時的執行中通知)。核准閘控的執行會重用核准 id 作為這些訊息中的 runId,便於關聯。
影響
- full 功能強大;盡可能優先使用允許清單。
- ask 讓你保持在控制迴路中,同時仍允許快速核准。
- 每個代理的允許清單可防止一個代理的核准洩漏到其他代理。
- 核准僅適用於來自授權發送者的主機執行請求。未授權的發送者無法發出
/exec。 /exec security=full是授權操作者的工作階段級便利功能,設計上會跳過核准。若要硬性阻擋主機執行,請將核准 security 設為deny或透過工具策略拒絕exec工具。
相關文件: