Gateway-owned pairing (Option B)

Trong Gateway-owned pairing, Gateway là nguồn chân lý (source of truth) quyết định node nào được phép tham gia. Các UI (ứng dụng macOS, client tương lai) chỉ là frontend để phê duyệt hoặc từ chối các yêu cầu đang chờ.

Quan trọng: WS node sử dụng device pairing (role node) trong quá trình connect. node.pair.* là một pairing store riêng biệt và không kiểm soát WS handshake. Chỉ các client gọi node.pair.* một cách rõ ràng mới sử dụng flow này.

Các khái niệm

  • Pending request: một node yêu cầu tham gia; cần được phê duyệt.
  • Paired node: node đã được phê duyệt với auth token đã cấp.
  • Transport: Gateway WS endpoint chuyển tiếp request nhưng không quyết định membership. (Hỗ trợ legacy TCP bridge đã deprecated/bị xóa.)

Cách Pairing hoạt động

  1. Một node kết nối tới Gateway WS và yêu cầu pairing.
  2. Gateway lưu trữ pending request và phát ra sự kiện node.pair.requested.
  3. Các bạn phê duyệt hoặc từ chối request (qua CLI hoặc UI).
  4. Khi phê duyệt, Gateway cấp một token mới (token được rotate khi re-pair).
  5. Node kết nối lại bằng token và giờ đã “paired”.

Các pending request tự động hết hạn sau 5 phút.

CLI workflow (thân thiện với headless)

openclaw nodes pending
openclaw nodes approve <requestId>
openclaw nodes reject <requestId>
openclaw nodes status
openclaw nodes rename --node <id|name|ip> --name "Living Room iPad"

nodes status hiển thị các node đã paired/connected và khả năng của chúng.

API surface (gateway protocol)

Events:

  • node.pair.requested — phát ra khi một pending request mới được tạo.
  • node.pair.resolved — phát ra khi một request được approved/rejected/expired.

Methods:

  • node.pair.request — tạo hoặc tái sử dụng một pending request.
  • node.pair.list — liệt kê các node pending + paired.
  • node.pair.approve — phê duyệt một pending request (cấp token).
  • node.pair.reject — từ chối một pending request.
  • node.pair.verify — xác minh { nodeId, token }.

Lưu ý:

  • node.pair.request là idempotent cho mỗi node: các lần gọi lặp lại trả về cùng một pending request.
  • Phê duyệt luôn luôn tạo ra token mới; không bao giờ trả về token từ node.pair.request.
  • Request có thể bao gồm silent: true như một gợi ý cho auto-approval flow.

Auto-approval (ứng dụng macOS)

Ứng dụng macOS có thể tùy chọn thử silent approval khi:

  • request được đánh dấu silent, và
  • ứng dụng có thể xác minh kết nối SSH tới gateway host bằng cùng user.

Nếu silent approval thất bại, nó sẽ quay lại prompt “Approve/Reject” bình thường.

Storage (local, private)

Trạng thái Pairing được lưu trữ trong thư mục state của Gateway (mặc định ~/.openclaw):

  • ~/.openclaw/nodes/paired.json
  • ~/.openclaw/nodes/pending.json

Nếu các bạn override OPENCLAW_STATE_DIR, thư mục nodes/ sẽ di chuyển theo.

Lưu ý bảo mật:

  • Token là thông tin bí mật; coi paired.json là nhạy cảm.
  • Rotate token yêu cầu phê duyệt lại (hoặc xóa node entry).

Hành vi Transport

  • Transport là stateless; nó không lưu trữ membership.
  • Nếu Gateway offline hoặc pairing bị tắt, các node không thể pair.
  • Nếu Gateway ở chế độ remote, pairing vẫn diễn ra với store của Gateway remote.