Exec Approvals
Exec approvalsは、サンドボックス化されたエージェントが実際のホスト(gateway または node)上でコマンドを実行することを許可するための コンパニオンアプリ / ノードホストガードレール です。安全インターロックのようなものと考えてください:コマンドは、ポリシー + 許可リスト + (オプションの) ユーザー承認のすべてが合意した場合にのみ許可されます。Exec approvalsは、ツールポリシーと昇格ゲーティングに追加で適用されます(昇格が full に設定されている場合を除く。full は承認をスキップします)。有効なポリシーは tools.exec.* と approvals のデフォルト値のうちより厳しい方です。approvals フィールドが省略されている場合、tools.exec の値が使用されます。コンパニオンアプリ UI が利用できない場合、プロンプトを必要とするリクエストは ask フォールバック (デフォルト: deny) によって解決されます。
適用範囲
Exec approvals は、実行ホスト上でローカルに適用されます:
- gateway ホスト → ゲートウェイマシン上の
openclawプロセス - node ホスト → ノードランナー (macOS コンパニオンアプリまたはヘッドレスノードホスト)
macOS の分割:
- node ホストサービス は
system.runをローカル IPC 経由で 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"
}
]
}
}
}
ポリシー設定項目
セキュリティ (exec.security)
- deny: すべてのホスト実行リクエストをブロックします。
- allowlist: 許可リストに登録されたコマンドのみを許可します。
- full: すべてを許可します (昇格モードと同等)。
確認 (exec.ask)
- off: プロンプトを表示しません。
- on-miss: 許可リストに一致しない場合のみプロンプトを表示します。
- always: すべてのコマンドに対してプロンプトを表示します。
確認フォールバック (askFallback)
プロンプトが必要だが UI に到達できない場合、フォールバックが決定します:
- deny: ブロックします。
- allowlist: 許可リストに一致する場合のみ許可します。
- full: 許可します。
許可リスト (エージェントごと)
許可リストはエージェントごとです。複数のエージェントが存在する場合は、macOS アプリで編集中のエージェントを切り替えてください。パターンは大文字小文字を区別しないグロブマッチです。パターンはバイナリパスに解決されるべきです(ベースネームのみのエントリは無視されます)。レガシーな agents.default エントリは、読み込み時に agents.main に移行されます。例:
~/Projects/**/bin/peekaboo~/.local/bin/*/opt/homebrew/bin/rg
各許可リストエントリは以下を追跡します:
- id: UI 識別子に使用される安定した UUID (オプション)
- last used: タイムスタンプ
- last used command: 最後に使用されたコマンド
- last resolved path: 最後に解決されたパス
スキル CLI の自動許可
スキル CLI の自動許可 が有効な場合、既知のスキルによって参照される実行可能ファイルは、ノード (macOS ノードまたはヘッドレスノードホスト) 上で許可リスト登録済みとして扱われます。これは、Gateway RPC を介して skills.bins を使用してスキルバイナリリストを取得します。厳密な手動許可リストを希望する場合は、この機能を無効にしてください。
安全なバイナリ (stdin のみ)
tools.exec.safeBins は、許可リストモードで明示的な許可リストエントリなしに実行できる、stdin のみのバイナリ (例: jq) の小さなリストを定義します。安全なバイナリは位置引数としてのファイル引数とパス類似トークンを拒否するため、受信ストリームに対してのみ操作できます。検証は argv の形状のみから決定論的に行われ (ホストファイルシステムの存在チェックは行わない)、許可/拒否の差異によるファイル存在オラクル動作を防ぎます。デフォルトの安全なバイナリでは、ファイル指向のオプションは拒否されます (例: sort -o, sort --output, sort --files0-from, sort --compress-program, wc --files0-from, jq -f/--from-file, grep -f/--file)。安全なバイナリはまた、stdin のみの動作を破るオプションに対して、バイナリごとの明示的なフラグポリシーを適用します (例: sort -o/--output/--compress-program や grep の再帰フラグ)。安全なバイナリはまた、stdin のみのセグメントでは、実行時に argv トークンをリテラルテキストとして扱うことを強制します (グロビングや $VARS 展開なし)。そのため、* や $HOME/... のようなパターンを使用してファイル読み込みを密輸することはできません。安全なバイナリは、信頼されたバイナリディレクトリ (システムデフォルトとゲートウェイプロセス起動時の PATH) から解決される必要もあります。これにより、リクエストスコープの PATH ハイジャックの試みをブロックします。シェルチェーンとリダイレクションは、許可リストモードでは自動許可されません。シェルチェーン (&&, ||, ;) は、すべてのトップレベルセグメントが許可リスト (安全なバイナリやスキル自動許可を含む) を満たす場合に許可されます。リダイレクションは許可リストモードではサポートされていません。コマンド置換 ($() / バッククォート) は、許可リスト解析中に拒否されます。二重引用符内も含みます。リテラルの $() テキストが必要な場合は、単一引用符を使用してください。macOS コンパニオンアプリの承認では、シェル制御または展開構文 (&&, ||, ;, |, ```, $, <, >, (, )) を含む生のシェルテキストは、シェルバイナリ自体が許可リストに登録されていない限り、許可リスト不一致として扱われます。デフォルトの安全なバイナリ: jq, cut, uniq, head, tail, tr, wc。grep と sort はデフォルトリストに含まれていません。オプトインする場合は、それらの非 stdin ワークフローに対して明示的な許可リストエントリを保持してください。安全なバイナリモードの grep では、パターンを -e/--regexp で指定してください。位置引数形式のパターンは拒否されるため、ファイルオペランドを曖昧な位置引数として密輸することはできません。
コントロール UI での編集
コントロール UI → ノード → Exec approvals カードを使用して、デフォルト、エージェントごとのオーバーライド、許可リストを編集します。スコープ (デフォルトまたはエージェント) を選択し、ポリシーを調整し、許可リストパターンを追加/削除してから、保存 をクリックします。UI はパターンごとの 最終使用 メタデータを表示するので、リストを整理しやすくなっています。ターゲットセレクタでは Gateway (ローカル承認) または Node を選択します。ノードは system.execApprovals.get/set をアドバタイズしている必要があります (macOS アプリまたはヘッドレスノードホスト)。ノードがまだ exec approvals をアドバタイズしていない場合は、そのローカルの ~/.openclaw/exec-approvals.json を直接編集してください。CLI: openclaw approvals はゲートウェイまたはノードの編集をサポートします (Approvals CLI を参照)。
承認フロー
プロンプトが必要な場合、ゲートウェイは exec.approval.requested をオペレータクライアントにブロードキャストします。コントロール UI と macOS アプリは exec.approval.resolve 経由で解決し、その後ゲートウェイは承認されたリクエストをノードホストに転送します。承認が必要な場合、exec ツールは承認 id ですぐに返ります。その id を使用して、後続のシステムイベント (Exec finished / Exec denied) と関連付けます。タイムアウト前に決定が到着しない場合、リクエストは承認タイムアウトとして扱われ、拒否理由として表示されます。確認ダイアログには以下が含まれます:
- コマンド + 引数
- cwd
- エージェント id
- 解決された実行可能ファイルパス
- ホスト + ポリシーメタデータ
アクション:
- 一度だけ許可 → 今すぐ実行
- 常に許可 → 許可リストに追加 + 実行
- 拒否 → ブロック
チャットチャネルへの承認転送
exec 承認プロンプトを任意のチャットチャネル (プラグインチャネルを含む) に転送し、/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
macOS IPC フロー
Gateway -> Node Service (WS)
| IPC (UDS + token + HMAC + TTL)
v
Mac App (UI + approvals + system.run)
セキュリティ上の注意:
- Unix ソケットモード
0600、トークンはexec-approvals.jsonに保存。 - 同一 UID ピアチェック。
- チャレンジ/レスポンス (nonce + HMAC トークン + リクエストハッシュ) + 短い TTL。
システムイベント
Exec ライフサイクルはシステムメッセージとして表示されます:
Exec running(コマンドが実行通知しきい値を超えた場合のみ)Exec finishedExec denied
これらは、ノードがイベントを報告した後、エージェントのセッションに投稿されます。ゲートウェイホストの exec approvals は、コマンドが終了したとき (およびオプションで実行時間がしきい値を超えたとき) に同じライフサイクルイベントを発行します。承認ゲートされた exec は、これらのメッセージ内の runId として承認 id を再利用し、簡単な関連付けを可能にします。
影響
- full は強力です。可能な限り許可リストを優先してください。
- ask は、迅速な承認を可能にしながらも、状況を把握し続けることができます。
- エージェントごとの許可リストは、あるエージェントの承認が他のエージェントに漏洩するのを防ぎます。
- 承認は、認可された送信者からのホスト実行リクエストにのみ適用されます。認可されていない送信者は
/execを発行できません。 /exec security=fullは、認可されたオペレータのためのセッションレベルの利便性であり、設計上承認をスキップします。ホスト実行を完全にブロックするには、承認セキュリティをdenyに設定するか、ツールポリシーでexecツールを拒否してください。
関連項目: