브리지 프로토콜(레거시 노드 전송)
왜 존재했는가
- 보안 경계: 브리지는 전체 gateway API 표면 대신 작은 허용 목록을 노출합니다.
- 페어링 + 노드 정체성: 노드 승인(admission)은 gateway가 소유하며 노드별 토큰에 연결됩니다.
- 검색 UX: 노드는 LAN에서 Bonjour를 통해 gateway를 검색하거나 tailnet을 통해 직접 연결할 수 있습니다.
- 루프백 WS: 전체 WS 제어 평면은 SSH를 통해 터널링하지 않는 한 로컬에 유지됩니다.
전송
- TCP, 한 줄당 하나의 JSON 객체(JSONL)
- 선택적 TLS (
bridge.tls.enabled가 true일 때) - 과거 기본 리스너 포트는
18790이었습니다(현재 빌드는 TCP 브리지를 시작하지 않음)
bridgeTls=1과 bridgeTlsSha256이 포함됩니다. Bonjour/mDNS TXT 레코드는 인증되지 않는다는 점에 유의하세요. 클라이언트는 명시적인 사용자 의도나 다른 대역 외 검증 없이 광고된 지문을 권위 있는 pin으로 취급해서는 안 됩니다.
핸드셰이크 + 페어링
- 클라이언트가 노드 메타데이터 + 토큰(이미 페어링된 경우 포함)으로
hello를 보냅니다. - 페어링되지 않은 경우 gateway는
error(NOT_PAIRED/UNAUTHORIZED)로 응답합니다. - 클라이언트가
pair-request를 보냅니다. - gateway는 승인을 기다린 뒤
pair-ok와hello-ok를 보냅니다.
hello-ok가 serverName을 반환했고 canvasHostUrl을 포함할 수 있었습니다.
프레임
클라이언트 → Gateway:req/res: 범위 제한 gateway RPC (chat,sessions,config,health,voicewake,skills.bins)event: 노드 신호(음성 전사, 에이전트 요청, 채팅 구독, exec 수명 주기)
invoke/invoke-res: 노드 명령(canvas.*,camera.*,screen.record,location.get,sms.send)event: 구독된 세션의 채팅 업데이트ping/pong: 연결 유지
src/gateway/server-bridge.ts에 있었습니다(제거됨).
Exec 수명 주기 이벤트
노드는system.run 활동을 노출하기 위해 exec.finished 또는 exec.denied 이벤트를 보낼 수 있습니다.
이 이벤트들은 gateway에서 시스템 이벤트로 매핑됩니다. (레거시 노드는 여전히 exec.started를 보낼 수 있습니다.)
payload 필드(명시되지 않은 한 모두 선택 사항):
sessionKey(필수): 시스템 이벤트를 받을 에이전트 세션runId: 그룹화를 위한 고유 exec IDcommand: 원시 또는 형식화된 명령 문자열exitCode,timedOut,success,output: 완료 세부 정보(finished전용)reason: 거부 사유(denied전용)
과거의 tailnet 사용
- 브리지를 tailnet IP에 바인딩:
~/.openclaw/openclaw.json에서bridge.bind: "tailnet"설정(역사적 참조 전용,bridge.*는 더 이상 유효하지 않음) - 클라이언트는 MagicDNS 이름 또는 tailnet IP를 통해 연결
- Bonjour는 네트워크를 넘지 않습니다. 필요할 때는 수동 host/port 또는 광역 DNS-SD를 사용하세요.