Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.openclaw.ai/llms.txt

Use this file to discover all available pages before exploring further.

Control UI เป็นแอปหน้าเดียว Vite + Lit ขนาดเล็กที่ Gateway ให้บริการ:
  • ค่าเริ่มต้น: http://<host>:18789/
  • คำนำหน้าเสริม: ตั้งค่า gateway.controlUi.basePath (เช่น /openclaw)
แอปนี้สื่อสาร โดยตรงกับ Gateway WebSocket บนพอร์ตเดียวกัน

เปิดอย่างรวดเร็ว (ภายในเครื่อง)

หาก Gateway กำลังทำงานบนคอมพิวเตอร์เครื่องเดียวกัน ให้เปิด: หากหน้าเว็บโหลดไม่สำเร็จ ให้เริ่ม Gateway ก่อน: openclaw gateway ระบบส่งข้อมูลยืนยันตัวตนระหว่างการ handshake ของ WebSocket ผ่าน:
  • connect.params.auth.token
  • connect.params.auth.password
  • ส่วนหัวข้อมูลประจำตัวของ Tailscale Serve เมื่อ gateway.auth.allowTailscale: true
  • ส่วนหัวข้อมูลประจำตัวของ trusted-proxy เมื่อ gateway.auth.mode: "trusted-proxy"
แผงการตั้งค่าแดชบอร์ดจะเก็บโทเค็นไว้สำหรับเซสชันแท็บเบราว์เซอร์ปัจจุบันและ URL Gateway ที่เลือก ส่วนรหัสผ่านจะไม่ถูกจัดเก็บ โดยปกติ onboarding จะสร้างโทเค็น Gateway สำหรับการยืนยันตัวตนแบบ shared-secret เมื่อเชื่อมต่อครั้งแรก แต่การยืนยันตัวตนด้วยรหัสผ่านก็ใช้ได้เช่นกันเมื่อ gateway.auth.mode เป็น "password"

การจับคู่อุปกรณ์ (การเชื่อมต่อครั้งแรก)

เมื่อคุณเชื่อมต่อกับ Control UI จากเบราว์เซอร์หรืออุปกรณ์ใหม่ Gateway มักจะต้องมี การอนุมัติการจับคู่แบบครั้งเดียว นี่เป็นมาตรการรักษาความปลอดภัยเพื่อป้องกันการเข้าถึงโดยไม่ได้รับอนุญาต สิ่งที่คุณจะเห็น: “disconnected (1008): pairing required”
1

แสดงรายการคำขอที่รอดำเนินการ

openclaw devices list
2

อนุมัติด้วย request ID

openclaw devices approve <requestId>
หากเบราว์เซอร์ลองจับคู่อีกครั้งพร้อมรายละเอียดการยืนยันตัวตนที่เปลี่ยนไป (role/scopes/public key) คำขอที่รอดำเนินการก่อนหน้าจะถูกแทนที่ และจะสร้าง requestId ใหม่ ให้รัน openclaw devices list อีกครั้งก่อนอนุมัติ หากเบราว์เซอร์ถูกจับคู่อยู่แล้ว และคุณเปลี่ยนจากสิทธิ์อ่านเป็นสิทธิ์เขียน/admin ระบบจะถือว่านี่เป็นการอัปเกรดการอนุมัติ ไม่ใช่การเชื่อมต่อใหม่แบบเงียบ OpenClaw จะคงการอนุมัติเก่าไว้ บล็อกการเชื่อมต่อใหม่ที่มีสิทธิ์กว้างขึ้น และขอให้คุณอนุมัติชุด scope ใหม่อย่างชัดเจน เมื่ออนุมัติแล้ว ระบบจะจดจำอุปกรณ์นั้น และจะไม่ต้องอนุมัติซ้ำ เว้นแต่คุณจะเพิกถอนด้วย openclaw devices revoke --device <id> --role <role> ดู Devices CLI สำหรับการหมุนเวียนและการเพิกถอนโทเค็น
  • การเชื่อมต่อเบราว์เซอร์ผ่าน local loopback โดยตรง (127.0.0.1 / localhost) จะได้รับการอนุมัติอัตโนมัติ
  • Tailscale Serve สามารถข้ามรอบการจับคู่สำหรับเซสชันผู้ปฏิบัติงาน Control UI ได้เมื่อ gateway.auth.allowTailscale: true, ยืนยันตัวตน Tailscale สำเร็จ และเบราว์เซอร์แสดงข้อมูลประจำตัวอุปกรณ์ของตน
  • การ bind กับ Tailnet โดยตรง, การเชื่อมต่อเบราว์เซอร์ผ่าน LAN และโปรไฟล์เบราว์เซอร์ที่ไม่มีข้อมูลประจำตัวอุปกรณ์ ยังต้องได้รับการอนุมัติอย่างชัดเจน
  • แต่ละโปรไฟล์เบราว์เซอร์จะสร้าง ID อุปกรณ์ที่ไม่ซ้ำกัน ดังนั้นการสลับเบราว์เซอร์หรือล้างข้อมูลเบราว์เซอร์จะต้องจับคู่ใหม่

ข้อมูลประจำตัวส่วนบุคคล (เฉพาะเบราว์เซอร์)

Control UI รองรับข้อมูลประจำตัวส่วนบุคคลต่อเบราว์เซอร์ (ชื่อที่แสดงและอวตาร) ซึ่งแนบกับข้อความขาออกเพื่อระบุที่มาในเซสชันที่แชร์ ข้อมูลนี้อยู่ในพื้นที่จัดเก็บของเบราว์เซอร์ ถูกจำกัดขอบเขตไว้ที่โปรไฟล์เบราว์เซอร์ปัจจุบัน และจะไม่ซิงก์ไปยังอุปกรณ์อื่นหรือเก็บถาวรฝั่งเซิร์ฟเวอร์ นอกเหนือจาก metadata ผู้เขียนตามปกติใน transcript ของข้อความที่คุณส่งจริง การล้างข้อมูลไซต์หรือสลับเบราว์เซอร์จะรีเซ็ตค่าให้ว่าง รูปแบบเฉพาะเบราว์เซอร์เดียวกันนี้ใช้กับการแทนที่อวตารของผู้ช่วยด้วย อวตารผู้ช่วยที่อัปโหลดจะซ้อนทับข้อมูลประจำตัวที่ Gateway resolve แล้วบนเบราว์เซอร์ภายในเครื่องเท่านั้น และจะไม่ส่งวนกลับผ่าน config.patch ฟิลด์ config ที่แชร์ชื่อ ui.assistant.avatar ยังพร้อมใช้งานสำหรับไคลเอนต์ที่ไม่ใช่ UI ซึ่งเขียนฟิลด์นี้โดยตรง (เช่น Gateway แบบสคริปต์หรือแดชบอร์ดแบบกำหนดเอง)

endpoint การตั้งค่ารันไทม์

Control UI ดึงการตั้งค่ารันไทม์จาก /__openclaw/control-ui-config.json endpoint นี้ถูกควบคุมด้วยการยืนยันตัวตน Gateway แบบเดียวกับพื้นผิว HTTP ส่วนที่เหลือ: เบราว์เซอร์ที่ไม่ได้ยืนยันตัวตนจะดึงข้อมูลไม่ได้ และการดึงข้อมูลสำเร็จต้องมีโทเค็น/รหัสผ่าน Gateway ที่ถูกต้องอยู่แล้ว, ข้อมูลประจำตัว Tailscale Serve หรือข้อมูลประจำตัว trusted-proxy

การรองรับภาษา

Control UI สามารถแปลตัวเองตาม locale ของเบราว์เซอร์ในการโหลดครั้งแรก หากต้องการเปลี่ยนในภายหลัง ให้เปิด Overview -> Gateway Access -> Language ตัวเลือก locale อยู่ในการ์ด Gateway Access ไม่ได้อยู่ใต้ Appearance
  • locale ที่รองรับ: en, zh-CN, zh-TW, pt-BR, de, es, ja-JP, ko, fr, ar, it, tr, uk, id, pl, th, vi, nl, fa
  • คำแปลที่ไม่ใช่ภาษาอังกฤษจะถูกโหลดแบบ lazy-load ในเบราว์เซอร์
  • locale ที่เลือกจะถูกบันทึกในพื้นที่จัดเก็บของเบราว์เซอร์และนำมาใช้ซ้ำในการเข้าชมครั้งถัดไป
  • คีย์คำแปลที่ขาดหายจะย้อนกลับไปใช้ภาษาอังกฤษ
คำแปลเอกสารถูกสร้างสำหรับชุด locale ที่ไม่ใช่ภาษาอังกฤษชุดเดียวกัน แต่ตัวเลือกภาษาของไซต์เอกสารที่ Mintlify มีในตัวจะจำกัดอยู่ที่รหัส locale ที่ Mintlify ยอมรับ เอกสารภาษาไทย (th) และเปอร์เซีย (fa) ยังคงถูกสร้างใน repo สำหรับเผยแพร่ แต่อาจยังไม่ปรากฏในตัวเลือกนั้นจนกว่า Mintlify จะรองรับรหัสเหล่านั้น

ธีม Appearance

แผง Appearance จะคงธีมในตัว Claw, Knot และ Dash รวมถึงช่องนำเข้า tweakcn เฉพาะเบราว์เซอร์หนึ่งช่อง หากต้องการนำเข้าธีม ให้เปิด tweakcn editor, เลือกหรือสร้างธีม, คลิก Share แล้ววางลิงก์ธีมที่คัดลอกไว้ใน Appearance ตัวนำเข้ายังรองรับ URL registry แบบ https://tweakcn.com/r/themes/<id>, URL editor เช่น https://tweakcn.com/editor/theme?theme=amethyst-haze, พาธสัมพัทธ์ /themes/<id>, ID ธีมดิบ และชื่อธีมเริ่มต้น เช่น amethyst-haze ธีมที่นำเข้าจะถูกเก็บไว้เฉพาะในโปรไฟล์เบราว์เซอร์ปัจจุบันเท่านั้น ธีมจะไม่ถูกเขียนลง config ของ Gateway และไม่ซิงก์ข้ามอุปกรณ์ การแทนที่ธีมที่นำเข้าจะอัปเดตช่องภายในเครื่องหนึ่งช่อง การล้างธีมจะสลับธีมที่ใช้งานกลับไปเป็น Claw หากธีมที่นำเข้าเคยถูกเลือกอยู่

สิ่งที่ทำได้ (วันนี้)

  • แชทกับโมเดลผ่าน Gateway WS (chat.history, chat.send, chat.abort, chat.inject)
  • การรีเฟรชประวัติแชทจะขอหน้าต่างล่าสุดที่จำกัดขอบเขต พร้อมเพดานข้อความต่อข้อความ เพื่อให้เซสชันขนาดใหญ่ไม่บังคับให้เบราว์เซอร์เรนเดอร์ payload transcript เต็มก่อนที่แชทจะพร้อมใช้งาน
  • พูดคุยผ่านเซสชันแบบเรียลไทม์ของเบราว์เซอร์ OpenAI ใช้ WebRTC โดยตรง, Google Live ใช้โทเค็นเบราว์เซอร์แบบใช้ครั้งเดียวที่ถูกจำกัดผ่าน WebSocket และ Plugin เสียงเรียลไทม์แบบ backend-only ใช้ transport relay ของ Gateway เซสชัน provider ที่ไคลเอนต์เป็นเจ้าของเริ่มด้วย talk.client.create; เซสชัน Gateway relay เริ่มด้วย talk.session.create relay จะเก็บข้อมูลรับรอง provider ไว้บน Gateway ขณะที่เบราว์เซอร์สตรีมไมโครโฟน PCM ผ่าน talk.session.appendAudio และส่งต่อการเรียก tool ของ provider openclaw_agent_consult ผ่าน talk.client.toolCall เพื่อใช้นโยบาย Gateway และโมเดล OpenClaw ที่กำหนดค่าไว้ซึ่งใหญ่กว่า
  • สตรีมการเรียก tool + การ์ดผลลัพธ์ tool แบบสดใน Chat (เหตุการณ์ agent)
  • ช่องทาง: สถานะช่องทางในตัวและช่องทางจาก Plugin ที่ bundled/ภายนอก, การเข้าสู่ระบบด้วย QR และ config ต่อช่องทาง (channels.status, web.login.*, config.patch)
  • การรีเฟรช probe ของช่องทางจะคง snapshot ก่อนหน้าให้มองเห็นอยู่ขณะที่การตรวจสอบ provider ที่ช้ากำลังเสร็จสิ้น และ snapshot บางส่วนจะถูกติดป้ายเมื่อ probe หรือ audit เกินงบเวลา UI
  • Instances: รายการ presence + รีเฟรช (system-presence)
  • Sessions: แสดงรายการเซสชัน configured-agent ตามค่าเริ่มต้น, fallback จากคีย์เซสชัน agent ที่ไม่ได้กำหนดค่าและค้างอยู่ และใช้การ override model/thinking/fast/verbose/trace/reasoning ต่อเซสชัน (sessions.list, sessions.patch)
  • Dreams: สถานะ dreaming, สวิตช์ enable/disable และตัวอ่าน Dream Diary (doctor.memory.status, doctor.memory.dreamDiary, config.patch)
  • งาน Cron: list/add/edit/run/enable/disable + ประวัติการรัน (cron.*)
  • Skills: สถานะ, enable/disable, ติดตั้ง, อัปเดต API key (skills.*)
  • Nodes: list + caps (node.list)
  • การอนุมัติ exec: แก้ไข allowlist ของ gateway หรือ node + นโยบาย ask สำหรับ exec host=gateway/node (exec.approvals.*)
  • ดู/แก้ไข ~/.openclaw/openclaw.json (config.get, config.set)
  • Apply + restart พร้อม validation (config.apply) และปลุกเซสชันล่าสุดที่ใช้งานอยู่
  • การเขียนมี guard แบบ base-hash เพื่อป้องกันการเขียนทับการแก้ไขที่เกิดขึ้นพร้อมกัน
  • การเขียน (config.set/config.apply/config.patch) จะ preflight การ resolve SecretRef ที่ active สำหรับ refs ใน payload config ที่ส่งมา; refs ที่ส่งมาและ active แต่ resolve ไม่ได้จะถูกปฏิเสธก่อนเขียน
  • Schema + การเรนเดอร์ฟอร์ม (config.schema / config.schema.lookup, รวมถึงฟิลด์ title / description, UI hints ที่ match, สรุป child โดยตรง, metadata เอกสารบนโหนด object/wildcard/array/composition แบบซ้อน รวมถึง schema ของ Plugin + ช่องทางเมื่อมี); Raw JSON editor พร้อมใช้งานเฉพาะเมื่อ snapshot มี raw round-trip ที่ปลอดภัย
  • หาก snapshot ไม่สามารถ round-trip ข้อความดิบได้อย่างปลอดภัย Control UI จะบังคับโหมด Form และปิดใช้โหมด Raw สำหรับ snapshot นั้น
  • Raw JSON editor “Reset to saved” จะรักษารูปทรงที่เขียนแบบ raw ไว้ (การจัดรูปแบบ, ความคิดเห็น, layout ของ $include) แทนการเรนเดอร์ snapshot ที่ flatten ใหม่ เพื่อให้การแก้ไขภายนอกยังอยู่รอดหลัง reset เมื่อ snapshot สามารถ round-trip ได้อย่างปลอดภัย
  • ค่า object แบบ Structured SecretRef จะแสดงเป็นแบบอ่านอย่างเดียวใน input ข้อความของฟอร์ม เพื่อป้องกันความเสียหายจากการแปลง object เป็น string โดยไม่ตั้งใจ
  • Debug: snapshot ของ status/health/models + event log + การเรียก RPC แบบ manual (status, health, models.list)
  • event log มีเวลาของการรีเฟรช/RPC ใน Control UI, เวลาการเรนเดอร์แชท/config ที่ช้า และรายการความตอบสนองของเบราว์เซอร์สำหรับ animation frame ที่ยาวหรืองานที่ยาว เมื่อเบราว์เซอร์เปิดเผยชนิดรายการ PerformanceObserver เหล่านั้น
  • Logs: tail สดของไฟล์ log ของ gateway พร้อม filter/export (logs.tail)
  • Update: รันการอัปเดต package/git + restart (update.run) พร้อมรายงานการ restart จากนั้น poll update.status หลังเชื่อมต่อใหม่เพื่อตรวจสอบเวอร์ชัน gateway ที่กำลังรันอยู่
  • สำหรับงานแบบ isolated ค่า delivery เริ่มต้นคือประกาศสรุป คุณสามารถสลับเป็น none ได้หากต้องการรันภายในเท่านั้น
  • ฟิลด์ช่องทาง/target จะปรากฏเมื่อเลือก announce
  • โหมด Webhook ใช้ delivery.mode = "webhook" โดยตั้งค่า delivery.to เป็น URL webhook HTTP(S) ที่ถูกต้อง
  • สำหรับงาน main-session มีโหมด delivery แบบ webhook และ none ให้ใช้
  • ตัวควบคุมแก้ไขขั้นสูงประกอบด้วย delete-after-run, clear agent override, ตัวเลือก cron exact/stagger, การ override agent model/thinking และสวิตช์ best-effort delivery
  • การตรวจสอบความถูกต้องของฟอร์มเป็นแบบ inline พร้อมข้อผิดพลาดระดับฟิลด์; ค่าที่ไม่ถูกต้องจะปิดใช้ปุ่มบันทึกจนกว่าจะแก้ไข
  • ตั้งค่า cron.webhookToken เพื่อส่ง bearer token เฉพาะ หากละไว้ webhook จะถูกส่งโดยไม่มีส่วนหัว auth
  • fallback ที่เลิกใช้แล้ว: งาน legacy ที่จัดเก็บไว้พร้อม notify: true ยังสามารถใช้ cron.webhook ได้จนกว่าจะ migrate

พฤติกรรมของ Chat

  • chat.send เป็นแบบ ไม่บล็อกการทำงาน: ยืนยันรับทันทีด้วย { runId, status: "started" } และคำตอบจะสตรีมผ่านเหตุการณ์ chat
  • การอัปโหลดแชตรองรับรูปภาพและไฟล์ที่ไม่ใช่วิดีโอ รูปภาพจะคงเส้นทางรูปภาพดั้งเดิมไว้ ส่วนไฟล์อื่นจะถูกจัดเก็บเป็นสื่อที่จัดการแล้วและแสดงในประวัติเป็นลิงก์ไฟล์แนบ
  • การส่งซ้ำด้วย idempotencyKey เดิมจะส่งคืน { status: "in_flight" } ขณะกำลังทำงาน และ { status: "ok" } หลังเสร็จสิ้น
  • คำตอบของ chat.history ถูกจำกัดขนาดเพื่อความปลอดภัยของ UI เมื่อรายการถอดความมีขนาดใหญ่เกินไป Gateway อาจตัดทอนฟิลด์ข้อความยาว ๆ ละเว้นบล็อกข้อมูลเมตาขนาดใหญ่ และแทนที่ข้อความที่ใหญ่เกินด้วยตัวแทน ([chat.history omitted: message too large])
  • รูปภาพจากผู้ช่วย/ที่สร้างขึ้นจะถูกเก็บถาวรเป็นการอ้างอิงสื่อที่จัดการแล้ว และส่งกลับผ่าน URL สื่อของ Gateway ที่ผ่านการยืนยันตัวตนแล้ว ดังนั้นการโหลดซ้ำจึงไม่ต้องพึ่งพาเพย์โหลดรูปภาพ base64 ดิบที่ยังคงอยู่ในคำตอบประวัติแชต
  • เมื่อเรนเดอร์ chat.history Control UI จะลบแท็กคำสั่งแบบอินไลน์ที่มีไว้เพื่อการแสดงผลเท่านั้นออกจากข้อความผู้ช่วยที่มองเห็นได้ (เช่น [[reply_to_*]] และ [[audio_as_voice]]), เพย์โหลด XML ของการเรียกเครื่องมือแบบข้อความล้วน (รวมถึง <tool_call>...</tool_call>, <function_call>...</function_call>, <tool_calls>...</tool_calls>, <function_calls>...</function_calls> และบล็อกการเรียกเครื่องมือที่ถูกตัดทอน), และโทเค็นควบคุมโมเดล ASCII/เต็มความกว้างที่รั่วไหลมา และละเว้นรายการของผู้ช่วยที่ข้อความที่มองเห็นได้ทั้งหมดเป็นเพียงโทเค็นเงียบที่ตรงกันทุกตัวอักษร NO_REPLY / no_reply หรือโทเค็นยืนยัน Heartbeat HEARTBEAT_OK
  • ระหว่างการส่งที่กำลังทำงานและการรีเฟรชประวัติครั้งสุดท้าย มุมมองแชตจะยังคงแสดงข้อความผู้ใช้/ผู้ช่วยแบบมองโลกในแง่ดีในเครื่องไว้ หาก chat.history ส่งคืนสแนปช็อตที่เก่ากว่าชั่วครู่; บันทึกถอดความแบบบัญญัติจะมาแทนที่ข้อความในเครื่องเหล่านั้นเมื่อประวัติ Gateway ตามทัน
  • เหตุการณ์ chat สดคือสถานะการส่งมอบ ส่วน chat.history ถูกสร้างใหม่จากบันทึกถอดความเซสชันที่คงทน หลังเหตุการณ์เครื่องมือขั้นสุดท้าย Control UI จะโหลดประวัติใหม่และผสานเฉพาะส่วนท้ายแบบมองโลกในแง่ดีขนาดเล็กเท่านั้น; ขอบเขตบันทึกถอดความมีเอกสารไว้ใน WebChat
  • chat.inject เพิ่มบันทึกของผู้ช่วยต่อท้ายบันทึกถอดความเซสชันและบรอดแคสต์เหตุการณ์ chat สำหรับการอัปเดตเฉพาะ UI (ไม่มีการรันเอเจนต์ ไม่มีการส่งมอบช่องทาง)
  • ส่วนหัวแชตแสดงตัวกรองเอเจนต์ก่อนตัวเลือกเซสชัน และตัวเลือกเซสชันจะถูกจำกัดขอบเขตตามเอเจนต์ที่เลือก การสลับเอเจนต์จะแสดงเฉพาะเซสชันที่ผูกกับเอเจนต์นั้น และย้อนกลับไปใช้เซสชันหลักของเอเจนต์นั้นเมื่อยังไม่มีเซสชันแดชบอร์ดที่บันทึกไว้
  • บนความกว้างเดสก์ท็อป ตัวควบคุมแชตจะอยู่ในแถวเดียวแบบกะทัดรัดและยุบลงขณะเลื่อนลงในบันทึกถอดความ; การเลื่อนขึ้น กลับไปด้านบน หรือไปถึงด้านล่างจะคืนค่าตัวควบคุม
  • ข้อความซ้ำที่อยู่ติดกันและมีเฉพาะข้อความจะแสดงเป็นบับเบิลเดียวพร้อมป้ายจำนวน ข้อความที่มีรูปภาพ ไฟล์แนบ เอาต์พุตเครื่องมือ หรือพรีวิวแคนวาสจะไม่ถูกยุบ
  • ตัวเลือกโมเดลและการคิดในส่วนหัวแชตจะแพตช์เซสชันที่ใช้งานอยู่ทันทีผ่าน sessions.patch; สิ่งเหล่านี้เป็นการแทนที่เซสชันแบบคงอยู่ ไม่ใช่ตัวเลือกการส่งเฉพาะเทิร์นเดียว
  • หากคุณส่งข้อความขณะที่การเปลี่ยนตัวเลือกโมเดลสำหรับเซสชันเดียวกันยังบันทึกอยู่ ตัวเขียนข้อความจะรอให้แพตช์เซสชันนั้นเสร็จก่อนเรียก chat.send เพื่อให้การส่งใช้โมเดลที่เลือก
  • การพิมพ์ /new ใน Control UI จะสร้างและสลับไปยังเซสชันแดชบอร์ดใหม่แบบเดียวกับ New Chat ยกเว้นเมื่อมีการกำหนดค่า session.dmScope: "main" และพาเรนต์ปัจจุบันเป็นเซสชันหลักของเอเจนต์; ในกรณีนั้นจะรีเซ็ตเซสชันหลักในตำแหน่งเดิม การพิมพ์ /reset จะคงการรีเซ็ตในตำแหน่งเดิมแบบชัดเจนของ Gateway สำหรับเซสชันปัจจุบัน
  • ตัวเลือกโมเดลแชตขอมุมมองโมเดลที่กำหนดค่าไว้ของ Gateway หากมี agents.defaults.models รายการอนุญาตนั้นจะขับเคลื่อนตัวเลือก รวมถึงรายการ provider/* ที่ทำให้แคตตาล็อกที่จำกัดตามผู้ให้บริการยังคงเป็นแบบไดนามิก มิฉะนั้น ตัวเลือกจะแสดงรายการ models.providers.*.models แบบชัดเจน พร้อมผู้ให้บริการที่มีการยืนยันตัวตนที่ใช้งานได้ แคตตาล็อกแบบเต็มยังคงพร้อมใช้งานผ่าน RPC ดีบัก models.list พร้อม view: "all"
  • เมื่อรายงานการใช้งานเซสชัน Gateway ใหม่มีโทเค็นบริบทปัจจุบัน พื้นที่ตัวเขียนข้อความแชตจะแสดงตัวบ่งชี้การใช้งานบริบทแบบกะทัดรัด โดยจะเปลี่ยนเป็นสไตล์คำเตือนเมื่อมีแรงกดดันต่อบริบทสูง และในระดับ Compaction ที่แนะนำ จะแสดงปุ่มแบบกะทัดรัดที่รันเส้นทาง Compaction เซสชันตามปกติ สแนปช็อตโทเค็นที่ล้าสมัยจะถูกซ่อนไว้จนกว่า Gateway จะรายงานการใช้งานใหม่อีกครั้ง
โหมดพูดคุยใช้ผู้ให้บริการเสียงเรียลไทม์ที่ลงทะเบียนไว้ กำหนดค่า OpenAI ด้วย talk.realtime.provider: "openai" พร้อม talk.realtime.providers.openai.apiKey, OPENAI_API_KEY หรือโปรไฟล์ OAuth openai-codex; กำหนดค่า Google ด้วย talk.realtime.provider: "google" พร้อม talk.realtime.providers.google.apiKey เบราว์เซอร์จะไม่ได้รับคีย์ API ผู้ให้บริการมาตรฐาน OpenAI ได้รับความลับไคลเอนต์ Realtime ชั่วคราวสำหรับ WebRTC Google Live ได้รับโทเค็นการยืนยันตัวตน Live API แบบจำกัดและใช้ครั้งเดียวสำหรับเซสชัน WebSocket ของเบราว์เซอร์ โดยมีคำสั่งและประกาศเครื่องมือที่ถูกล็อกไว้ในโทเค็นโดย Gateway ผู้ให้บริการที่เปิดเผยเฉพาะสะพานเรียลไทม์ฝั่งแบ็กเอนด์จะทำงานผ่านทรานสปอร์ตรีเลย์ของ Gateway ดังนั้นข้อมูลประจำตัวและซ็อกเก็ตผู้ขายจะอยู่ฝั่งเซิร์ฟเวอร์ ขณะที่เสียงจากเบราว์เซอร์เคลื่อนผ่าน RPC ของ Gateway ที่ผ่านการยืนยันตัวตน พรอมป์เซสชัน Realtime ถูกประกอบโดย Gateway; talk.client.create ไม่ยอมรับการแทนที่คำสั่งจากผู้เรียกตัวเขียนข้อความแชตมีปุ่มตัวเลือกพูดคุยถัดจากปุ่มเริ่ม/หยุดพูดคุย ตัวเลือกจะมีผลกับเซสชันพูดคุยถัดไป และสามารถแทนที่ผู้ให้บริการ ทรานสปอร์ต โมเดล เสียง ความพยายามในการให้เหตุผล เกณฑ์ VAD ระยะเวลาเงียบ และการเติมนำหน้าได้ เมื่อตัวเลือกว่าง Gateway จะใช้ค่าเริ่มต้นที่กำหนดค่าไว้เมื่อมี หรือค่าเริ่มต้นของผู้ให้บริการ การเลือกรีเลย์ Gateway จะบังคับใช้เส้นทางรีเลย์แบ็กเอนด์; การเลือก WebRTC จะคงให้เซสชันเป็นของไคลเอนต์ และล้มเหลวแทนที่จะย้อนกลับไปใช้รีเลย์อย่างเงียบ ๆ หากผู้ให้บริการไม่สามารถสร้างเซสชันเบราว์เซอร์ได้ในตัวเขียนข้อความแชต ตัวควบคุมพูดคุยคือปุ่มรูปคลื่นถัดจากปุ่มถอดคำพูดจากไมโครโฟน เมื่อการพูดคุยเริ่มต้น แถวสถานะของตัวเขียนข้อความจะแสดง Connecting Talk... จากนั้นแสดง Talk live ขณะที่เสียงเชื่อมต่ออยู่ หรือ Asking OpenClaw... ขณะการเรียกเครื่องมือเรียลไทม์กำลังปรึกษาโมเดลขนาดใหญ่กว่าที่กำหนดค่าไว้ผ่าน talk.client.toolCallการทดสอบควันแบบสดสำหรับผู้ดูแล: OPENAI_API_KEY=... GEMINI_API_KEY=... node --import tsx scripts/dev/realtime-talk-live-smoke.ts ตรวจสอบสะพาน WebSocket แบ็กเอนด์ของ OpenAI, การแลกเปลี่ยน SDP ของ WebRTC เบราว์เซอร์ OpenAI, การตั้งค่า WebSocket เบราว์เซอร์ด้วยโทเค็นจำกัดของ Google Live และอะแดปเตอร์เบราว์เซอร์รีเลย์ Gateway พร้อมสื่อไมโครโฟนจำลอง คำสั่งจะแสดงเฉพาะสถานะผู้ให้บริการและไม่บันทึกความลับ
  • คลิก หยุด (เรียก chat.abort)
  • ขณะที่การรันกำลังทำงาน การติดตามผลตามปกติจะเข้าคิว คลิก นำทาง บนข้อความที่เข้าคิวเพื่อฉีดการติดตามผลนั้นเข้าสู่เทิร์นที่กำลังรัน
  • พิมพ์ /stop (หรือวลีหยุดแบบเดี่ยว เช่น stop, stop action, stop run, stop openclaw, please stop) เพื่อยกเลิกนอกแบนด์
  • chat.abort รองรับ { sessionKey } (ไม่มี runId) เพื่อยกเลิกการรันที่ทำงานอยู่ทั้งหมดสำหรับเซสชันนั้น
  • เมื่อการรันถูกยกเลิก ข้อความผู้ช่วยบางส่วนยังสามารถแสดงใน UI ได้
  • Gateway จะคงข้อความผู้ช่วยบางส่วนที่ถูกยกเลิกไว้ในประวัติบันทึกถอดความเมื่อมีเอาต์พุตที่บัฟเฟอร์ไว้
  • รายการที่คงไว้มีข้อมูลเมตาการยกเลิก เพื่อให้ผู้ใช้บันทึกถอดความแยกข้อความบางส่วนจากการยกเลิกออกจากเอาต์พุตการเสร็จสมบูรณ์ตามปกติได้

การติดตั้ง PWA และ Web Push

Control UI มาพร้อม manifest.webmanifest และ service worker ดังนั้นเบราว์เซอร์สมัยใหม่จึงติดตั้งเป็น PWA แบบสแตนด์อโลนได้ Web Push ช่วยให้ Gateway ปลุก PWA ที่ติดตั้งแล้วด้วยการแจ้งเตือนได้ แม้แท็บหรือหน้าต่างเบราว์เซอร์ไม่ได้เปิดอยู่
พื้นผิวสิ่งที่ทำ
ui/public/manifest.webmanifestแมนิเฟสต์ PWA เบราว์เซอร์จะเสนอ “ติดตั้งแอป” เมื่อเข้าถึงได้
ui/public/sw.jsservice worker ที่จัดการเหตุการณ์ push และการคลิกการแจ้งเตือน
push/vapid-keys.json (ใต้ไดเรกทอรีสถานะ OpenClaw)คู่คีย์ VAPID ที่สร้างอัตโนมัติ ใช้ลงนามเพย์โหลด Web Push
push/web-push-subscriptions.jsonendpoint การสมัครรับข้อมูลของเบราว์เซอร์ที่คงไว้
แทนที่คู่คีย์ VAPID ผ่านตัวแปรสภาพแวดล้อมบนกระบวนการ Gateway เมื่อคุณต้องการตรึงคีย์ (สำหรับการปรับใช้หลายโฮสต์ การหมุนเวียนความลับ หรือการทดสอบ):
  • OPENCLAW_VAPID_PUBLIC_KEY
  • OPENCLAW_VAPID_PRIVATE_KEY
  • OPENCLAW_VAPID_SUBJECT (ค่าเริ่มต้นคือ mailto:openclaw@localhost)
Control UI ใช้เมธอด Gateway ที่จำกัดด้วยขอบเขตเหล่านี้เพื่อลงทะเบียนและทดสอบการสมัครรับข้อมูลของเบราว์เซอร์:
  • push.web.vapidPublicKey — ดึงคีย์สาธารณะ VAPID ที่ใช้งานอยู่
  • push.web.subscribe — ลงทะเบียน endpoint พร้อม keys.p256dh/keys.auth
  • push.web.unsubscribe — ลบ endpoint ที่ลงทะเบียนไว้
  • push.web.test — ส่งการแจ้งเตือนทดสอบไปยังการสมัครรับข้อมูลของผู้เรียก
Web Push เป็นอิสระจากเส้นทางรีเลย์ APNS ของ iOS (ดู การกำหนดค่า สำหรับการพุชที่มีรีเลย์รองรับ) และเมธอด push.test ที่มีอยู่ ซึ่งมุ่งเป้าไปที่การจับคู่มือถือแบบเนทีฟ

เอ็มเบดที่โฮสต์

ข้อความผู้ช่วยสามารถเรนเดอร์เนื้อหาเว็บที่โฮสต์แบบอินไลน์ด้วยชอร์ตโค้ด [embed ...] นโยบาย sandbox ของ iframe ถูกควบคุมโดย gateway.controlUi.embedSandbox:
ปิดใช้งานการเรียกใช้สคริปต์ภายในเอ็มเบดที่โฮสต์
ตัวอย่าง:
{
  gateway: {
    controlUi: {
      embedSandbox: "scripts",
    },
  },
}
ใช้ trusted เฉพาะเมื่อเอกสารที่ฝังต้องการพฤติกรรม same-origin จริง ๆ สำหรับเกมและแคนวาสโต้ตอบที่เอเจนต์สร้างส่วนใหญ่ scripts เป็นตัวเลือกที่ปลอดภัยกว่า
URL เอ็มเบด http(s) ภายนอกแบบสมบูรณ์ยังคงถูกบล็อกโดยค่าเริ่มต้น หากคุณตั้งใจต้องการให้ [embed url="https://..."] โหลดหน้าจากบุคคลที่สาม ให้ตั้งค่า gateway.controlUi.allowExternalEmbedUrls: true

ความกว้างข้อความแชต

ข้อความแชตที่จัดกลุ่มใช้ความกว้างสูงสุดค่าเริ่มต้นที่อ่านง่าย การปรับใช้บนจอกว้างสามารถแทนที่ได้โดยไม่ต้องแพตช์ CSS ที่บันเดิลมา ด้วยการตั้งค่า gateway.controlUi.chatMessageMaxWidth:
{
  gateway: {
    controlUi: {
      chatMessageMaxWidth: "min(1280px, 82%)",
    },
  },
}
ค่าจะถูกตรวจสอบก่อนถึงเบราว์เซอร์ ค่าที่รองรับรวมถึงความยาวและเปอร์เซ็นต์แบบธรรมดา เช่น 960px หรือ 82% พร้อมนิพจน์ความกว้างที่จำกัดอย่าง min(...), max(...), clamp(...), calc(...) และ fit-content(...)

การเข้าถึง Tailnet (แนะนำ)

คง Gateway ไว้บน loopback และให้ Tailscale Serve พร็อกซีด้วย HTTPS:
openclaw gateway --tailscale serve
เปิด:
  • https://<magicdns>/ (หรือ gateway.controlUi.basePath ที่คุณกำหนดค่าไว้)
โดยค่าเริ่มต้น คำขอ Control UI/WebSocket Serve สามารถยืนยันตัวตนผ่านส่วนหัวข้อมูลประจำตัวของ Tailscale (tailscale-user-login) ได้เมื่อ gateway.auth.allowTailscale เป็น true OpenClaw ตรวจสอบข้อมูลประจำตัวโดยแปลงที่อยู่ x-forwarded-for ด้วย tailscale whois และจับคู่กับส่วนหัว และจะยอมรับเฉพาะเมื่อคำขอเข้ามาที่ loopback พร้อมส่วนหัว x-forwarded-* ของ Tailscale เท่านั้น สำหรับเซสชันผู้ปฏิบัติงาน Control UI ที่มีข้อมูลประจำตัวอุปกรณ์ของเบราว์เซอร์ เส้นทาง Serve ที่ตรวจสอบแล้วนี้จะข้ามรอบการจับคู่อุปกรณ์ด้วยเช่นกัน ส่วนเบราว์เซอร์ที่ไม่มีอุปกรณ์และการเชื่อมต่อบทบาทโหนดยังคงทำตามการตรวจสอบอุปกรณ์ตามปกติ ตั้งค่า gateway.auth.allowTailscale: false หากคุณต้องการบังคับใช้ข้อมูลรับรอง shared-secret อย่างชัดเจนแม้กับทราฟฟิก Serve จากนั้นใช้ gateway.auth.mode: "token" หรือ "password"สำหรับเส้นทางข้อมูลประจำตัว Serve แบบ async นี้ ความพยายามยืนยันตัวตนที่ล้มเหลวสำหรับ IP ไคลเอนต์และขอบเขตการยืนยันตัวตนเดียวกันจะถูกจัดลำดับก่อนการเขียน rate-limit ดังนั้นการลองซ้ำที่ผิดพลาดพร้อมกันจากเบราว์เซอร์เดียวกันอาจแสดง retry later ในคำขอที่สอง แทนที่จะเกิด mismatch ธรรมดาสองรายการที่แข่งกันแบบขนาน
การยืนยันตัวตน Serve แบบไม่มีโทเคนถือว่าโฮสต์ gateway เชื่อถือได้ หากโค้ดโลคัลที่ไม่น่าเชื่อถืออาจทำงานบนโฮสต์นั้น ให้บังคับใช้การยืนยันตัวตนด้วยโทเคน/รหัสผ่าน

HTTP ที่ไม่ปลอดภัย

หากคุณเปิดแดชบอร์ดผ่าน HTTP ธรรมดา (http://<lan-ip> หรือ http://<tailscale-ip>) เบราว์เซอร์จะทำงานใน บริบทที่ไม่ปลอดภัย และบล็อก WebCrypto โดยค่าเริ่มต้น OpenClaw จะ บล็อก การเชื่อมต่อ Control UI ที่ไม่มีข้อมูลประจำตัวอุปกรณ์ ข้อยกเว้นที่บันทึกไว้:
  • ความเข้ากันได้กับ HTTP ที่ไม่ปลอดภัยเฉพาะ localhost ด้วย gateway.controlUi.allowInsecureAuth=true
  • การยืนยันตัวตน Control UI ของผู้ปฏิบัติงานสำเร็จผ่าน gateway.auth.mode: "trusted-proxy"
  • กลไกฉุกเฉิน gateway.controlUi.dangerouslyDisableDeviceAuth=true
วิธีแก้ไขที่แนะนำ: ใช้ HTTPS (Tailscale Serve) หรือเปิด UI ในเครื่อง:
  • https://<magicdns>/ (Serve)
  • http://127.0.0.1:18789/ (บนโฮสต์ gateway)
{
  gateway: {
    controlUi: { allowInsecureAuth: true },
    bind: "tailnet",
    auth: { mode: "token", token: "replace-me" },
  },
}
allowInsecureAuth เป็นสวิตช์ความเข้ากันได้ในเครื่องเท่านั้น:
  • อนุญาตให้เซสชัน Control UI บน localhost ดำเนินต่อได้โดยไม่มีข้อมูลประจำตัวอุปกรณ์ในบริบท HTTP ที่ไม่ปลอดภัย
  • ไม่ข้ามการตรวจสอบการจับคู่
  • ไม่ผ่อนคลายข้อกำหนดข้อมูลประจำตัวอุปกรณ์ระยะไกล (ที่ไม่ใช่ localhost)
{
  gateway: {
    controlUi: { dangerouslyDisableDeviceAuth: true },
    bind: "tailnet",
    auth: { mode: "token", token: "replace-me" },
  },
}
dangerouslyDisableDeviceAuth ปิดใช้งานการตรวจสอบข้อมูลประจำตัวอุปกรณ์ของ Control UI และเป็นการลดระดับความปลอดภัยอย่างรุนแรง ให้ย้อนกลับโดยเร็วหลังใช้ในกรณีฉุกเฉิน
  • การยืนยันตัวตน trusted-proxy ที่สำเร็จสามารถอนุญาตเซสชัน Control UI ของ ผู้ปฏิบัติงาน โดยไม่มีข้อมูลประจำตัวอุปกรณ์ได้
  • สิ่งนี้ ไม่ ขยายไปถึงเซสชัน Control UI บทบาทโหนด
  • reverse proxy แบบ loopback บนโฮสต์เดียวกันยังคงไม่ผ่านการยืนยันตัวตน trusted-proxy; ดู การยืนยันตัวตน trusted proxy
ดู Tailscale สำหรับคำแนะนำการตั้งค่า HTTPS

นโยบายความปลอดภัยของเนื้อหา

Control UI มาพร้อมนโยบาย img-src ที่เข้มงวด: อนุญาตเฉพาะแอสเซ็ต same-origin, URL data: และ URL blob: ที่สร้างในเครื่องเท่านั้น URL รูปภาพระยะไกลแบบ http(s) และแบบสัมพันธ์กับโปรโตคอลจะถูกเบราว์เซอร์ปฏิเสธและจะไม่เกิดการดึงข้อมูลผ่านเครือข่าย ในทางปฏิบัติ หมายความว่า:
  • อวาตาร์และรูปภาพที่ให้บริการใต้พาธสัมพันธ์ (เช่น /avatars/<id>) ยังแสดงผลได้ รวมถึงเส้นทางอวาตาร์ที่ผ่านการยืนยันตัวตนซึ่ง UI ดึงมาและแปลงเป็น URL blob: ในเครื่อง
  • URL แบบ inline data:image/... ยังแสดงผลได้ (มีประโยชน์สำหรับ payload ในโปรโตคอล)
  • URL blob: ในเครื่องที่สร้างโดย Control UI ยังแสดงผลได้
  • URL อวาตาร์ระยะไกลที่ปล่อยออกมาจาก metadata ของช่องทางจะถูกตัดออกที่ตัวช่วยอวาตาร์ของ Control UI และแทนที่ด้วยโลโก้/แบดจ์ในตัว ดังนั้นช่องทางที่ถูกเจาะหรือประสงค์ร้ายจึงไม่สามารถบังคับให้เบราว์เซอร์ของผู้ปฏิบัติงานดึงรูปภาพระยะไกลตามอำเภอใจได้
คุณไม่จำเป็นต้องเปลี่ยนอะไรเพื่อให้ได้พฤติกรรมนี้ เพราะเปิดใช้อยู่เสมอและกำหนดค่าไม่ได้

การยืนยันตัวตนเส้นทางอวาตาร์

เมื่อกำหนดค่าการยืนยันตัวตน gateway แล้ว endpoint อวาตาร์ของ Control UI ต้องใช้โทเคน gateway เดียวกับ API ส่วนอื่น:
  • GET /avatar/<agentId> ส่งคืนรูปภาพอวาตาร์เฉพาะให้ผู้เรียกที่ผ่านการยืนยันตัวตนเท่านั้น GET /avatar/<agentId>?meta=1 ส่งคืน metadata ของอวาตาร์ภายใต้กฎเดียวกัน
  • คำขอที่ไม่ผ่านการยืนยันตัวตนไปยังเส้นทางใดเส้นทางหนึ่งจะถูกปฏิเสธ (ตรงกับเส้นทาง assistant-media ที่อยู่ระดับเดียวกัน) สิ่งนี้ป้องกันไม่ให้เส้นทางอวาตาร์รั่วไหลข้อมูลประจำตัวเอเจนต์บนโฮสต์ที่ได้รับการป้องกันด้วยวิธีอื่น
  • Control UI เองส่งต่อโทเคน gateway เป็นส่วนหัว bearer เมื่อดึงอวาตาร์ และใช้ URL blob ที่ผ่านการยืนยันตัวตนเพื่อให้รูปภาพยังแสดงในแดชบอร์ดได้
หากคุณปิดใช้งานการยืนยันตัวตน gateway (ไม่แนะนำบนโฮสต์ที่ใช้ร่วมกัน) เส้นทางอวาตาร์ก็จะไม่ต้องยืนยันตัวตนเช่นกัน สอดคล้องกับ gateway ส่วนอื่น

การยืนยันตัวตนเส้นทางสื่อของผู้ช่วย

เมื่อกำหนดค่าการยืนยันตัวตน gateway แล้ว ตัวอย่างสื่อโลคัลของผู้ช่วยจะใช้เส้นทางสองขั้นตอน:
  • GET /__openclaw__/assistant-media?meta=1&source=<path> ต้องใช้การยืนยันตัวตนผู้ปฏิบัติงาน Control UI ตามปกติ เบราว์เซอร์ส่งโทเคน gateway เป็นส่วนหัว bearer เมื่อตรวจสอบความพร้อมใช้งาน
  • การตอบกลับ metadata ที่สำเร็จจะมี mediaTicket อายุสั้นที่ถูกจำกัดขอบเขตกับพาธต้นทางนั้นเท่านั้น
  • URL รูปภาพ เสียง วิดีโอ และเอกสารที่เบราว์เซอร์แสดงผลใช้ mediaTicket=<ticket> แทนโทเคนหรือรหัสผ่าน gateway ที่ใช้งานอยู่ ตั๋วจะหมดอายุอย่างรวดเร็วและไม่สามารถอนุญาตต้นทางอื่นได้
สิ่งนี้ทำให้การแสดงผลสื่อตามปกติยังเข้ากันได้กับองค์ประกอบสื่อแบบ native ของเบราว์เซอร์ โดยไม่ใส่ข้อมูลรับรอง gateway ที่นำกลับมาใช้ซ้ำได้ใน URL สื่อที่มองเห็นได้

การสร้าง UI

Gateway ให้บริการไฟล์สแตติกจาก dist/control-ui สร้างไฟล์เหล่านี้ด้วย:
pnpm ui:build
base แบบสัมบูรณ์ที่เลือกใช้ได้ (เมื่อคุณต้องการ URL แอสเซ็ตแบบคงที่):
OPENCLAW_CONTROL_UI_BASE_PATH=/openclaw/ pnpm ui:build
สำหรับการพัฒนาในเครื่อง (dev server แยกต่างหาก):
pnpm ui:dev
จากนั้นชี้ UI ไปที่ URL Gateway WS ของคุณ (เช่น ws://127.0.0.1:18789)

หน้า Control UI ว่างเปล่า

หากเบราว์เซอร์โหลดแดชบอร์ดว่างและ DevTools ไม่แสดงข้อผิดพลาดที่เป็นประโยชน์ ส่วนขยายหรือ content script ช่วงต้นอาจขัดขวางไม่ให้แอปโมดูล JavaScript ประเมินผล หน้า static มีแผงกู้คืน HTML ธรรมดาที่ปรากฏเมื่อ <openclaw-app> ไม่ถูกลงทะเบียนหลังเริ่มต้น ใช้การกระทำ ลองอีกครั้ง ของแผงหลังเปลี่ยนสภาพแวดล้อมเบราว์เซอร์ หรือโหลดใหม่ด้วยตนเองหลังตรวจสอบสิ่งเหล่านี้:
  • ปิดใช้งานส่วนขยายที่แทรกเข้าไปในทุกหน้า โดยเฉพาะส่วนขยายที่มี content script แบบ <all_urls>
  • ลองใช้หน้าต่างส่วนตัว โปรไฟล์เบราว์เซอร์ใหม่ หรือเบราว์เซอร์อื่น
  • ให้ Gateway ทำงานต่อและตรวจสอบ URL แดชบอร์ดเดียวกันหลังเปลี่ยนเบราว์เซอร์

การดีบัก/ทดสอบ: dev server + Gateway ระยะไกล

Control UI เป็นไฟล์สแตติก เป้าหมาย WebSocket สามารถกำหนดค่าได้และอาจแตกต่างจาก origin ของ HTTP วิธีนี้สะดวกเมื่อคุณต้องการ Vite dev server ในเครื่อง แต่ Gateway ทำงานอยู่ที่อื่น
1

Start the UI dev server

pnpm ui:dev
2

Open with gatewayUrl

http://localhost:5173/?gatewayUrl=ws%3A%2F%2F<gateway-host>%3A18789
การยืนยันตัวตนแบบครั้งเดียวที่เลือกใช้ได้ (หากจำเป็น):
http://localhost:5173/?gatewayUrl=wss%3A%2F%2F<gateway-host>%3A18789#token=<gateway-token>
  • gatewayUrl ถูกเก็บใน localStorage หลังโหลดและถูกลบออกจาก URL
  • หากคุณส่ง endpoint ws:// หรือ wss:// แบบเต็มผ่าน gatewayUrl ให้ URL-encode ค่า gatewayUrl เพื่อให้เบราว์เซอร์แยกวิเคราะห์ query string ได้ถูกต้อง
  • ควรส่ง token ผ่าน URL fragment (#token=...) เมื่อเป็นไปได้ fragment จะไม่ถูกส่งไปยังเซิร์ฟเวอร์ ซึ่งหลีกเลี่ยงการรั่วไหลผ่าน request-log และ Referer พารามิเตอร์ query แบบเดิม ?token= ยังคงถูกนำเข้าได้หนึ่งครั้งเพื่อความเข้ากันได้ แต่ใช้เป็น fallback เท่านั้น และจะถูกตัดออกทันทีหลัง bootstrap
  • password ถูกเก็บไว้ในหน่วยความจำเท่านั้น
  • เมื่อ gatewayUrl ถูกตั้งค่า UI จะไม่ fallback ไปใช้ข้อมูลรับรองจาก config หรือ environment ให้ระบุ token (หรือ password) อย่างชัดเจน การขาดข้อมูลรับรองที่ระบุอย่างชัดเจนถือเป็นข้อผิดพลาด
  • ใช้ wss:// เมื่อ Gateway อยู่หลัง TLS (Tailscale Serve, HTTPS proxy ฯลฯ)
  • gatewayUrl ยอมรับเฉพาะในหน้าต่างระดับบนสุด (ไม่ใช่แบบฝัง) เพื่อป้องกัน clickjacking
  • การปรับใช้ Control UI ที่ไม่ใช่ loopback ต้องตั้งค่า gateway.controlUi.allowedOrigins อย่างชัดเจน (origin เต็ม) ซึ่งรวมถึงการตั้งค่า dev ระยะไกล
  • การเริ่มต้น Gateway อาจ seed origin ในเครื่อง เช่น http://localhost:<port> และ http://127.0.0.1:<port> จาก bind และ port ของ runtime ที่มีผล แต่ origin ของเบราว์เซอร์ระยะไกลยังต้องมีรายการอย่างชัดเจน
  • อย่าใช้ gateway.controlUi.allowedOrigins: ["*"] ยกเว้นสำหรับการทดสอบในเครื่องที่ควบคุมอย่างเข้มงวด หมายถึงอนุญาต origin ของเบราว์เซอร์ใดก็ได้ ไม่ใช่ “จับคู่กับโฮสต์อะไรก็ตามที่ฉันใช้อยู่”
  • gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true เปิดใช้งานโหมด fallback origin จากส่วนหัว Host แต่เป็นโหมดความปลอดภัยที่อันตราย
ตัวอย่าง:
{
  gateway: {
    controlUi: {
      allowedOrigins: ["http://localhost:5173"],
    },
  },
}
รายละเอียดการตั้งค่าการเข้าถึงระยะไกล: การเข้าถึงระยะไกล

ที่เกี่ยวข้อง