OpenClaw macOS IPC 架构¶
本地 Unix socket 将节点宿主服务连接到 macOS 应用,用于执行审批和 system.run。随附的 openclaw-mac CLI 使用单独的本地控制 socket 来检查和配置主连接及已保存的 Gateway 连接。代理操作仍然通过 Gateway WebSocket 和 node.invoke 流转。基于节点的 computer.act 路径在进程内运行嵌入式 Peekaboo 自动化。独立的 Peekaboo 客户端使用 PeekabooBridge。
目标¶
- 单一 GUI 应用实例,负责所有面向 TCC 的工作(通知、屏幕录制、麦克风、语音、AppleScript)。
- 为自动化提供小型接口面:Gateway + 节点命令、进程内
computer.act,以及用于独立 UI 自动化客户端的 PeekabooBridge。 - 可预测的权限:始终使用相同的已签名 bundle ID,由 launchd 启动,因此 TCC 授予的权限会持续有效。
工作原理¶
Gateway + 节点传输¶
- 应用以本地模式运行 Gateway,并作为节点连接到它。
- 代理操作通过
node.invoke执行(例如system.run、system.notify、canvas.present)。 - 节点命令包括
canvas.present、canvas.hide、canvas.navigate、camera.list、camera.snap、camera.clip、camera.ptz.status、camera.ptz.control、screen.snapshot、screen.record、computer.act、system.run和system.notify。 - 节点会报告一个
permissions映射。代理利用它来查看屏幕、摄像头、麦克风、语音、自动化或辅助功能访问是否可用。
节点服务 + 应用 IPC¶
- 一个无头(headless)节点宿主服务连接到 Gateway WebSocket。
system.run请求通过本地 Unix socket(ExecApprovalsSocket.swift)转发到 macOS 应用。- 应用在 UI 上下文中执行 exec,必要时提示用户,并返回输出。
- socket 拥有请求的生命周期。节点取消或 socket 超时都会关闭响应读取器,从而取消原生提示或命令及其进程组。停止应用的 exec 服务器也会在释放其 socket 租约之前取消并排空所有活动请求。
- 客户端在发送一个 JSONL 请求后,仍然会半关闭其写入端。这种正常的请求 EOF 不会取消执行。响应读取器保持打开,直到结果到达。
示意图(SCI):
Agent -> Gateway -> Node Service (WS)
| IPC (UDS + token + HMAC + TTL)
v
Mac App (UI + TCC + system.run)
应用控制 socket¶
openclaw-mac 在每个 Unix 域连接上发送一个 JSONL 请求并接收一个 JSONL 响应。运行中的应用会通过其 exec-approvals 生命周期所有者来启动和停止此监听器。该共享监听器负责 socket 路径租约、受保护的文件系统清理、连接组帧以及关闭排空。它只暴露以下操作:
| 操作 | 结果与作用 |
|---|---|
status |
主连接、已保存的 Gateway 以及应用版本/构建/配置文件。 |
primary.set |
通过应用的原生连接所有者设置本地模式、SSH 传输或直接传输;返回由此产生的主连接状态。 |
primary.clear |
将主连接恢复到未配置状态;返回主连接状态。 |
gateway.list |
列出已保存的 Gateway 及其连接状态。 |
gateway.add |
通过 Gateways 标签页的登录协调器进行验证并连接;存在时返回已保存的 Gateway 和身份信息。 |
gateway.remove |
解析 ID/名称,并使用配置文件存储(profile store)的 Remove 路径,包括凭据和仪表盘数据清理。 |
gateway.reconnect |
对浏览器配置文件重新执行浏览器登录,或重新连接已保存的令牌/密码连接。 |
请求通过 operation 字符串标识操作。主连接的 SSH 设置包括 sshTarget、可选端口、identityPath 和 hostKeyPolicy(strict 或 openssh)。直接传输设置包括 url 和可选的 tlsFingerprint。携带凭据的操作在已认证请求中接受 token 或 password。CLI 从文件或 stdin 读取这些凭据。已保存 Gateway 的请求使用 name、url 和 browser,或使用 idOrName 进行移除/重新连接。匹配首先尝试精确 ID,然后尝试唯一的不区分大小写的名称。存在歧义时返回错误,并附上候选名称/ID。
默认配置文件使用 ~/.openclaw/mac-control.sock 和 ~/.openclaw/mac-control.token。命名配置文件使用对应的 ~/.openclaw-<name>/ 目录。这些路径遵循 AppProfile.stateDirectoryURL,独立于配置/状态的环境覆盖。令牌创建由应用负责。令牌必须是常规的、用户所有的文件,且权限模式为 0600。缺失或不安全的凭据会拒绝请求。客户端必须具有应用的对端 UID(getpeereid)。JSON 信封包含 nonce、毫秒级时间戳、编码后的请求,以及基于 nonce、时间戳和精确请求字节计算的 HMAC-SHA256。请求的认证 TTL 为 15 秒。成功通过认证的浏览器登录可以在协调器限定的 300 秒操作期间保持打开。
Socket 响应使用 {ok:true,result:...} 或 {ok:false,error:{code,message}}。CLI 的 --json 成功输出会解包 result。status 包含:
primary:模式、可空(nullable)传输、URL、可选的 SSH 目标/远程端口、隧道状态/本地端口,以及连接状态/版本/错误。gateways:ID、名称、URL、认证类型(token、password或browser)、可选的 Cloudflare Access 身份主体/过期时间,以及连接状态/错误。app:版本/构建/配置文件。
响应绝不包含令牌、密码、浏览器会话凭据或 Keychain 内容。saved-Gateway 的变更在签名应用内执行,由 profile 存储负责 Keychain 访问、连接退役、仪表盘 Cookie 和设备令牌清理。CLI 从不写入 saved-Gateway 注册表。
有关 shell 示例、profile 选择、安全凭据输入以及后台应用启动,请参阅 远程控制。
PeekabooBridge(UI 自动化)¶
- 内置的
computer代理工具不使用此套接字。配对的 macOS 节点会在应用进程内通过内嵌的 Peekaboo 服务执行computer.act。 - UI 自动化使用独立的 UNIX 套接字(
~/Library/Application Support/OpenClaw/<socket>)和 PeekabooBridge JSON 协议。 - 主机偏好顺序(客户端):Peekaboo.app -> Claude.app -> OpenClaw.app -> 本地执行。
- 安全性:桥接主机要求精确匹配已签名的 Peekaboo 客户端 bundle identifier,以及 Peekaboo 规范的当前/旧版发布签名者集合。
PEEKABOO_ALLOW_UNSIGNED_SOCKET_CLIENTS=1为仅 DEBUG 模式下的同 UID 逃生通道提供保护(Peekaboo 约定)。 - 详见:PeekabooBridge 用法。
操作流程¶
- 重启/重建:
scripts/restart-mac.sh会终止现有实例,通过 Swift 重新构建、重新打包并重新启动。它会自动检测可用的签名身份。如果未找到身份,则回退到--no-sign。传入--sign可要求必须签名,若没有可用密钥则失败。传入--no-sign则强制走未签名路径。打包会保留显式的SIGN_IDENTITY。否则scripts/codesign-mac-app.sh会自动检测证书。 - 单实例:应用通过
NSWorkspace.runningApplications检查重复的 bundle ID。如果发现超过一个实例,则退出(MenuBar.swift中的isDuplicateInstance())。
加固说明¶
- 对于所有特权面,建议要求 TeamID 匹配。
- PeekabooBridge:
PEEKABOO_ALLOW_UNSIGNED_SOCKET_CLIENTS=1(仅 DEBUG)可能允许本地开发中的同 UID 调用方。 - 所有通信仍仅限本地。不会暴露任何网络套接字。
- TCC 提示仅来自 GUI 应用包。请让已签名的 bundle ID 在重建过程中保持稳定。
- Exec approvals 套接字加固:文件模式
0600,共享令牌存储在state/openclaw.sqlite的exec_approvals_config行中,辅以 peer-UID 检查(getpeereid)、HMAC-SHA256 质询/响应,以及请求上的短 TTL。
相关¶
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw