執行核准

執行核准是配套應用程式 / 節點主機的防護機制,用於控制沙箱化代理在真實主機(gatewaynode)上執行指令。可以想成安全連鎖裝置:只有在策略 + 允許清單 +(可選的)使用者核准全部同意時,指令才會被允許執行。執行核准是在工具策略和提權門檻之外的額外層(除非提權設為 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,因此只能操作輸入串流。把它當成串流篩選器的窄通道快速路徑,而非通用信任清單。不要將直譯器或執行環境的二進位檔(例如 python3noderubybashshzsh)加入 safeBins。如果一個指令本身就能評估程式碼、執行子指令或讀取檔案,請使用明確的允許清單條目並保持核准提示啟用。自訂的安全二進位檔必須在 tools.exec.safeBinProfiles.<bin> 中定義明確的設定檔。驗證僅從 argv 結構進行確定性判斷(不做主機檔案系統存在性檢查),以防止允許 / 拒絕的差異洩漏檔案存在資訊。預設安全二進位檔的檔案導向選項會被拒絕(例如 sort -osort --outputsort --files0-fromsort --compress-programsort --random-sourcesort --temporary-directory/-Twc --files0-fromjq -f/--from-filegrep -f/--file)。安全二進位檔也對破壞僅限 stdin 行為的選項執行明確的每個二進位檔旗標策略(例如 sort -o/--output/--compress-program 和 grep 的遞迴旗標)。長選項在安全二進位檔模式下以失敗關閉方式驗證:未知旗標和模糊的縮寫會被拒絕。安全二進位檔各設定檔被拒絕的旗標:

  • 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

安全二進位檔也會強制將 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 覆寫會被縮減為一小組明確的允許清單(TERMLANGLC_*COLORTERMNO_COLORFORCE_COLOR)。對於 allowlist 模式下的永久允許決定,已知的分派包裝器(envnicenohupstdbuftimeout)會持久化內部可執行檔路徑而非包裝器路徑。Shell 多工器(busyboxtoybox)也會為 shell applet(shash 等)進行解包裝,讓內部可執行檔被持久化而非多工器二進位檔。如果包裝器或多工器無法安全解包裝,不會自動持久化允許清單條目。

預設安全二進位檔:jqcutuniqheadtailtrwc

grepsort 不在預設清單中。如果你選擇加入,請為它們的非 stdin 工作流程保留明確的允許清單條目。對於安全二進位檔模式下的 grep,請使用 -e/--regexp 提供模式;位置模式形式會被拒絕,以防止檔案運算元被偽裝為模糊的位置引數。

安全二進位檔與允許清單的比較

主題tools.exec.safeBins允許清單(exec-approvals.json
目標自動允許窄範圍的 stdin 篩選器明確信任特定的可執行檔
比對類型可執行檔名稱 + 安全二進位檔 argv 策略解析後的可執行檔路徑 glob 模式
引數範圍受安全二進位檔設定檔和字面 token 規則限制僅路徑比對;引數的部分由你自行負責
典型範例jqheadtailwcpython3nodeffmpeg、自訂 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 execpnpm nodenpm execnpx)會在綁定前解包裝。
  • 如果 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")。你可以切換為 channelboth,讓核准提示同時出現在來源 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 finished
  • Exec denied

這些會在節點回報事件後發布到代理的工作階段。Gateway 主機的執行核准在指令完成時發出相同的生命週期事件(以及可選的超過門檻值時的執行中通知)。核准閘控的執行會重用核准 id 作為這些訊息中的 runId,便於關聯。

影響

  • full 功能強大;盡可能優先使用允許清單。
  • ask 讓你保持在控制迴路中,同時仍允許快速核准。
  • 每個代理的允許清單可防止一個代理的核准洩漏到其他代理。
  • 核准僅適用於來自授權發送者的主機執行請求。未授權的發送者無法發出 /exec
  • /exec security=full 是授權操作者的工作階段級便利功能,設計上會跳過核准。若要硬性阻擋主機執行,請將核准 security 設為 deny 或透過工具策略拒絕 exec 工具。

相關文件: