{
  "title": "OpenClaw macOS IPC architecture",
  "content": "**Current model:** a local Unix socket connects the **node host service** to the **macOS app** for exec approvals + `system.run`. A `openclaw-mac` debug CLI exists for discovery/connect checks; agent actions still flow through the Gateway WebSocket and `node.invoke`. UI automation uses PeekabooBridge.\n\n* Single GUI app instance that owns all TCC-facing work (notifications, screen recording, mic, speech, AppleScript).\n* A small surface for automation: Gateway + node commands, plus PeekabooBridge for UI automation.\n* Predictable permissions: always the same signed bundle ID, launched by launchd, so TCC grants stick.\n\n### Gateway + node transport\n\n* The app runs the Gateway (local mode) and connects to it as a node.\n* Agent actions are performed via `node.invoke` (e.g. `system.run`, `system.notify`, `canvas.*`).\n\n### Node service + app IPC\n\n* A headless node host service connects to the Gateway WebSocket.\n* `system.run` requests are forwarded to the macOS app over a local Unix socket.\n* The app performs the exec in UI context, prompts if needed, and returns output.\n\n### PeekabooBridge (UI automation)\n\n* UI automation uses a separate UNIX socket named `bridge.sock` and the PeekabooBridge JSON protocol.\n* Host preference order (client-side): Peekaboo.app → Claude.app → OpenClaw\\.app → local execution.\n* Security: bridge hosts require an allowed TeamID; DEBUG-only same-UID escape hatch is guarded by `PEEKABOO_ALLOW_UNSIGNED_SOCKET_CLIENTS=1` (Peekaboo convention).\n* See: [PeekabooBridge usage](/platforms/mac/peekaboo) for details.\n\n* Restart/rebuild: `SIGN_IDENTITY=\"Apple Development: <Developer Name> (<TEAMID>)\" scripts/restart-mac.sh`\n  * Kills existing instances\n  * Swift build + package\n  * Writes/bootstraps/kickstarts the LaunchAgent\n* Single instance: app exits early if another instance with the same bundle ID is running.\n\n* Prefer requiring a TeamID match for all privileged surfaces.\n* PeekabooBridge: `PEEKABOO_ALLOW_UNSIGNED_SOCKET_CLIENTS=1` (DEBUG-only) may allow same-UID callers for local development.\n* All communication remains local-only; no network sockets are exposed.\n* TCC prompts originate only from the GUI app bundle; keep the signed bundle ID stable across rebuilds.\n* IPC hardening: socket mode `0600`, token, peer-UID checks, HMAC challenge/response, short TTL.",
  "code_samples": [
    {
      "code": "Agent -> Gateway -> Node Service (WS)\n                      |  IPC (UDS + token + HMAC + TTL)\n                      v\n                  Mac App (UI + TCC + system.run)",
      "language": "unknown"
    }
  ],
  "headings": [
    {
      "level": "h2",
      "text": "Goals",
      "id": "goals"
    },
    {
      "level": "h2",
      "text": "How it works",
      "id": "how-it-works"
    },
    {
      "level": "h3",
      "text": "Gateway + node transport",
      "id": "gateway-+-node-transport"
    },
    {
      "level": "h3",
      "text": "Node service + app IPC",
      "id": "node-service-+-app-ipc"
    },
    {
      "level": "h3",
      "text": "PeekabooBridge (UI automation)",
      "id": "peekaboobridge-(ui-automation)"
    },
    {
      "level": "h2",
      "text": "Operational flows",
      "id": "operational-flows"
    },
    {
      "level": "h2",
      "text": "Hardening notes",
      "id": "hardening-notes"
    }
  ],
  "url": "llms-txt#openclaw-macos-ipc-architecture",
  "links": []
}