Control UI (브라우저)
Control UI는 Gateway가 제공하는 소형 Vite + Lit 싱글 페이지 앱입니다:
- 기본값:
http://<host>:18789/ - 선택적 접두사:
gateway.controlUi.basePath설정 (예:/openclaw)
동일한 포트의 Gateway WebSocket에 직접 통신합니다.
빠른 열기 (로컬)
Gateway가 같은 컴퓨터에서 실행 중이면:
페이지 로드에 실패하면 먼저 Gateway를 시작하세요: openclaw gateway.
인증은 WebSocket 핸드셰이크 시 다음을 통해 제공됩니다:
connect.params.auth.tokenconnect.params.auth.password대시보드 설정 패널은 현재 브라우저 탭 세션 및 선택된 게이트웨이 URL에 대한 토큰을 유지합니다. 비밀번호는 저장되지 않습니다. 온보딩 마법사가 기본적으로 게이트웨이 토큰을 생성하므로, 첫 연결 시 여기에 붙여넣으세요.
디바이스 페어링 (첫 연결)
새 브라우저나 디바이스에서 Control UI에 연결할 때, 같은 Tailnet에서
gateway.auth.allowTailscale: true인 경우에도 Gateway는
일회성 페어링 승인을 요구합니다. 이는 무단 접근을 방지하기 위한
보안 조치입니다.
표시 내용: “disconnected (1008): pairing required”
디바이스 승인 방법:
# 대기 중인 요청 목록
openclaw devices list
# 요청 ID로 승인
openclaw devices approve <requestId>
승인되면, 해당 디바이스는 기억되며
openclaw devices revoke --device <id> --role <role>로 취소하지 않는 한 재승인이 필요하지 않습니다.
디바이스 CLI에서 토큰 교체 및 취소를 확인하세요.
참고:
- 로컬 연결 (
127.0.0.1)은 자동 승인됩니다. - 원격 연결 (LAN, Tailnet 등)은 명시적 승인이 필요합니다.
- 각 브라우저 프로필은 고유한 디바이스 ID를 생성하므로, 브라우저를 변경하거나 브라우저 데이터를 삭제하면 재페어링이 필요합니다.
언어 지원
Control UI는 첫 로드 시 브라우저 로캘에 따라 자동으로 언어를 설정할 수 있으며, 이후 Access 카드의 언어 선택기에서 변경할 수 있습니다.
- 지원 로캘:
en,zh-CN,zh-TW,pt-BR,de,es - 영어 외 번역은 브라우저에서 지연 로드됩니다.
- 선택된 로캘은 브라우저 저장소에 저장되어 다음 방문 시 재사용됩니다.
- 누락된 번역 키는 영어로 폴백합니다.
현재 지원 기능
- Gateway WS를 통한 모델과의 채팅 (
chat.history,chat.send,chat.abort,chat.inject) - 채팅에서의 도구 호출 스트리밍 + 실시간 도구 출력 카드 (에이전트 이벤트)
- 채널: WhatsApp/Telegram/Discord/Slack + 플러그인 채널 (Mattermost 등) 상태 + QR 로그인 + 채널별 설정 (
channels.status,web.login.*,config.patch) - 인스턴스: 현재 상태 목록 + 새로고침 (
system-presence) - 세션: 목록 + 세션별 thinking/fast/verbose/reasoning 재정의 (
sessions.list,sessions.patch) - 크론 작업: 목록/추가/편집/실행/활성화/비활성화 + 실행 이력 (
cron.*) - 스킬: 상태, 활성화/비활성화, 설치, API 키 업데이트 (
skills.*) - 노드: 목록 + 기능 (
node.list) - 실행 승인: 게이트웨이 또는 노드 허용 목록 편집 +
exec host=gateway/node에 대한 ask 정책 (exec.approvals.*) - 설정:
~/.openclaw/openclaw.json보기/편집 (config.get,config.set) - 설정: 검증과 함께 적용 + 재시작 (
config.apply) 및 마지막 활성 세션 깨우기 - 설정 쓰기에는 동시 편집 덮어쓰기를 방지하는 base-hash 가드가 포함됨
- 설정 스키마 + 폼 렌더링 (
config.schema, 플러그인 + 채널 스키마 포함); Raw JSON 편집기도 사용 가능 - 디버그: 상태/헬스/모델 스냅샷 + 이벤트 로그 + 수동 RPC 호출 (
status,health,models.list) - 로그: 필터/내보내기가 있는 게이트웨이 파일 로그 실시간 추적 (
logs.tail) - 업데이트: 패키지/git 업데이트 실행 + 재시작 (
update.run) 및 재시작 보고서
크론 작업 패널 참고:
- 격리된 작업의 경우 전달 기본값은 요약 알림입니다. 내부 전용 실행을 원하면 none으로 전환할 수 있습니다.
- 알림이 선택되면 채널/대상 필드가 나타납니다.
- 웹훅 모드는
delivery.mode = "webhook"과 유효한 HTTP(S) 웹훅 URL로 설정된delivery.to를 사용합니다. - 메인 세션 작업에는 웹훅 및 none 전달 모드를 사용할 수 있습니다.
- 고급 편집 컨트롤에는 실행 후 삭제, 에이전트 재정의 해제, cron 정확/분산 옵션, 에이전트 모델/thinking 재정의, best-effort 전달 토글이 포함됩니다.
- 폼 검증은 필드별 오류가 인라인으로 표시됩니다. 유효하지 않은 값이 있으면 저장 버튼이 비활성화됩니다.
cron.webhookToken을 설정하여 전용 베어러 토큰을 전송할 수 있습니다. 생략 시 인증 헤더 없이 웹훅이 전송됩니다.- 폐기 예정 폴백:
notify: true가 저장된 레거시 작업은 마이그레이션될 때까지cron.webhook을 사용할 수 있습니다.
채팅 동작
chat.send는 논블로킹입니다:{ runId, status: "started" }로 즉시 확인 응답하고, 응답은chat이벤트를 통해 스트리밍됩니다.- 같은
idempotencyKey로 재전송하면 실행 중일 때{ status: "in_flight" }를, 완료 후{ status: "ok" }를 반환합니다. chat.history응답은 UI 안전을 위해 크기가 제한됩니다. 트랜스크립트 항목이 너무 크면, Gateway가 긴 텍스트 필드를 잘라내거나, 무거운 메타데이터 블록을 생략하거나, 초과 크기 메시지를 플레이스홀더([chat.history omitted: message too large])로 대체할 수 있습니다.chat.inject는 세션 트랜스크립트에 어시스턴트 노트를 추가하고 UI 전용 업데이트를 위해chat이벤트를 브로드캐스트합니다 (에이전트 실행 없음, 채널 전달 없음).- 중지:
- 중지 클릭 (
chat.abort호출) /stop입력 (또는stop,stop action,stop run,stop openclaw,please stop과 같은 독립적인 중단 구문)하여 대역 외 중단chat.abort는 해당 세션의 모든 활성 실행을 중단하기 위해{ sessionKey }를 지원합니다 (runId불필요)
- 중지 클릭 (
- 중단 부분 유지:
- 실행이 중단되면 부분적인 어시스턴트 텍스트가 UI에 계속 표시될 수 있습니다
- Gateway는 버퍼링된 출력이 있을 때 중단된 부분 어시스턴트 텍스트를 트랜스크립트 이력에 유지합니다
- 유지된 항목에는 트랜스크립트 소비자가 중단 부분과 정상 완료 출력을 구별할 수 있도록 중단 메타데이터가 포함됩니다
Tailnet 접근 (권장)
통합 Tailscale Serve (선호)
Gateway를 루프백에 유지하고 Tailscale Serve가 HTTPS로 프록시하도록 합니다:
openclaw gateway --tailscale serve
열기:
https://<magicdns>/(또는 설정된gateway.controlUi.basePath)
기본적으로 Control UI/WebSocket Serve 요청은 gateway.auth.allowTailscale이 true일 때
Tailscale 신원 헤더(tailscale-user-login)를 통해 인증할 수 있습니다. OpenClaw는
x-forwarded-for 주소를 tailscale whois로 확인하고 헤더와 매칭하여 신원을 검증하며,
요청이 Tailscale의 x-forwarded-* 헤더와 함께 루프백에 도착할 때만 이를 수락합니다.
Serve 트래픽에도 토큰/비밀번호를 요구하려면
gateway.auth.allowTailscale: false (또는 gateway.auth.mode: "password" 강제)를 설정하세요.
토큰리스 Serve 인증은 게이트웨이 호스트가 신뢰할 수 있다고 가정합니다. 신뢰할 수 없는 로컬
코드가 해당 호스트에서 실행될 수 있으면, 토큰/비밀번호 인증을 요구하세요.
Tailnet 바인딩 + 토큰
openclaw gateway --bind tailnet --token "$(openssl rand -hex 32)"
그런 다음:
http://<tailscale-ip>:18789/(또는 설정된gateway.controlUi.basePath)
UI 설정에 토큰을 붙여넣으세요 (connect.params.auth.token으로 전송됨).
비보안 HTTP
대시보드를 일반 HTTP (http://<lan-ip> 또는 http://<tailscale-ip>)로 열면,
브라우저가 비보안 컨텍스트에서 실행되어 WebCrypto를 차단합니다. 기본적으로
OpenClaw는 디바이스 신원 없이 Control UI 연결을 차단합니다.
권장 해결 방법: HTTPS(Tailscale Serve) 사용 또는 UI를 로컬에서 열기:
https://<magicdns>/(Serve)http://127.0.0.1:18789/(게이트웨이 호스트에서)
비보안 인증 토글 동작:
{
gateway: {
controlUi: { allowInsecureAuth: true },
bind: "tailnet",
auth: { mode: "token", token: "replace-me" },
},
}
allowInsecureAuth는 로컬 호환성 토글일 뿐입니다:
- 비보안 HTTP 컨텍스트에서 localhost Control UI 세션이 디바이스 신원 없이 진행되도록 허용합니다.
- 페어링 검사를 우회하지 않습니다.
- 원격(비localhost) 디바이스 신원 요구사항을 완화하지 않습니다.
긴급 사용 전용:
{
gateway: {
controlUi: { dangerouslyDisableDeviceAuth: true },
bind: "tailnet",
auth: { mode: "token", token: "replace-me" },
},
}
dangerouslyDisableDeviceAuth는 Control UI 디바이스 신원 검사를 비활성화하며
심각한 보안 저하입니다. 긴급 사용 후 빠르게 원복하세요.
Tailscale에서 HTTPS 설정 가이드를 확인하세요.
UI 빌드
Gateway는 dist/control-ui의 정적 파일을 제공합니다. 다음으로 빌드하세요:
pnpm ui:build # 첫 실행 시 UI 의존성 자동 설치
선택적 절대 경로 (고정 에셋 URL이 필요한 경우):
OPENCLAW_CONTROL_UI_BASE_PATH=/openclaw/ pnpm ui:build
로컬 개발 (별도 개발 서버):
pnpm ui:dev # 첫 실행 시 UI 의존성 자동 설치
그런 다음 UI에서 Gateway WS URL을 지정하세요 (예: ws://127.0.0.1:18789).
디버깅/테스트: 개발 서버 + 원격 Gateway
Control UI는 정적 파일이며, WebSocket 대상은 설정 가능하고 HTTP 오리진과 다를 수 있습니다. 로컬에서 Vite 개발 서버를 실행하면서 Gateway가 다른 곳에서 실행될 때 유용합니다.
- UI 개발 서버 시작:
pnpm ui:dev - 다음과 같은 URL 열기:
http://localhost:5173/?gatewayUrl=ws://<gateway-host>:18789
선택적 일회성 인증 (필요한 경우):
http://localhost:5173/?gatewayUrl=wss://<gateway-host>:18789#token=<gateway-token>
참고:
gatewayUrl은 로드 후 localStorage에 저장되고 URL에서 제거됩니다.token은 URL 프래그먼트에서 가져와 현재 브라우저 탭 세션 및 선택된 게이트웨이 URL에 대해 sessionStorage에 저장되고 URL에서 제거됩니다. localStorage에는 저장되지 않습니다.password는 메모리에만 유지됩니다.gatewayUrl이 설정되면, UI는 설정이나 환경 자격 증명으로 폴백하지 않습니다.token(또는password)을 명시적으로 제공하세요. 명시적 자격 증명 누락은 오류입니다.- Gateway가 TLS 뒤에 있을 때 (Tailscale Serve, HTTPS 프록시 등)
wss://를 사용하세요. gatewayUrl은 클릭재킹 방지를 위해 최상위 창에서만 허용됩니다 (임베디드 불가).- 비루프백 Control UI 배포는
gateway.controlUi.allowedOrigins를 명시적으로 설정해야 합니다 (전체 오리진). 원격 개발 설정도 포함됩니다. gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true는 Host 헤더 오리진 폴백 모드를 활성화하지만, 위험한 보안 모드입니다.
예시:
{
gateway: {
controlUi: {
allowedOrigins: ["http://localhost:5173"],
},
},
}
원격 접근 설정 세부사항: 원격 접근.