WSL2上でOpenClaw Gatewayを動かし、Windows側のOpenClaw CompanionをNode Agentとして接続して、WindowsのファイルやPowerShellを操作しようとしたところ、Node自体は接続できているのにコマンド実行がうまく通らない問題に遭遇しました。
この記事では、そのときに確認した内容と、どこまで正常だったのか、どこで問題が起きていたのかを整理します。
今回の主な構成は次のとおりです。
Mattermost / Discord
↓
OpenClaw Agent
↓
WSL2 OpenClaw Gateway
↓
Windows Companion Node
↓
system.run
↓
PowerShell / Windowsコマンド
OpenClawは2026.7系、Windows側はOpenClaw Companionを利用しています。
Windows Nodeは正常に接続できていた
まず確認したのがNodeの状態です。
openclaw nodes status
正常な場合は、
Known: 1
Paired: 1
Connected: 1
のように表示されます。
さらにNodeのCapabilityに、
browser
system
screen
...
が表示されていれば、Windows CompanionがNodeとして各種機能をGatewayへ公開できています。
今回も、
paired
connected
approved
までは正常でした。
つまり、
Windows Companion
↓
WSL2 Gateway
の通信自体には問題がありませんでした。
execの実行先をWindows Nodeへ変更する
次に確認したのが tools.exec の設定です。
openclaw config get tools.exec
Windows Nodeへコマンドを送る場合は、概ね次の設定になります。
{
"host": "node",
"mode": "allowlist",
"node": "<Windows Node名>"
}
重要なのは、
host = node
です。
これがGatewayやローカル実行になっていると、PowerShellを実行するよう依頼しても、WSL2上のLinux環境で実行しようとしてしまいます。
今回も最初はAgentから、
OpenClawが動いているのはLinux環境なので、
PowerShellは実行できない
という返答が出ました。
しかし tools.exec.host=node を設定したことで、Windows Nodeまで処理が届くようになりました。
node.invokeが成功しているか確認する
Gatewayログを見ると、NodeへのRPCが成功しているか確認できます。
例えば、
[ws] ⇄ res ✓ node.invoke
というログです。
この ✓ node.invoke が出ていれば、
Agent
↓
Gateway
↓
Windows Node
までは正常です。
今回も複数回、
node.invoke ... ✓
が確認できました。
そのため、
Windows Nodeに接続できない
ことが原因ではないと判断できました。
system.runはnodes invokeから直接実行できない
切り分けのため、Nodeへ直接 system.run を送ろうとしました。
例えば、
openclaw nodes invoke \
--node "<Windows Node名>" \
--command system.run \
--params '{"command":"C:\\Windows\\System32\\hostname.exe"}'
しかし2026.7系では、
command "system.run" is reserved for shell execution;
use the exec tool with host=node instead
と拒否されます。
つまり system.run は、
nodes invoke
から直接呼ぶためのCommandではありません。
正しい流れは、
Agent
↓
exec tool
host=node
↓
Gateway
↓
system.run
↓
Windows Node
です。
そのためNode実行の動作確認は、Agentの exec ツール経由で行う必要があります。
Windows Companion側にもExec Approvalがある
OpenClawでは、Gateway側だけでなくWindows Node側にも独立した実行承認があります。
概念的には、
Agent
↓
Gateway側 exec policy
↓
Windows Node
↓
Windows側 Exec Approval
↓
実際のコマンド
という二重構造です。
Companion上で、
Allow Once
のようなポップアップが表示されるのは、このWindows側Exec Approvalです。
つまり、Gateway側で host=node が許可されていても、それだけでWindows上のコマンドが無制限に動くわけではありません。
Windows NodeのExec Approvalを確認する
Windows NodeのExec Approvalは、2026.7系では通常の node.invoke から直接取得できません。
次のようにすると、
openclaw nodes invoke \
--node "<Windows Node名>" \
--command system.execApprovals.get
次のエラーになります。
node.invoke does not allow system.execApprovals.*;
use exec.approvals.node.*
そこでGateway RPCを使います。
まずNodeのIDを確認します。
openclaw nodes status
そして、Node名ではなくNode IDを使って、
openclaw gateway call exec.approvals.node.get \
--params '{"nodeId":"<Node ID>"}'
を実行します。
これでWindows Companion側のExec Approval設定を取得できます。
Exec Approvalの設定例
今回取得できた設定では、概ね次のような状態でした。
{
"defaults": {
"security": "full",
"ask": "off",
"askFallback": "deny",
"autoAllowSkills": false
},
"agents": {
"main": {
"security": "full",
"ask": "off",
"askFallback": "deny",
"allowlist": [
{
"pattern": "C:\\WINDOWS\\system32\\whoami.EXE",
"source": "allow-always"
},
{
"pattern": "C:\\WINDOWS\\system32\\hostname.exe",
"source": "allow-always"
}
]
}
}
}
つまりWindows側では、
security = full
ask = off
になっており、
whoami.exe
hostname.exe
もすでに永続許可されていました。
この時点で、
Windows Node側のallowlist不足
は主原因ではないと判断できます。
agent=”*” のallowlistはリモート変更できない
Gateway側からWindows Nodeのallowlistを追加しようとすると、
Remote exec approval updates cannot add or change
allowlist entries for agent '*'.
というエラーになる場合があります。
これは不具合というより、セキュリティ上の制約です。
Windows Node側の全Agent共通allowlistを、Gatewayから勝手に変更できないようにしています。
つまり、
Windowsの所有者がローカルで許可する
という境界が保たれています。
elevated=true が原因で失敗するケース
調査中、かなり重要なログが出ました。
exec failed: elevated is not available right now
さらに、
Failing gates: allowFrom
と表示されました。
このときAgentが実際に送ろうとしていたパラメータを見ると、
{
"elevated": true,
"host": "node"
}
となっていました。
つまり、Windows Node接続やExec Approval以前に、
管理者権限で実行しようとした
↓
Mattermost経由ではelevated実行が許可されていない
↓
OpenClaw側で拒否
という状態です。
hostname.exeにはelevatedは不要
例えば、
hostname.exe
whoami.exe
Desktopのファイル一覧取得
といった処理には通常、管理者権限は必要ありません。
そのためテスト時には、
host=node
elevated=false
を明示する方が切り分けしやすくなります。
例えばAgentへの指示は、
Windows Nodeでexecツールを使って
C:\Windows\System32\hostname.exe
を実行してください。
host=node
elevated=false
のようにします。
tools.elevatedが未設定でも問題ない
確認のため、
openclaw config get tools.elevated
を実行すると、
Config path not found: tools.elevated
となることがあります。
これは、
tools.elevated
がまだ設定されていないというだけです。
通常のWindowsコマンドを elevated=false で動かす限り、必ずしも設定する必要はありません。
逆にMattermostやDiscordから管理者権限実行を許可すると非常に強い権限になるため、必要になるまで設定しない方が安全です。
tools.profileでnodesが消えていてもexecは使える
Gatewayログには、
tool policy removed ... nodes ...
といった表示もありました。
例えば、
tools.profile = coding
などのTool Profileによって、
nodes
gateway
message
...
がAgentから除外されることがあります。
しかし今回重要なのは、
exec
が削除されていないことです。
Agent自身が nodes ツールを直接操作しなくても、
exec
host=node
によってGateway内部でWindows Nodeの system.run へルーティングできます。
したがって、
nodesツールがAgentから見えない
こと自体は、今回の主要原因ではありませんでした。
OpenAIがrate limitになってGeminiへfallbackしていた
調査中のログでは、
requested=openai/...
reason=rate_limit
next=google/gemini-2.5-flash
というモデルフォールバックも発生していました。
つまり、
OpenAIモデル
↓ rate limit / cooldown
Gemini 2.5 Flash
へ切り替わっていました。
これはNode接続の問題とは別です。
ただし、モデルが変わることで、
execを使うか
elevated=trueを付けるか
説明だけ返して終わるか
といったTool Callingの挙動が変わる可能性はあります。
実際、一度はAgentが exec をまったく呼ばず、文章だけ返して終了したケースもありました。
そのときGatewayログには、
node.invoke
が一度も出ませんでした。
一方で、
必ずexecツールを使う
host=node
elevated=false
と明示したところ、再び node.invoke が発生しました。
Nortonを無効化しても根本原因は変わらなかった
Windows側にセキュリティソフトがあるため、一時的にリアルタイム保護を停止して切り分けも行いました。
しかしNortonを停止した状態でも、
elevated is not available
などOpenClaw側のエラーが発生しました。
そのため今回のケースでは、
Nortonが主原因
とは考えにくい結果でした。
セキュリティソフトを無効化するのは、あくまで短時間の切り分けに留めるべきです。
確認後は必ず有効に戻します。
UACとOpenClawのExec Approvalは別物
WindowsではUACも関係しますが、
OpenClaw CompanionのAllow Once
と、
Windows UACの「はい」
は別の仕組みです。
処理経路は概ね、
OpenClaw Exec Approval
↓
Windows Node
↓
Windows UAC
↓
セキュリティソフト
↓
実際のプログラム
になります。
hostname.exe や通常ユーザーのDesktop一覧取得は、通常UAC昇格を必要としません。
そのため、こうした単純なコマンドで失敗する場合は、最初からUACを疑うより、
Exec Approval
elevated設定
Node routing
を確認する方が切り分けしやすいです。
一時的にtools.exec.mode=fullでもテストした
切り分けのため、Gateway側のexec policyも一時的に、
openclaw config set tools.exec.mode full
へ変更しました。
Windows Node側も、
security = full
ask = off
だったため、
Gateway側 = full
Windows側 = full
に揃えて検証しました。
これでもNode通信そのものは成功していましたが、OpenClaw 2026.7系ではExec Approval周辺の挙動が複雑で、最終的に安定動作までは至りませんでした。
切り分けで分かったこと
今回の検証では、少なくとも以下までは正常でした。
Windows Companion接続 OK
Node pairing OK
Node connected OK
Node approved OK
system capability OK
tools.exec.host=node OK
Node RPC / node.invoke OK
Windows Exec Approval取得 OK
hostname.exe allow-always OK
whoami.exe allow-always OK
Mattermost → Agent OK
モデルfallback OK
一方で問題が残ったのは、
Agentのexecパラメータ
elevated指定
2026.7系のWindows Node approval挙動
周辺でした。
OpenClaw 2026.9.1へ更新して仕切り直すことにした
ここまで切り分けた結果、OpenClaw 2026.7系のまま細かいapproval挙動を追い続けるよりも、
OpenClaw 2026.9.1
へアップデートして、Windows Nodeまわりを再構成することにしました。
Windows NodeやExec Approvalはバージョン間で変更が多い部分なので、GatewayとCompanionの世代を近づけた方がトラブルシュートしやすいと判断しました。
アップデート前に戻したセキュリティ設定
トラブルシュートでは一時的に権限を緩めていたため、アップデート前に戻します。
tools.exec.mode
一時的に、
full
へ変更していたものを、
allowlist
または再構築時には、
ask
へ戻します。
例:
openclaw config set tools.exec.mode allowlist
Node実行先は維持します。
host = node
node = <Windows Node>
Gateway bindもloopbackへ戻す
Windowsから、
Test-NetConnection 127.0.0.1 -Port 18789
でWSL2 Gatewayへ接続できる場合、GatewayをLAN全体へ公開する必要はありません。
一時的に、
gateway.bind = lan
としていた場合は、
openclaw config set gateway.bind loopback
openclaw gateway restart
で戻します。
理想的には、
127.0.0.1:18789
だけで待ち受ける状態です。
Gateway Token認証は残す
GatewayとCompanion間ではToken認証を利用します。
例えば、
openclaw doctor --generate-gateway-token
で生成したTokenです。
Tokenは、
APIキー
パスワード
OAuthトークン
と同じく秘密情報として扱います。
ブログやGitHub、スクリーンショットには掲載しません。
Windows側のExec Approvalもfullのままにしない
切り分けのためWindows Companion側が、
security = full
ask = off
になっていた場合、再構築後は、
security = allowlist
ask = on-miss
askFallback = deny
程度へ戻すのが安全です。
つまり、
既知の許可コマンド
→ 実行
未知のコマンド
→ Windowsユーザーへ確認
確認できない
→ deny
という構成です。
elevatedは未設定のまま
MattermostやDiscordからWindows管理者権限を使えるようにすると、非常に強い権限になります。
今回の目的は、
Windowsファイル操作
ブラウザ操作
通常のPowerShell
なので、管理者権限は基本的に不要です。
そのため、
tools.elevated
は未設定のままにします。
必要になった場合だけ、送信元やAgentを限定して設定するのが安全です。
セキュリティソフトも有効に戻す
トラブルシュート中にNortonなどを一時停止した場合は、検証終了後に必ずONへ戻します。
今回のケースでは、NortonをOFFにしても問題が継続したため、主原因ではありませんでした。
常時OFFにしておく理由はありません。
最終的に戻す構成
アップデート前は次の状態を目標にします。
Gateway
├─ bind = loopback
└─ auth = token
Agent exec
├─ host = node
├─ node = Windows Node
└─ mode = allowlist / ask
Windows Companion
├─ Node Mode = ON
├─ Exec security = allowlist
├─ Ask = on-miss
└─ Ask fallback = deny
Elevated
└─ 未設定
Windows Security / Norton
└─ ON
この状態から2026.9.1へアップデートし、Windows Companionも対応する最新版へ揃えて再度テストする予定です。
まとめ
今回の検証で一番重要だったのは、
「Windows Nodeにつながらない」
と、
「Windows Nodeにつながっているが実行承認で止まる」
を分けて考えることでした。
openclaw nodes status で、
paired
connected
approved
になっていて、Gatewayログにも、
node.invoke ✓
が出ているなら、ネットワークやNode接続そのものは成功しています。
その後は、
tools.exec.host
tools.exec.mode
Windows Exec Approval
elevated
AgentのTool Calling
を順番に確認すると原因を絞り込みやすくなります。
今回の環境ではNode通信までは正常で、2026.7系のExec Approvalやelevated周辺で挙動が不安定だったため、2026.9.1へアップデートして再構築することにしました。
同じように「CompanionはConnectedなのにWindowsコマンドだけ動かない」という場合は、Node接続を最初からやり直す前に、
openclaw nodes status
openclaw config get tools.exec
とGatewayログの、
node.invoke
exec failed
elevated
approval
周辺を確認すると、かなり効率よく切り分けできます。

