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.

โมเดลความเชื่อถือสำหรับผู้ช่วยส่วนตัว แนวทางนี้ถือว่ามีขอบเขตผู้ปฏิบัติการที่เชื่อถือได้หนึ่งขอบเขตต่อ Gateway (โมเดลผู้ใช้คนเดียว ผู้ช่วยส่วนตัว) OpenClaw ไม่ใช่ ขอบเขตความปลอดภัยแบบหลายผู้เช่าที่เป็นปฏิปักษ์สำหรับผู้ใช้ที่ไม่ไว้วางใจกันหลายคนซึ่งใช้ agent หรือ Gateway เดียวกัน หากคุณต้องใช้งานแบบความเชื่อถือปะปนหรือผู้ใช้เป็นปฏิปักษ์ ให้แยกขอบเขตความเชื่อถือ (Gateway + credentials แยกกัน และควรเป็นผู้ใช้ OS หรือโฮสต์แยกกัน)

กำหนดขอบเขตก่อน: โมเดลความปลอดภัยของผู้ช่วยส่วนตัว

แนวทางความปลอดภัยของ OpenClaw ถือว่าเป็นการปรับใช้แบบ ผู้ช่วยส่วนตัว: ขอบเขตผู้ปฏิบัติการที่เชื่อถือได้หนึ่งขอบเขต และอาจมี agent หลายตัว
  • สถานะความปลอดภัยที่รองรับ: หนึ่งผู้ใช้/ขอบเขตความเชื่อถือต่อ Gateway (แนะนำหนึ่งผู้ใช้ OS/โฮสต์/VPS ต่อขอบเขต)
  • ไม่ใช่ขอบเขตความปลอดภัยที่รองรับ: Gateway/agent เดียวที่ใช้ร่วมกันโดยผู้ใช้ที่ไม่ไว้วางใจกันหรือเป็นปฏิปักษ์
  • หากจำเป็นต้องแยกผู้ใช้ที่เป็นปฏิปักษ์ ให้แยกตามขอบเขตความเชื่อถือ (Gateway + credentials แยกกัน และควรมีผู้ใช้ OS/โฮสต์แยกกัน)
  • หากผู้ใช้ที่ไม่ไว้วางใจกันหลายคนสามารถส่งข้อความถึง agent ที่เปิดใช้เครื่องมือได้ ให้ถือว่าพวกเขาใช้สิทธิ์เครื่องมือที่มอบหมายชุดเดียวกันสำหรับ agent นั้นร่วมกัน
หน้านี้อธิบายการเสริมความปลอดภัย ภายในโมเดลนั้น ไม่ได้อ้างว่าสามารถแยกผู้เช่าหลายรายที่เป็นปฏิปักษ์บน Gateway ที่ใช้ร่วมกันหนึ่งตัวได้

ตรวจสอบด่วน: openclaw security audit

ดูเพิ่มเติม: การตรวจสอบความถูกต้องอย่างเป็นทางการ (โมเดลความปลอดภัย) รันคำสั่งนี้เป็นประจำ (โดยเฉพาะหลังจากเปลี่ยน config หรือเปิดเผยพื้นผิวเครือข่าย):
openclaw security audit
openclaw security audit --deep
openclaw security audit --fix
openclaw security audit --json
security audit --fix ถูกตั้งใจให้มีขอบเขตแคบ: จะเปลี่ยนนโยบายกลุ่มที่เปิดกว้างทั่วไปเป็น allowlist, คืนค่า logging.redactSensitive: "tools", ทำให้สิทธิ์ state/config/include-file เข้มงวดขึ้น และใช้การรีเซ็ต ACL ของ Windows แทน POSIX chmod เมื่อรันบน Windows คำสั่งนี้จะแจ้งเตือนจุดพลาดที่พบบ่อย (การเปิดเผย auth ของ Gateway, การเปิดเผยการควบคุมเบราว์เซอร์, allowlist ที่ยกระดับ, สิทธิ์ไฟล์ระบบ, การอนุมัติ exec ที่ผ่อนปรน และการเปิดเผยเครื่องมือในช่องทางที่เปิดกว้าง) OpenClaw เป็นทั้งผลิตภัณฑ์และการทดลอง: คุณกำลังเชื่อมพฤติกรรมของโมเดลแนวหน้ากับพื้นผิวการส่งข้อความจริงและเครื่องมือจริง ไม่มีการตั้งค่าใดที่ “ปลอดภัยสมบูรณ์แบบ” เป้าหมายคือการตั้งใจพิจารณาเรื่อง:
  • ใครสามารถคุยกับบอตของคุณได้
  • บอตได้รับอนุญาตให้ทำงานที่ใด
  • บอตแตะต้องอะไรได้บ้าง
เริ่มจากสิทธิ์ที่น้อยที่สุดที่ยังทำงานได้ แล้วค่อยขยายเมื่อคุณมั่นใจมากขึ้น

การปรับใช้และความเชื่อถือของโฮสต์

OpenClaw ถือว่าโฮสต์และขอบเขต config เป็นสิ่งที่เชื่อถือได้:
  • หากมีคนแก้ไข state/config ของโฮสต์ Gateway ได้ (~/.openclaw รวมถึง openclaw.json) ให้ถือว่าบุคคลนั้นเป็นผู้ปฏิบัติการที่เชื่อถือได้
  • การรัน Gateway เดียวสำหรับผู้ปฏิบัติการหลายคนที่ไม่ไว้วางใจกันหรือเป็นปฏิปักษ์ ไม่ใช่การตั้งค่าที่แนะนำ
  • สำหรับทีมที่มีความเชื่อถือปะปน ให้แยกขอบเขตความเชื่อถือด้วย Gateway แยกกัน (หรืออย่างน้อยแยกผู้ใช้ OS/โฮสต์)
  • ค่าเริ่มต้นที่แนะนำ: หนึ่งผู้ใช้ต่อเครื่อง/โฮสต์ (หรือ VPS), หนึ่ง Gateway สำหรับผู้ใช้นั้น และ agent หนึ่งตัวหรือมากกว่าใน Gateway นั้น
  • ภายในอินสแตนซ์ Gateway เดียว การเข้าถึงของผู้ปฏิบัติการที่ผ่านการยืนยันตัวตนเป็นบทบาท control-plane ที่เชื่อถือได้ ไม่ใช่บทบาทผู้เช่าต่อผู้ใช้
  • ตัวระบุเซสชัน (sessionKey, ID เซสชัน, ป้ายกำกับ) เป็นตัวเลือกเส้นทาง ไม่ใช่โทเค็นการอนุญาต
  • หากหลายคนส่งข้อความถึง agent ที่เปิดใช้เครื่องมือได้ แต่ละคนสามารถชี้นำชุดสิทธิ์เดียวกันนั้นได้ การแยกเซสชัน/หน่วยความจำต่อผู้ใช้ช่วยเรื่องความเป็นส่วนตัว แต่ไม่ได้เปลี่ยน agent ที่ใช้ร่วมกันให้เป็นการอนุญาตโฮสต์แบบต่อผู้ใช้

การดำเนินการไฟล์อย่างปลอดภัย

OpenClaw ใช้ @openclaw/fs-safe สำหรับการเข้าถึงไฟล์แบบจำกัด root, การเขียนแบบ atomic, การแตก archive, พื้นที่ทำงานชั่วคราว และตัวช่วยไฟล์ลับ ค่าเริ่มต้นของ OpenClaw ปิดตัวช่วย POSIX Python แบบเลือกใช้ของ fs-safe; ตั้ง OPENCLAW_FS_SAFE_PYTHON_MODE=auto หรือ require เฉพาะเมื่อคุณต้องการการเสริมความแข็งแรงให้การเปลี่ยนแปลงแบบอ้างอิง fd และรองรับ runtime ของ Python ได้ รายละเอียด: การดำเนินการไฟล์อย่างปลอดภัย

พื้นที่ทำงาน Slack ที่ใช้ร่วมกัน: ความเสี่ยงจริง

หาก “ทุกคนใน Slack สามารถส่งข้อความถึงบอตได้” ความเสี่ยงหลักคือสิทธิ์เครื่องมือที่มอบหมาย:
  • ผู้ส่งที่ได้รับอนุญาตทุกคนสามารถทำให้เกิดการเรียกเครื่องมือ (exec, เบราว์เซอร์, เครื่องมือเครือข่าย/ไฟล์) ภายในนโยบายของ agent ได้;
  • การฉีด prompt/content จากผู้ส่งคนหนึ่งอาจทำให้เกิดการกระทำที่กระทบ state, อุปกรณ์ หรือผลลัพธ์ที่ใช้ร่วมกัน;
  • หาก agent ที่ใช้ร่วมกันหนึ่งตัวมี credentials/ไฟล์ที่ละเอียดอ่อน ผู้ส่งที่ได้รับอนุญาตทุกคนอาจสั่งให้รั่วไหลผ่านการใช้เครื่องมือได้
ใช้ agent/Gateway แยกกันพร้อมเครื่องมือขั้นต่ำสำหรับ workflow ของทีม; เก็บ agent ที่มีข้อมูลส่วนตัวไว้เป็นส่วนตัว

agent ที่บริษัทใช้ร่วมกัน: รูปแบบที่ยอมรับได้

สิ่งนี้ยอมรับได้เมื่อทุกคนที่ใช้ agent นั้นอยู่ในขอบเขตความเชื่อถือเดียวกัน (เช่น ทีมบริษัทเดียวกัน) และ agent ถูกจำกัดขอบเขตไว้เพื่อธุรกิจอย่างเคร่งครัด
  • รันบนเครื่อง/VM/container เฉพาะ;
  • ใช้ผู้ใช้ OS เฉพาะ + เบราว์เซอร์/โปรไฟล์/บัญชีเฉพาะสำหรับ runtime นั้น;
  • อย่าลงชื่อเข้าใช้ runtime นั้นด้วยบัญชี Apple/Google ส่วนตัว หรือโปรไฟล์ password-manager/เบราว์เซอร์ส่วนตัว
หากคุณผสมตัวตนส่วนตัวและบริษัทบน runtime เดียวกัน คุณจะทำให้การแยกขอบเขตหายไปและเพิ่มความเสี่ยงในการเปิดเผยข้อมูลส่วนตัว

แนวคิดความเชื่อถือของ Gateway และ Node

ถือว่า Gateway และ Node เป็นโดเมนความเชื่อถือของผู้ปฏิบัติการเดียวกัน โดยมีบทบาทต่างกัน:
  • Gateway คือ control plane และพื้นผิวนโยบาย (gateway.auth, นโยบายเครื่องมือ, การกำหนดเส้นทาง)
  • Node คือพื้นผิวการดำเนินการระยะไกลที่จับคู่กับ Gateway นั้น (คำสั่ง, การกระทำกับอุปกรณ์, ความสามารถเฉพาะโฮสต์)
  • ผู้เรียกที่ผ่านการยืนยันตัวตนกับ Gateway จะได้รับความเชื่อถือในขอบเขต Gateway หลังจากจับคู่แล้ว การกระทำของ Node จะถือเป็นการกระทำของผู้ปฏิบัติการที่เชื่อถือได้บน Node นั้น
  • ระดับขอบเขตของผู้ปฏิบัติการและการตรวจสอบขณะอนุมัติสรุปไว้ใน ขอบเขตผู้ปฏิบัติการ
  • ไคลเอนต์ backend แบบ loopback โดยตรงที่ผ่านการยืนยันตัวตนด้วย token/password ของ Gateway ที่ใช้ร่วมกันสามารถเรียก RPC ภายใน control-plane ได้โดยไม่ต้องแสดงตัวตนอุปกรณ์ของผู้ใช้ นี่ไม่ใช่การข้ามการจับคู่ระยะไกลหรือเบราว์เซอร์: ไคลเอนต์เครือข่าย, ไคลเอนต์ Node, ไคลเอนต์ device-token และตัวตนอุปกรณ์แบบชัดเจนยังคงผ่านการจับคู่และการบังคับใช้การยกระดับขอบเขต
  • sessionKey คือการเลือกเส้นทาง/บริบท ไม่ใช่ auth ต่อผู้ใช้
  • การอนุมัติ Exec (allowlist + ask) เป็น guardrail สำหรับเจตนาของผู้ปฏิบัติการ ไม่ใช่การแยกผู้เช่าหลายรายที่เป็นปฏิปักษ์
  • ค่าเริ่มต้นของผลิตภัณฑ์ OpenClaw สำหรับการตั้งค่าผู้ปฏิบัติการเดี่ยวที่เชื่อถือได้คืออนุญาต host exec บน gateway/node โดยไม่มี prompt ขออนุมัติ (security="full", ask="off" เว้นแต่คุณจะทำให้เข้มงวดขึ้น) ค่าเริ่มต้นนี้เป็น UX ที่ตั้งใจไว้ ไม่ใช่ช่องโหว่ในตัวเอง
  • การอนุมัติ Exec ผูกกับบริบทคำขอที่แน่นอนและตัวถูกดำเนินการไฟล์ local โดยตรงแบบ best-effort; การอนุมัตินี้ไม่ได้สร้างโมเดลเชิงความหมายให้กับทุก path ของ runtime/interpreter loader ใช้ sandboxing และการแยกโฮสต์สำหรับขอบเขตที่แข็งแรง
หากคุณต้องแยกผู้ใช้ที่เป็นปฏิปักษ์ ให้แยกขอบเขตความเชื่อถือตามผู้ใช้ OS/โฮสต์ และรัน Gateway แยกกัน

เมทริกซ์ขอบเขตความเชื่อถือ

ใช้สิ่งนี้เป็นโมเดลด่วนเมื่อตรวจคัดแยกความเสี่ยง:
ขอบเขตหรือการควบคุมความหมายการอ่านผิดที่พบบ่อย
gateway.auth (token/password/trusted-proxy/device auth)ยืนยันตัวตนผู้เรียกกับ API ของ Gateway”ต้องมีลายเซ็นต่อข้อความในทุก frame จึงจะปลอดภัย”
sessionKeyคีย์กำหนดเส้นทางสำหรับการเลือกบริบท/เซสชัน”session key เป็นขอบเขต auth ของผู้ใช้”
guardrail สำหรับ prompt/contentลดความเสี่ยงจากการใช้โมเดลในทางที่ผิด”prompt injection อย่างเดียวพิสูจน์การข้าม auth”
canvas.eval / browser evaluateความสามารถของผู้ปฏิบัติการโดยตั้งใจเมื่อเปิดใช้”primitive สำหรับ JS eval ใดๆ เป็น vuln โดยอัตโนมัติในโมเดลความเชื่อถือนี้”
เชลล์ ! ของ TUI localการดำเนินการ local ที่ผู้ปฏิบัติการเรียกใช้อย่างชัดเจน”คำสั่งอำนวยความสะดวกของเชลล์ local คือ remote injection”
การจับคู่ Node และคำสั่ง Nodeการดำเนินการระยะไกลระดับผู้ปฏิบัติการบนอุปกรณ์ที่จับคู่แล้ว”การควบคุมอุปกรณ์ระยะไกลควรถูกถือเป็นการเข้าถึงของผู้ใช้ที่ไม่เชื่อถือโดยค่าเริ่มต้น”
gateway.nodes.pairing.autoApproveCidrsนโยบายรับลงทะเบียน Node จากเครือข่ายที่เชื่อถือแบบ opt-in”allowlist ที่ปิดโดยค่าเริ่มต้นคือช่องโหว่การจับคู่อัตโนมัติ”

ไม่ใช่ช่องโหว่ตามการออกแบบ

รูปแบบเหล่านี้ถูกรายงานบ่อย และโดยปกติจะปิดโดยไม่ต้องดำเนินการ เว้นแต่จะพิสูจน์การข้ามขอบเขตจริงได้:
  • เชนที่มีเพียง prompt-injection โดยไม่มีการข้ามนโยบาย, auth หรือ sandbox
  • การกล่าวอ้างที่ถือว่ามีการใช้งานแบบหลายผู้เช่าที่เป็นปฏิปักษ์บนโฮสต์หรือ config ที่ใช้ร่วมกันหนึ่งชุด
  • การกล่าวอ้างที่จัดประเภทการเข้าถึง read-path ปกติของผู้ปฏิบัติการ (เช่น sessions.list / sessions.preview / chat.history) เป็น IDOR ในการตั้งค่า Gateway ที่ใช้ร่วมกัน
  • ข้อค้นพบจากการปรับใช้แบบ localhost เท่านั้น (เช่น HSTS บน Gateway แบบ loopback-only)
  • ข้อค้นพบเกี่ยวกับลายเซ็น Webhook ขาเข้าของ Discord สำหรับ path ขาเข้าที่ไม่มีอยู่ใน repo นี้
  • รายงานที่ถือว่า metadata การจับคู่ Node เป็นชั้นอนุมัติต่อคำสั่งชั้นที่สองแบบซ่อนสำหรับ system.run ทั้งที่ขอบเขตการดำเนินการจริงยังคงเป็นนโยบายคำสั่ง Node ระดับ global ของ Gateway รวมกับการอนุมัติ exec ของ Node เอง
  • รายงานที่ถือว่า gateway.nodes.pairing.autoApproveCidrs ที่กำหนดค่าไว้เป็นช่องโหว่ในตัวเอง การตั้งค่านี้ปิดโดยค่าเริ่มต้น ต้องมีรายการ CIDR/IP อย่างชัดเจน ใช้เฉพาะกับการจับคู่ role: node ครั้งแรกที่ไม่มีขอบเขตที่ร้องขอ และไม่อนุมัติโดยอัตโนมัติสำหรับ operator/browser/Control UI, WebChat, การยกระดับบทบาท, การยกระดับขอบเขต, การเปลี่ยน metadata, การเปลี่ยน public-key หรือ path header ของ trusted-proxy แบบ loopback บนโฮสต์เดียวกัน เว้นแต่เปิดใช้ loopback trusted-proxy auth อย่างชัดเจน
  • ข้อค้นพบ “ไม่มีการอนุญาตต่อผู้ใช้” ที่ถือว่า sessionKey เป็น auth token

baseline แบบเข้มงวดใน 60 วินาที

ใช้ baseline นี้ก่อน แล้วค่อยเปิดใช้เครื่องมือซ้ำแบบเลือกได้ต่อ agent ที่เชื่อถือ:
{
  gateway: {
    mode: "local",
    bind: "loopback",
    auth: { mode: "token", token: "replace-with-long-random-token" },
  },
  session: {
    dmScope: "per-channel-peer",
  },
  tools: {
    profile: "messaging",
    deny: ["group:automation", "group:runtime", "group:fs", "sessions_spawn", "sessions_send"],
    fs: { workspaceOnly: true },
    exec: { security: "deny", ask: "always" },
    elevated: { enabled: false },
  },
  channels: {
    whatsapp: { dmPolicy: "pairing", groups: { "*": { requireMention: true } } },
  },
}
สิ่งนี้ทำให้ Gateway เป็นแบบ local-only, แยก DM และปิดเครื่องมือ control-plane/runtime โดยค่าเริ่มต้น

กฎด่วนสำหรับกล่องข้อความที่ใช้ร่วมกัน

หากมีมากกว่าหนึ่งคนที่สามารถ DM บอตของคุณได้:
  • ตั้ง session.dmScope: "per-channel-peer" (หรือ "per-account-channel-peer" สำหรับช่องทางที่มีหลายบัญชี)
  • ใช้ dmPolicy: "pairing" หรือ allowlist ที่เข้มงวด
  • อย่ารวม DM ที่ใช้ร่วมกันกับการเข้าถึงเครื่องมือแบบกว้าง
  • สิ่งนี้ช่วยเสริมความปลอดภัยให้กล่องข้อความแบบร่วมมือ/ใช้ร่วมกัน แต่ไม่ได้ออกแบบมาเพื่อแยกผู้เช่าร่วมที่เป็นปฏิปักษ์เมื่อผู้ใช้มีสิทธิ์เขียน host/config ร่วมกัน

โมเดลการมองเห็นบริบท

OpenClaw แยกแนวคิดสองอย่าง:
  • การอนุญาตการเรียกใช้งาน: ใครสามารถเรียกใช้ agent ได้ (dmPolicy, groupPolicy, allowlist, gate จากการ mention)
  • การมองเห็นบริบท: บริบทเพิ่มเติมใดถูกฉีดเข้าไปใน input ของโมเดล (เนื้อความตอบกลับ, ข้อความที่อ้างถึง, ประวัติ thread, metadata ที่ส่งต่อ)
allowlist ควบคุมการเรียกใช้และการอนุญาตคำสั่ง การตั้งค่า contextVisibility ควบคุมวิธีกรองบริบทเพิ่มเติม (การตอบกลับที่อ้างถึง, root ของ thread, ประวัติที่ดึงมา):
  • contextVisibility: "all" (ค่าเริ่มต้น) เก็บบริบทเสริมไว้ตามที่ได้รับ
  • contextVisibility: "allowlist" กรองบริบทเสริมเพื่อส่งไปยังผู้ส่งที่ได้รับอนุญาตตามการตรวจสอบ allowlist ที่ใช้งานอยู่
  • contextVisibility: "allowlist_quote" ทำงานเหมือน allowlist แต่ยังคงเก็บการตอบกลับที่อ้างอิงอย่างชัดเจนไว้หนึ่งรายการ
ตั้งค่า contextVisibility ต่อช่องทางหรือต่อห้อง/การสนทนา ดูรายละเอียดการตั้งค่าที่ แชตกลุ่ม คำแนะนำการคัดแยกคำแนะนำด้านความปลอดภัย:
  • ข้อกล่าวอ้างที่แสดงเพียงว่า “model can see quoted or historical text from non-allowlisted senders” เป็นข้อค้นพบด้านการเพิ่มความแข็งแรงที่แก้ไขได้ด้วย contextVisibility ไม่ใช่การข้ามขอบเขต auth หรือ sandbox ด้วยตัวเอง
  • เพื่อให้มีผลกระทบด้านความปลอดภัย รายงานยังคงต้องแสดงให้เห็นการข้ามขอบเขตความไว้วางใจ (auth, policy, sandbox, approval หรือขอบเขตอื่นที่มีเอกสารกำกับ)

สิ่งที่การตรวจสอบ audit ตรวจ (ภาพรวมระดับสูง)

  • การเข้าถึงขาเข้า (นโยบาย DM, นโยบายกลุ่ม, allowlist): คนแปลกหน้าสามารถเรียก bot ได้หรือไม่
  • รัศมีผลกระทบของเครื่องมือ (เครื่องมือที่ยกระดับสิทธิ์ + ห้องเปิด): prompt injection อาจกลายเป็นการกระทำกับ shell/file/network ได้หรือไม่
  • การคลาดเคลื่อนของ filesystem สำหรับ exec: เครื่องมือ filesystem ที่เปลี่ยนแปลงข้อมูลถูกปฏิเสธในขณะที่ exec/process ยังใช้งานได้โดยไม่มีข้อจำกัด filesystem ของ sandbox หรือไม่
  • การคลาดเคลื่อนของการอนุมัติ exec (security=full, autoAllowSkills, allowlist ของ interpreter ที่ไม่มี strictInlineEval): guardrail สำหรับ host-exec ยังคงทำงานตามที่คุณคิดหรือไม่
    • security="full" เป็นคำเตือน posture แบบกว้าง ไม่ใช่หลักฐานของบั๊ก เป็นค่าเริ่มต้นที่เลือกไว้สำหรับการตั้งค่า personal-assistant ที่เชื่อถือได้ ให้เพิ่มความเข้มงวดเฉพาะเมื่อ threat model ของคุณต้องการ guardrail แบบ approval หรือ allowlist
  • การเปิดเผยเครือข่าย (Gateway bind/auth, Tailscale Serve/Funnel, token auth ที่อ่อนหรือสั้น)
  • การเปิดเผยการควบคุมเบราว์เซอร์ (node ระยะไกล, port relay, endpoint CDP ระยะไกล)
  • สุขอนามัยของดิสก์ภายในเครื่อง (permission, symlink, config include, path ของ “synced folder”)
  • Plugin (Plugin โหลดได้โดยไม่มี allowlist ที่ระบุชัดเจน)
  • การคลาดเคลื่อน/การตั้งค่าผิดของนโยบาย (ตั้งค่า sandbox docker ไว้แต่ปิดโหมด sandbox; pattern ของ gateway.nodes.denyCommands ไม่มีผลเพราะการจับคู่เป็นชื่อคำสั่งแบบ exact เท่านั้น (เช่น system.run) และไม่ตรวจข้อความ shell; รายการ gateway.nodes.allowCommands ที่อันตราย; tools.profile="minimal" ระดับ global ถูก override ด้วย profile ต่อ agent; เครื่องมือที่ Plugin เป็นเจ้าของเข้าถึงได้ภายใต้นโยบายเครื่องมือที่ผ่อนปรน)
  • การคลาดเคลื่อนของความคาดหวัง runtime (เช่น สมมติว่า exec โดยนัยยังหมายถึง sandbox เมื่อ tools.exec.host ตอนนี้มีค่าเริ่มต้นเป็น auto หรือกำหนด tools.exec.host="sandbox" อย่างชัดเจนในขณะที่โหมด sandbox ปิดอยู่)
  • สุขอนามัยของ model (เตือนเมื่อ model ที่ตั้งค่าดูเป็นรุ่นเก่า ไม่ใช่ hard block)
หากคุณรัน --deep OpenClaw จะพยายาม probe Gateway แบบ live ด้วยความพยายามที่ดีที่สุดด้วย

แผนที่การจัดเก็บ credential

ใช้ส่วนนี้เมื่อ audit การเข้าถึงหรือตัดสินใจว่าจะสำรองข้อมูลใด:
  • WhatsApp: ~/.openclaw/credentials/whatsapp/<accountId>/creds.json
  • token ของ Telegram bot: config/env หรือ channels.telegram.tokenFile (ไฟล์ปกติเท่านั้น; symlink ถูกปฏิเสธ)
  • token ของ Discord bot: config/env หรือ SecretRef (provider env/file/exec)
  • token ของ Slack: config/env (channels.slack.*)
  • allowlist สำหรับการจับคู่:
    • ~/.openclaw/credentials/<channel>-allowFrom.json (account เริ่มต้น)
    • ~/.openclaw/credentials/<channel>-<accountId>-allowFrom.json (account ที่ไม่ใช่ค่าเริ่มต้น)
  • profile auth ของ model: ~/.openclaw/agents/<agentId>/agent/auth-profiles.json
  • สถานะ runtime ของ Codex: ~/.openclaw/agents/<agentId>/agent/codex-home/
  • payload secrets ที่ backed ด้วยไฟล์ (ไม่บังคับ): ~/.openclaw/secrets.json
  • การนำเข้า OAuth รุ่นเก่า: ~/.openclaw/credentials/oauth.json

checklist การ audit ความปลอดภัย

เมื่อ audit พิมพ์ข้อค้นพบ ให้ถือว่านี่เป็นลำดับความสำคัญ:
  1. สิ่งใดก็ตามที่ “open” + เปิดใช้เครื่องมือ: ล็อก DM/กลุ่มก่อน (pairing/allowlist) จากนั้นเพิ่มความเข้มงวดของนโยบายเครื่องมือ/sandboxing
  2. การเปิดเผยเครือข่ายสาธารณะ (LAN bind, Funnel, ขาด auth): แก้ไขทันที
  3. การเปิดเผยการควบคุมเบราว์เซอร์ระยะไกล: ปฏิบัติเหมือนเป็นการเข้าถึงระดับ operator (เฉพาะ tailnet, จับคู่ node อย่างตั้งใจ, หลีกเลี่ยงการเปิดเผยสาธารณะ)
  4. permission: ตรวจให้แน่ใจว่า state/config/credential/auth ไม่สามารถอ่านได้โดย group/world
  5. Plugin: โหลดเฉพาะสิ่งที่คุณเชื่อถืออย่างชัดเจนเท่านั้น
  6. การเลือก model: ควรใช้ model สมัยใหม่ที่ harden ต่อ instruction สำหรับ bot ใดก็ตามที่มีเครื่องมือ

อภิธานศัพท์การ audit ความปลอดภัย

ข้อค้นพบของ audit แต่ละรายการถูกระบุด้วย checkId แบบมีโครงสร้าง (เช่น gateway.bind_no_auth หรือ tools.exec.security_full_configured) คลาสความรุนแรง critical ที่พบบ่อย:
  • fs.* - permission ของ filesystem บน state, config, credential, profile auth
  • gateway.* - โหมด bind, auth, Tailscale, Control UI, การตั้งค่า trusted-proxy
  • hooks.*, browser.*, sandbox.*, tools.exec.* - การ harden ต่อพื้นผิว
  • plugins.*, skills.* - supply chain ของ plugin/skill และข้อค้นพบจากการสแกน
  • security.exposure.* - การตรวจแบบครอบคลุมหลายส่วนที่นโยบายการเข้าถึงมาพบกับรัศมีผลกระทบของเครื่องมือ
ดู catalog ฉบับเต็มพร้อมระดับความรุนแรง, key สำหรับแก้ไข และการรองรับ auto-fix ได้ที่ การตรวจ audit ความปลอดภัย

Control UI ผ่าน HTTP

Control UI ต้องการ secure context (HTTPS หรือ localhost) เพื่อสร้าง identity ของอุปกรณ์ gateway.controlUi.allowInsecureAuth เป็น toggle ความเข้ากันได้ภายในเครื่อง:
  • บน localhost จะอนุญาต auth ของ Control UI โดยไม่มี device identity เมื่อโหลดหน้า ผ่าน HTTP ที่ไม่ปลอดภัย
  • ไม่ข้ามการตรวจ pairing
  • ไม่ผ่อนคลายข้อกำหนด device identity ระยะไกล (non-localhost)
ควรใช้ HTTPS (Tailscale Serve) หรือเปิด UI บน 127.0.0.1 สำหรับสถานการณ์ break-glass เท่านั้น gateway.controlUi.dangerouslyDisableDeviceAuth จะปิดการตรวจ device identity ทั้งหมด นี่เป็นการลดระดับความปลอดภัยอย่างรุนแรง; ให้ปิดไว้เว้นแต่คุณกำลัง debug อยู่และสามารถย้อนกลับได้อย่างรวดเร็ว แยกจาก flag อันตรายเหล่านั้น gateway.auth.mode: "trusted-proxy" ที่สำเร็จ สามารถรับ session Control UI ระดับ operator โดยไม่มี device identity ได้ นั่นเป็น พฤติกรรม auth-mode ที่ตั้งใจไว้ ไม่ใช่ทางลัดของ allowInsecureAuth และยังคง ไม่ขยายไปถึง session Control UI แบบ node-role openclaw security audit จะเตือนเมื่อเปิดใช้การตั้งค่านี้

สรุป flag ที่ไม่ปลอดภัยหรืออันตราย

openclaw security audit จะแจ้ง config.insecure_or_dangerous_flags เมื่อ เปิดใช้ debug switch ที่ทราบว่าไม่ปลอดภัย/อันตราย ให้ไม่ตั้งค่าเหล่านี้ใน production
  • gateway.controlUi.allowInsecureAuth=true
  • gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true
  • gateway.controlUi.dangerouslyDisableDeviceAuth=true
  • hooks.gmail.allowUnsafeExternalContent=true
  • hooks.mappings[<index>].allowUnsafeExternalContent=true
  • tools.exec.applyPatch.workspaceOnly=false
  • plugins.entries.acpx.config.permissionMode=approve-all
Control UI และเบราว์เซอร์:
  • gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback
  • gateway.controlUi.dangerouslyDisableDeviceAuth
  • browser.ssrfPolicy.dangerouslyAllowPrivateNetwork
การจับคู่ชื่อช่องทาง (ช่องทางที่ bundled และช่องทาง Plugin; ยังมีให้ใช้ต่อ accounts.<accountId> เมื่อใช้ได้):
  • channels.discord.dangerouslyAllowNameMatching
  • channels.slack.dangerouslyAllowNameMatching
  • channels.googlechat.dangerouslyAllowNameMatching
  • channels.msteams.dangerouslyAllowNameMatching
  • channels.synology-chat.dangerouslyAllowNameMatching (ช่องทาง Plugin)
  • channels.synology-chat.dangerouslyAllowInheritedWebhookPath (ช่องทาง Plugin)
  • channels.zalouser.dangerouslyAllowNameMatching (ช่องทาง Plugin)
  • channels.irc.dangerouslyAllowNameMatching (ช่องทาง Plugin)
  • channels.mattermost.dangerouslyAllowNameMatching (ช่องทาง Plugin)
การเปิดเผยเครือข่าย:
  • channels.telegram.network.dangerouslyAllowPrivateNetwork (ต่อ account ได้ด้วย)
Sandbox Docker (ค่าเริ่มต้น + ต่อ agent):
  • agents.defaults.sandbox.docker.dangerouslyAllowReservedContainerTargets
  • agents.defaults.sandbox.docker.dangerouslyAllowExternalBindSources
  • agents.defaults.sandbox.docker.dangerouslyAllowContainerNamespaceJoin

การตั้งค่า reverse proxy

หากคุณรัน Gateway หลัง reverse proxy (nginx, Caddy, Traefik ฯลฯ) ให้ตั้งค่า gateway.trustedProxies เพื่อจัดการ IP ของ client ที่ forwarded มาอย่างถูกต้อง เมื่อ Gateway ตรวจพบ header proxy จากที่อยู่ที่ ไม่ได้ อยู่ใน trustedProxies จะ ไม่ ถือว่า connection เป็น client ภายในเครื่อง หากปิดใช้งาน gateway auth connection เหล่านั้นจะถูกปฏิเสธ สิ่งนี้ป้องกันการข้าม authentication ซึ่ง connection ที่ผ่าน proxy มิฉะนั้นอาจดูเหมือนมาจาก localhost และได้รับความไว้วางใจโดยอัตโนมัติ gateway.trustedProxies ยังป้อนให้ gateway.auth.mode: "trusted-proxy" ด้วย แต่ auth mode นั้นเข้มงวดกว่า:
  • auth แบบ trusted-proxy fail closed กับ proxy ที่มี source เป็น loopback โดยค่าเริ่มต้น
  • reverse proxy แบบ loopback บน host เดียวกันสามารถใช้ gateway.trustedProxies สำหรับการตรวจจับ local-client และการจัดการ forwarded IP
  • reverse proxy แบบ loopback บน host เดียวกันสามารถผ่าน gateway.auth.mode: "trusted-proxy" ได้เฉพาะเมื่อ gateway.auth.trustedProxy.allowLoopback = true; มิฉะนั้นให้ใช้ auth แบบ token/password
gateway:
  trustedProxies:
    - "10.0.0.1" # reverse proxy IP
  # Optional. Default false.
  # Only enable if your proxy cannot provide X-Forwarded-For.
  allowRealIpFallback: false
  auth:
    mode: password
    password: ${OPENCLAW_GATEWAY_PASSWORD}
เมื่อกำหนดค่า trustedProxies แล้ว Gateway จะใช้ X-Forwarded-For เพื่อระบุ IP ของ client X-Real-IP จะถูกละเว้นโดยค่าเริ่มต้น เว้นแต่จะตั้งค่า gateway.allowRealIpFallback: true อย่างชัดเจน header ของ trusted proxy ไม่ได้ทำให้การจับคู่ device ของ node ถูกเชื่อถือโดยอัตโนมัติ gateway.nodes.pairing.autoApproveCidrs เป็นนโยบาย operator แยกต่างหากที่ปิดโดยค่าเริ่มต้น แม้เมื่อเปิดใช้ เส้นทาง header ของ trusted-proxy ที่มี source เป็น loopback จะถูกยกเว้นจาก auto-approval ของ node เพราะผู้เรียกภายในเครื่องสามารถปลอม header เหล่านั้นได้ รวมถึงเมื่อเปิดใช้ auth trusted-proxy แบบ loopback อย่างชัดเจน พฤติกรรม reverse proxy ที่ดี (เขียนทับ header forwarding ขาเข้า):
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
พฤติกรรม reverse proxy ที่ไม่ดี (ต่อท้าย/เก็บ header forwarding ที่ไม่น่าเชื่อถือไว้):
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

หมายเหตุเกี่ยวกับ HSTS และ origin

  • gateway ของ OpenClaw เน้น local/loopback เป็นอันดับแรก หากคุณ terminate TLS ที่ reverse proxy ให้ตั้ง HSTS บน domain HTTPS ฝั่ง proxy ที่นั่น
  • หาก gateway terminate HTTPS เอง คุณสามารถตั้ง gateway.http.securityHeaders.strictTransportSecurity เพื่อปล่อย header HSTS จาก response ของ OpenClaw
  • คำแนะนำ deployment โดยละเอียดอยู่ใน Trusted Proxy Auth
  • สำหรับ deployment ของ Control UI ที่ไม่ใช่ loopback ต้องมี gateway.controlUi.allowedOrigins โดยค่าเริ่มต้น
  • gateway.controlUi.allowedOrigins: ["*"] เป็นนโยบาย browser-origin แบบ allow-all ที่ระบุชัดเจน ไม่ใช่ค่าเริ่มต้นที่ harden แล้ว หลีกเลี่ยงนอกการทดสอบภายในเครื่องที่ควบคุมอย่างเข้มงวด
  • ความล้มเหลวของ auth แบบ browser-origin บน loopback ยังถูก rate-limit แม้เมื่อเปิดใช้ ข้อยกเว้น loopback ทั่วไป แต่ key สำหรับ lockout จะ scoped ต่อ ค่า Origin ที่ normalize แล้ว แทนที่จะเป็น bucket localhost ร่วมกันหนึ่งรายการ
  • gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true เปิดใช้โหมด fallback ของ origin จาก Host-header; ให้ถือว่าเป็นนโยบายอันตรายที่ operator เลือก
  • ให้ถือว่า DNS rebinding และพฤติกรรม header proxy-host เป็นข้อกังวลด้านการ harden deployment; จำกัด trustedProxies ให้แคบและหลีกเลี่ยงการเปิดเผย gateway โดยตรงต่ออินเทอร์เน็ตสาธารณะ

log session ภายในเครื่องอยู่บนดิสก์

OpenClaw จัดเก็บทรานสคริปต์ของเซสชันไว้บนดิสก์ภายใต้ ~/.openclaw/agents/<agentId>/sessions/*.jsonl สิ่งนี้จำเป็นสำหรับความต่อเนื่องของเซสชัน และ (เลือกได้) การทำดัชนีหน่วยความจำของเซสชัน แต่ก็หมายความว่า โปรเซส/ผู้ใช้ใด ๆ ที่มีสิทธิ์เข้าถึงระบบไฟล์สามารถอ่านบันทึกเหล่านั้นได้ ให้ถือว่าการเข้าถึงดิสก์เป็นขอบเขตความเชื่อถือ และล็อกสิทธิ์บน ~/.openclaw ให้แน่นหนา (ดูส่วนการตรวจสอบด้านล่าง) หากคุณต้องการ การแยกขาดระหว่างเอเจนต์ที่แข็งแรงกว่า ให้รันเอเจนต์เหล่านั้นภายใต้ผู้ใช้ OS แยกกันหรือโฮสต์แยกกัน

การดำเนินการ Node (system.run)

หากจับคู่ Node ของ macOS แล้ว Gateway จะสามารถเรียกใช้ system.run บน Node นั้นได้ นี่คือ การดำเนินการโค้ดระยะไกล บน Mac:
  • ต้องมีการจับคู่ Node (การอนุมัติ + โทเค็น)
  • การจับคู่ Gateway Node ไม่ใช่พื้นผิวการอนุมัติแบบรายคำสั่ง แต่เป็นการสร้างตัวตน/ความเชื่อถือของ Node และการออกโทเค็น
  • Gateway ใช้นโยบายคำสั่ง Node แบบคร่าว ๆ ระดับทั่วโลกผ่าน gateway.nodes.allowCommands / denyCommands
  • ควบคุมบน Mac ผ่าน Settings → Exec approvals (ความปลอดภัย + ถาม + allowlist)
  • นโยบาย system.run แบบราย Node คือไฟล์การอนุมัติการดำเนินการของ Node เอง (exec.approvals.node.*) ซึ่งอาจเข้มงวดกว่าหรือผ่อนปรนกว่านโยบาย command-ID ระดับทั่วโลกของ Gateway
  • Node ที่รันด้วย security="full" และ ask="off" กำลังทำตามโมเดลผู้ปฏิบัติการที่เชื่อถือได้ตามค่าเริ่มต้น ให้ถือว่านั่นเป็นพฤติกรรมที่คาดไว้ เว้นแต่การปรับใช้ของคุณจะต้องการจุดยืนการอนุมัติหรือ allowlist ที่เข้มงวดกว่าอย่างชัดเจน
  • โหมดการอนุมัติผูกกับบริบทคำขอที่แน่นอน และเมื่อเป็นไปได้ จะผูกกับโอเปอแรนด์สคริปต์/ไฟล์โลคัลหนึ่งรายการที่เป็นรูปธรรม หาก OpenClaw ไม่สามารถระบุไฟล์โลคัลโดยตรงเพียงหนึ่งไฟล์สำหรับคำสั่งอินเทอร์พรีเตอร์/รันไทม์ได้อย่างแน่นอน การดำเนินการที่อ้างอิงการอนุมัติจะถูกปฏิเสธ แทนที่จะสัญญาว่าครอบคลุมเชิงความหมายทั้งหมด
  • สำหรับ host=node การรันที่อ้างอิงการอนุมัติยังจัดเก็บ systemRunPlan ที่เตรียมไว้ในรูปแบบมาตรฐานด้วย การส่งต่อที่ได้รับอนุมัติในภายหลังจะใช้แผนที่จัดเก็บไว้นั้นซ้ำ และการตรวจสอบความถูกต้องของ Gateway จะปฏิเสธการแก้ไขของผู้เรียกต่อคำสั่ง/cwd/บริบทเซสชัน หลังจากที่ คำขออนุมัติถูกสร้างขึ้นแล้ว
  • หากคุณไม่ต้องการการดำเนินการระยะไกล ให้ตั้งค่าความปลอดภัยเป็น deny และลบการจับคู่ Node สำหรับ Mac เครื่องนั้น
ความแตกต่างนี้สำคัญต่อการคัดแยกปัญหา:
  • Node ที่จับคู่แล้วซึ่งเชื่อมต่อใหม่และประกาศรายการคำสั่งที่ต่างออกไป ไม่ใช่ช่องโหว่ในตัวมันเอง หากนโยบายระดับทั่วโลกของ Gateway และการอนุมัติการดำเนินการโลคัลของ Node ยังคงบังคับใช้ขอบเขตการดำเนินการจริง
  • รายงานที่ถือว่าเมทาดาทาการจับคู่ Node เป็นเลเยอร์การอนุมัติรายคำสั่งลับอีกชั้น มักเป็นความสับสนด้านนโยบาย/UX ไม่ใช่การข้ามขอบเขตความปลอดภัย

Skills แบบไดนามิก (ตัวเฝ้าดู / Node ระยะไกล)

OpenClaw สามารถรีเฟรชรายการ Skills ระหว่างเซสชันได้:
  • ตัวเฝ้าดู Skills: การเปลี่ยนแปลงใน SKILL.md สามารถอัปเดตสแนปชอต Skills ได้ในเทิร์นถัดไปของเอเจนต์
  • Node ระยะไกล: การเชื่อมต่อ Node ของ macOS สามารถทำให้ Skills เฉพาะ macOS มีสิทธิ์ใช้งานได้ (อิงจากการตรวจสอบ bin)
ให้ถือว่าโฟลเดอร์ Skills เป็น โค้ดที่เชื่อถือได้ และจำกัดผู้ที่สามารถแก้ไขโฟลเดอร์เหล่านั้น

โมเดลภัยคุกคาม

ผู้ช่วย AI ของคุณสามารถ:
  • ดำเนินการคำสั่งเชลล์ใด ๆ ก็ได้
  • อ่าน/เขียนไฟล์
  • เข้าถึงบริการเครือข่าย
  • ส่งข้อความถึงใครก็ได้ (หากคุณให้สิทธิ์เข้าถึง WhatsApp)
คนที่ส่งข้อความถึงคุณสามารถ:
  • พยายามหลอก AI ของคุณให้ทำสิ่งที่ไม่ดี
  • ใช้วิศวกรรมสังคมเพื่อเข้าถึงข้อมูลของคุณ
  • ตรวจสอบรายละเอียดโครงสร้างพื้นฐาน

แนวคิดหลัก: การควบคุมการเข้าถึงก่อนความฉลาด

ความล้มเหลวส่วนใหญ่ในที่นี้ไม่ใช่การโจมตีที่ซับซ้อน แต่คือ “มีคนส่งข้อความหาบอต แล้วบอตก็ทำตามที่พวกเขาขอ” จุดยืนของ OpenClaw:
  • ตัวตนก่อน: ตัดสินว่าใครสามารถคุยกับบอตได้ (การจับคู่ DM / allowlist / “open” อย่างชัดเจน)
  • ขอบเขตถัดมา: ตัดสินว่าบอตได้รับอนุญาตให้ดำเนินการที่ใด (allowlist ของกลุ่ม + การเปิดใช้งานด้วยการกล่าวถึง, เครื่องมือ, sandboxing, สิทธิ์อุปกรณ์)
  • โมเดลสุดท้าย: สมมติว่าโมเดลสามารถถูกชักจูงได้ ออกแบบให้การชักจูงมีรัศมีผลกระทบจำกัด

โมเดลการอนุญาตคำสั่ง

คำสั่ง Slash และ directive จะถูกยอมรับเฉพาะสำหรับ ผู้ส่งที่ได้รับอนุญาต เท่านั้น การอนุญาตได้มาจาก allowlist/การจับคู่ของช่องทาง รวมถึง commands.useAccessGroups (ดู การกำหนดค่า และ คำสั่ง Slash) หาก allowlist ของช่องทางว่างเปล่าหรือมี "*", คำสั่งจะเปิดใช้งานโดยปริยายสำหรับช่องทางนั้น /exec เป็นความสะดวกเฉพาะเซสชันสำหรับผู้ปฏิบัติการที่ได้รับอนุญาต มัน ไม่ เขียน config หรือ เปลี่ยนเซสชันอื่น

ความเสี่ยงของเครื่องมือระนาบควบคุม

เครื่องมือในตัวสองตัวสามารถทำการเปลี่ยนแปลงระนาบควบคุมแบบถาวรได้:
  • gateway สามารถตรวจสอบ config ด้วย config.schema.lookup / config.get และสามารถทำการเปลี่ยนแปลงถาวรด้วย config.apply, config.patch และ update.run
  • cron สามารถสร้างงานตามกำหนดเวลาที่ยังคงรันต่อไปหลังจากแชต/งานเดิมสิ้นสุดแล้ว
เครื่องมือรันไทม์ gateway แบบเจ้าของเท่านั้นยังคงปฏิเสธการเขียนทับ tools.exec.ask หรือ tools.exec.security; alias แบบเก่า tools.bash.* จะถูก ทำให้เป็นมาตรฐานไปยังพาธ exec ที่ได้รับการป้องกันเดียวกันก่อนการเขียน การแก้ไข gateway config.apply และ gateway config.patch ที่ขับเคลื่อนโดยเอเจนต์ จะปิดเมื่อผิดพลาดตามค่าเริ่มต้น: มีเพียงชุดพาธที่แคบของ prompt, model และการเปิดใช้งานด้วยการกล่าวถึง เท่านั้นที่เอเจนต์ปรับแต่งได้ ดังนั้นแผนผัง config ที่ละเอียดอ่อนใหม่จึงได้รับการป้องกัน เว้นแต่จะถูกเพิ่มเข้า allowlist โดยตั้งใจ สำหรับเอเจนต์/พื้นผิวใด ๆ ที่จัดการเนื้อหาที่ไม่เชื่อถือ ให้ปฏิเสธรายการเหล่านี้ตามค่าเริ่มต้น:
{
  tools: {
    deny: ["gateway", "cron", "sessions_spawn", "sessions_send"],
  },
}
commands.restart=false บล็อกเฉพาะการดำเนินการรีสตาร์ตเท่านั้น มันไม่ได้ปิดใช้งานการดำเนินการ config/update ของ gateway

Plugin

Plugin รัน ในโปรเซสเดียวกัน กับ Gateway ให้ถือว่าเป็นโค้ดที่เชื่อถือได้:
  • ติดตั้ง Plugin จากแหล่งที่คุณเชื่อถือเท่านั้น
  • ควรใช้ allowlist plugins.allow ที่ระบุอย่างชัดเจน
  • ตรวจสอบ config ของ Plugin ก่อนเปิดใช้งาน
  • รีสตาร์ต Gateway หลังจากมีการเปลี่ยนแปลง Plugin
  • หากคุณติดตั้งหรืออัปเดต Plugin (openclaw plugins install <package>, openclaw plugins update <id>) ให้ถือว่าเหมือนการรันโค้ดที่ไม่เชื่อถือ:
    • พาธติดตั้งคือไดเรกทอรีราย Plugin ภายใต้รูทการติดตั้ง Plugin ที่ใช้งานอยู่
    • OpenClaw รันการสแกนโค้ดอันตรายในตัวก่อนการติดตั้ง/อัปเดต ผลการตรวจพบระดับ critical จะบล็อกตามค่าเริ่มต้น
    • การติดตั้ง Plugin ผ่าน npm และ git จะรันการปรับ dependency ให้สอดคล้องผ่าน package-manager เฉพาะระหว่างโฟลว์ติดตั้ง/อัปเดตที่ชัดเจนเท่านั้น พาธโลคัลและ archive จะถูกถือเป็นแพ็กเกจ Plugin ที่สมบูรณ์ในตัวเอง OpenClaw จะคัดลอก/อ้างอิงสิ่งเหล่านั้นโดยไม่รัน npm install
    • ควรใช้เวอร์ชันที่ปักหมุดแบบแน่นอน (@scope/pkg@1.2.3) และตรวจสอบโค้ดที่แตกไฟล์บนดิสก์ก่อนเปิดใช้งาน
    • --dangerously-force-unsafe-install มีไว้สำหรับกรณีฉุกเฉินเท่านั้น เมื่อการสแกนในตัวแจ้งผลบวกเทียมในโฟลว์ติดตั้ง/อัปเดต Plugin มันไม่ข้ามการบล็อกนโยบาย hook before_install ของ Plugin และไม่ข้ามความล้มเหลวของการสแกน
    • การติดตั้ง dependency ของ Skills ที่อ้างอิง Gateway ใช้การแบ่ง dangerous/suspicious แบบเดียวกัน: ผลการตรวจพบ critical ในตัวจะบล็อก เว้นแต่ผู้เรียกจะตั้งค่า dangerouslyForceUnsafeInstall อย่างชัดเจน ขณะที่ผลการตรวจพบที่น่าสงสัยยังคงเตือนเท่านั้น openclaw skills install ยังคงเป็นโฟลว์ดาวน์โหลด/ติดตั้ง Skills ของ ClawHub แยกต่างหาก
รายละเอียด: Plugin

โมเดลการเข้าถึง DM: การจับคู่, allowlist, open, disabled

ช่องทางปัจจุบันทั้งหมดที่รองรับ DM รองรับนโยบาย DM (dmPolicy หรือ *.dm.policy) ที่กั้น DM ขาเข้า ก่อน ประมวลผลข้อความ:
  • pairing (ค่าเริ่มต้น): ผู้ส่งที่ไม่รู้จักจะได้รับรหัสจับคู่สั้น ๆ และบอตจะเพิกเฉยต่อข้อความของพวกเขาจนกว่าจะได้รับอนุมัติ รหัสหมดอายุหลังจาก 1 ชั่วโมง; DM ซ้ำจะไม่ส่งรหัสอีกจนกว่าจะมีการสร้างคำขอใหม่ คำขอที่รออยู่ถูกจำกัดไว้ที่ 3 ต่อช่องทาง ตามค่าเริ่มต้น
  • allowlist: ผู้ส่งที่ไม่รู้จักจะถูกบล็อก (ไม่มี handshake การจับคู่)
  • open: อนุญาตให้ใครก็ได้ส่ง DM (สาธารณะ) ต้อง ให้ allowlist ของช่องทางมี "*" (การเลือกเปิดใช้งานอย่างชัดเจน)
  • disabled: เพิกเฉยต่อ DM ขาเข้าทั้งหมด
อนุมัติผ่าน CLI:
openclaw pairing list <channel>
openclaw pairing approve <channel> <code>
รายละเอียด + ไฟล์บนดิสก์: การจับคู่

การแยกเซสชัน DM (โหมดผู้ใช้หลายคน)

ตามค่าเริ่มต้น OpenClaw จะส่ง DM ทั้งหมดเข้าสู่เซสชันหลัก เพื่อให้ผู้ช่วยของคุณมีความต่อเนื่องข้ามอุปกรณ์และช่องทาง หาก หลายคน สามารถส่ง DM ถึงบอตได้ (DM แบบ open หรือ allowlist หลายคน) ให้พิจารณาแยกเซสชัน DM:
{
  session: { dmScope: "per-channel-peer" },
}
สิ่งนี้ป้องกันการรั่วไหลของบริบทข้ามผู้ใช้ ขณะยังคงแยกแชตกลุ่มออกจากกัน นี่เป็นขอบเขตบริบทการส่งข้อความ ไม่ใช่ขอบเขตผู้ดูแลโฮสต์ หากผู้ใช้เป็นฝ่ายตรงข้ามกันและแชร์โฮสต์/config ของ Gateway เดียวกัน ให้รัน Gateway แยกกันตามขอบเขตความเชื่อถือแทน

โหมด DM ที่ปลอดภัย (แนะนำ)

ให้ถือ snippet ด้านบนเป็น โหมด DM ที่ปลอดภัย:
  • ค่าเริ่มต้น: session.dmScope: "main" (DM ทั้งหมดแชร์เซสชันเดียวเพื่อความต่อเนื่อง)
  • ค่าเริ่มต้นของการเริ่มใช้งาน CLI โลคัล: เขียน session.dmScope: "per-channel-peer" เมื่อยังไม่ได้ตั้งค่า (คงค่าที่ระบุไว้อย่างชัดเจนเดิมไว้)
  • โหมด DM ที่ปลอดภัย: session.dmScope: "per-channel-peer" (คู่ช่องทาง+ผู้ส่งแต่ละคู่จะได้บริบท DM ที่แยกกัน)
  • การแยก peer ข้ามช่องทาง: session.dmScope: "per-peer" (ผู้ส่งแต่ละรายได้หนึ่งเซสชันข้ามทุกช่องทางประเภทเดียวกัน)
หากคุณรันหลายบัญชีบนช่องทางเดียวกัน ให้ใช้ per-account-channel-peer แทน หากบุคคลเดียวกันติดต่อคุณบนหลายช่องทาง ให้ใช้ session.identityLinks เพื่อรวมเซสชัน DM เหล่านั้นเป็นตัวตนมาตรฐานเดียว ดู การจัดการเซสชัน และ การกำหนดค่า

Allowlists สำหรับ DM และกลุ่ม

OpenClaw มีเลเยอร์ “ใครสามารถทริกเกอร์ฉันได้?” แยกกันสองชั้น:
  • DM allowlist (allowFrom / channels.discord.allowFrom / channels.slack.allowFrom; แบบเก่า: channels.discord.dm.allowFrom, channels.slack.dm.allowFrom): ใครได้รับอนุญาตให้คุยกับบอตในข้อความโดยตรง
    • เมื่อ dmPolicy="pairing" การอนุมัติจะถูกเขียนไปยังที่เก็บ allowlist การจับคู่แบบผูกกับบัญชีภายใต้ ~/.openclaw/credentials/ (<channel>-allowFrom.json สำหรับบัญชีเริ่มต้น, <channel>-<accountId>-allowFrom.json สำหรับบัญชีที่ไม่ใช่ค่าเริ่มต้น) แล้วผสานกับ allowlist ใน config
  • Group allowlist (เฉพาะช่องทาง): กลุ่ม/ช่องทาง/guild ใดที่บอตจะยอมรับข้อความด้วย
    • รูปแบบทั่วไป:
      • channels.whatsapp.groups, channels.telegram.groups, channels.imessage.groups: ค่าเริ่มต้นรายกลุ่ม เช่น requireMention; เมื่อตั้งค่าแล้ว จะทำหน้าที่เป็น group allowlist ด้วย (ใส่ "*" เพื่อคงพฤติกรรมอนุญาตทั้งหมด)
      • groupPolicy="allowlist" + groupAllowFrom: จำกัดว่าใครสามารถทริกเกอร์บอต ภายใน เซสชันกลุ่มได้ (WhatsApp/Telegram/Signal/iMessage/Microsoft Teams)
      • channels.discord.guilds / channels.slack.channels: allowlist รายพื้นผิว + ค่าเริ่มต้นการกล่าวถึง
    • การตรวจสอบกลุ่มรันตามลำดับนี้: groupPolicy/group allowlist ก่อน, การเปิดใช้งานด้วยการกล่าวถึง/ตอบกลับเป็นลำดับที่สอง
    • การตอบกลับข้อความของบอต (การกล่าวถึงโดยนัย) ไม่ ข้าม allowlist ของผู้ส่ง เช่น groupAllowFrom
    • หมายเหตุด้านความปลอดภัย: ให้ถือว่า dmPolicy="open" และ groupPolicy="open" เป็นการตั้งค่าทางเลือกสุดท้าย ควรใช้น้อยมาก; ควรใช้การจับคู่ + allowlist เว้นแต่คุณจะเชื่อถือสมาชิกทุกคนในห้องอย่างสมบูรณ์
รายละเอียด: การกำหนดค่า และ กลุ่ม

Prompt injection (คืออะไร และเหตุใดจึงสำคัญ)

Prompt injection คือการที่ผู้โจมตีสร้างข้อความที่ชักจูงโมเดลให้ทำสิ่งที่ไม่ปลอดภัย (“ignore your instructions”, “dump your filesystem”, “follow this link and run commands” ฯลฯ) แม้จะมี system prompts ที่แข็งแรง prompt injection ก็ยังไม่ได้ถูกแก้ปัญหาอย่างสมบูรณ์ guardrails ของ system prompt เป็นเพียงคำแนะนำแบบอ่อนเท่านั้น; การบังคับใช้แบบแข็งมาจากนโยบายเครื่องมือ, การอนุมัติ exec, sandboxing และ allowlist ของช่องทาง (และผู้ปฏิบัติการสามารถปิดใช้งานสิ่งเหล่านี้ได้ตามการออกแบบ) สิ่งที่ช่วยได้ในทางปฏิบัติ:
  • ล็อก DM ขาเข้าให้แน่นหนา (การจับคู่/รายการอนุญาต)
  • ในกลุ่ม ควรใช้การอนุญาตเมื่อถูกกล่าวถึง; หลีกเลี่ยงบอตที่ “ทำงานตลอดเวลา” ในห้องสาธารณะ
  • ถือว่าลิงก์ ไฟล์แนบ และคำสั่งที่วางเข้ามาเป็นอันตรายโดยค่าเริ่มต้น
  • เรียกใช้การดำเนินการเครื่องมือที่ละเอียดอ่อนใน sandbox; เก็บความลับไว้นอกระบบไฟล์ที่ agent เข้าถึงได้
  • หมายเหตุ: การใช้ sandbox เป็นแบบเลือกเปิดใช้ หากปิดโหมด sandbox ค่า host=auto โดยนัยจะถูกแปลงเป็นโฮสต์ Gateway ค่า host=sandbox ที่ระบุชัดเจนจะยังคงล้มเหลวแบบปิด เพราะไม่มี runtime ของ sandbox ให้ใช้งาน ตั้งค่า host=gateway หากคุณต้องการให้พฤติกรรมนั้นระบุไว้อย่างชัดเจนใน config
  • จำกัดเครื่องมือความเสี่ยงสูง (exec, browser, web_fetch, web_search) ให้ใช้ได้เฉพาะ agent ที่เชื่อถือได้หรือรายการอนุญาตที่ระบุชัดเจน
  • หากคุณใส่ interpreter ไว้ในรายการอนุญาต (python, node, ruby, perl, php, lua, osascript) ให้เปิดใช้ tools.exec.strictInlineEval เพื่อให้รูปแบบ inline eval ยังคงต้องได้รับการอนุมัติอย่างชัดเจน
  • การวิเคราะห์การอนุมัติของ shell ยังปฏิเสธรูปแบบ POSIX parameter-expansion ($VAR, $?, $$, $1, $@, ${…}) ภายใน heredoc ที่ไม่ได้ใส่เครื่องหมายคำพูด ดังนั้นเนื้อหา heredoc ที่อยู่ในรายการอนุญาตจะไม่สามารถเล็ดลอดการขยายตัวของ shell ผ่านการตรวจสอบรายการอนุญาตในฐานะข้อความธรรมดาได้ ใส่เครื่องหมายคำพูดให้ตัวสิ้นสุด heredoc (เช่น <<'EOF') เพื่อเลือกใช้ความหมายของเนื้อหาแบบ literal; heredoc ที่ไม่ได้ใส่เครื่องหมายคำพูดซึ่งจะมีการขยายตัวแปรจะถูกปฏิเสธ
  • การเลือกรุ่นโมเดลมีผลสำคัญ: โมเดลเก่า/เล็กกว่า/legacy มีความทนทานต่อ prompt injection และการใช้เครื่องมือผิดวิธีน้อยกว่ามาก สำหรับ agent ที่เปิดใช้เครื่องมือ ให้ใช้โมเดลรุ่นล่าสุดที่แข็งแกร่งที่สุดและเสริมความแข็งแรงด้าน instruction เท่าที่มี
สัญญาณเตือนที่ควรถือว่าไม่น่าเชื่อถือ:
  • “อ่านไฟล์/URL นี้ แล้วทำตามที่บอกทุกอย่าง”
  • “ละเว้น system prompt หรือกฎความปลอดภัยของคุณ”
  • “เปิดเผยคำสั่งที่ซ่อนไว้หรือ output ของเครื่องมือ”
  • “วางเนื้อหาทั้งหมดของ ~/.openclaw หรือ log ของคุณ”

การล้าง special-token ของเนื้อหาภายนอก

OpenClaw จะลบ literal ของ special-token ที่พบบ่อยใน chat template ของ LLM แบบ self-hosted ออกจากเนื้อหาและ metadata ภายนอกที่ถูกห่อไว้ ก่อนที่สิ่งเหล่านั้นจะไปถึงโมเดล กลุ่ม marker ที่ครอบคลุมรวมถึง token บทบาท/turn ของ Qwen/ChatML, Llama, Gemma, Mistral, Phi และ GPT-OSS เหตุผล:
  • backend ที่เข้ากันได้กับ OpenAI ซึ่งอยู่หน้าโมเดล self-hosted บางครั้งจะเก็บ special token ที่ปรากฏในข้อความผู้ใช้ไว้แทนที่จะ mask token เหล่านั้น ผู้โจมตีที่สามารถเขียนลงในเนื้อหาภายนอกขาเข้า (หน้าที่ fetch มา, เนื้อหา email, output ของเครื่องมืออ่านเนื้อหาไฟล์) อาจ inject ขอบเขตบทบาท assistant หรือ system สังเคราะห์และหลบ guardrail ของ wrapped-content ได้
  • การล้างเกิดขึ้นที่ชั้นการห่อเนื้อหาภายนอก จึงใช้ได้อย่างสม่ำเสมอทั้งกับเครื่องมือ fetch/read และเนื้อหาช่องทางขาเข้า แทนที่จะผูกกับ provider รายตัว
  • การตอบกลับขาออกของโมเดลมี sanitizer แยกอยู่แล้ว ซึ่งลบ <tool_call>, <function_calls>, <system-reminder>, <previous_response> ที่รั่วออกมา และโครง runtime ภายในที่คล้ายกันออกจากการตอบกลับที่ผู้ใช้เห็น ณ ขอบเขตส่งมอบช่องทางสุดท้าย sanitizer ของเนื้อหาภายนอกคือส่วนคู่กันฝั่งขาเข้า
สิ่งนี้ไม่ได้แทนที่การเสริมความแข็งแรงอื่นบนหน้านี้ - dmPolicy, รายการอนุญาต, การอนุมัติ exec, sandboxing และ contextVisibility ยังทำงานหลักอยู่ สิ่งนี้ปิดช่องทางเลี่ยงเฉพาะจุดหนึ่งในชั้น tokenizer สำหรับสแตก self-hosted ที่ส่งต่อข้อความผู้ใช้โดยคง special token ไว้ครบถ้วน

flag เลี่ยงเนื้อหาภายนอกที่ไม่ปลอดภัย

OpenClaw มี flag เลี่ยงแบบชัดเจนที่ปิดการห่อความปลอดภัยของเนื้อหาภายนอก:
  • hooks.mappings[].allowUnsafeExternalContent
  • hooks.gmail.allowUnsafeExternalContent
  • ฟิลด์ payload ของ Cron allowUnsafeExternalContent
แนวทาง:
  • ใน production ให้ปล่อยค่าเหล่านี้เป็น unset/false
  • เปิดใช้ชั่วคราวเท่านั้นสำหรับการ debug ที่มีขอบเขตแคบ
  • หากเปิดใช้ ให้แยก agent นั้นออกมา (sandbox + เครื่องมือน้อยที่สุด + namespace ของ session เฉพาะ)
หมายเหตุความเสี่ยงของ hook:
  • payload ของ Hook เป็นเนื้อหาที่ไม่น่าเชื่อถือ แม้การส่งมอบจะมาจากระบบที่คุณควบคุมก็ตาม (เนื้อหา mail/docs/web อาจมี prompt injection)
  • tier ของโมเดลที่อ่อนแอจะเพิ่มความเสี่ยงนี้ สำหรับ automation ที่ขับเคลื่อนด้วย hook ให้ใช้ tier โมเดลสมัยใหม่ที่แข็งแกร่ง และคุม policy ของเครื่องมือให้เข้มงวด (tools.profile: "messaging" หรือเข้มงวดกว่า) พร้อม sandboxing เมื่อทำได้

Prompt injection ไม่จำเป็นต้องใช้ DM สาธารณะ

แม้ว่า มีเพียงคุณ ที่ส่งข้อความหาบอตได้ prompt injection ก็ยังเกิดขึ้นได้ผ่าน เนื้อหาที่ไม่น่าเชื่อถือ ใดๆ ที่บอตอ่าน (ผลลัพธ์ web search/fetch, หน้า browser, email, docs, ไฟล์แนบ, log/code ที่วางเข้ามา) กล่าวอีกอย่าง: ผู้ส่งไม่ใช่ พื้นผิวภัยคุกคามเพียงอย่างเดียว; ตัวเนื้อหาเอง สามารถพกคำสั่งเชิงโจมตีมาได้ เมื่อเปิดใช้เครื่องมือ ความเสี่ยงทั่วไปคือการขโมย context หรือกระตุ้นให้เกิด tool call ลดขอบเขตผลกระทบโดย:
  • ใช้ reader agent แบบอ่านอย่างเดียวหรือปิดเครื่องมือ เพื่อสรุปเนื้อหาที่ไม่น่าเชื่อถือ แล้วส่งสรุปนั้นให้ agent หลักของคุณ
  • ปิด web_search / web_fetch / browser สำหรับ agent ที่เปิดใช้เครื่องมือ เว้นแต่จำเป็น
  • สำหรับ input URL ของ OpenResponses (input_file / input_image) ให้ตั้ง gateway.http.endpoints.responses.files.urlAllowlist และ gateway.http.endpoints.responses.images.urlAllowlist ให้เข้มงวด และตั้ง maxUrlParts ให้ต่ำ รายการอนุญาตว่างจะถือว่าไม่ได้ตั้งค่า; ใช้ files.allowUrl: false / images.allowUrl: false หากคุณต้องการปิดการ fetch URL ทั้งหมด
  • สำหรับ input ไฟล์ของ OpenResponses ข้อความ input_file ที่ decode แล้วจะยังถูก inject เป็น เนื้อหาภายนอกที่ไม่น่าเชื่อถือ อย่าพึ่งพาว่าข้อความในไฟล์เชื่อถือได้เพียงเพราะ Gateway decode ไฟล์นั้นภายในเครื่อง บล็อกที่ inject ยังมี marker ขอบเขต <<<EXTERNAL_UNTRUSTED_CONTENT ...>>> พร้อม metadata Source: External แม้ว่า path นี้จะละเว้น banner SECURITY NOTICE: ที่ยาวกว่า
  • การห่อด้วย marker แบบเดียวกันจะถูกใช้เมื่อ media-understanding ดึงข้อความ จากเอกสารแนบก่อนเพิ่มข้อความนั้นต่อท้าย media prompt
  • เปิดใช้ sandboxing และรายการอนุญาตเครื่องมือที่เข้มงวดสำหรับ agent ใดๆ ที่แตะ input ที่ไม่น่าเชื่อถือ
  • เก็บความลับไว้นอก prompt; ส่งผ่าน env/config บนโฮสต์ Gateway แทน

backend LLM แบบ self-hosted

backend แบบ self-hosted ที่เข้ากันได้กับ OpenAI เช่น vLLM, SGLang, TGI, LM Studio, หรือสแตก tokenizer ของ Hugging Face แบบกำหนดเอง อาจแตกต่างจาก hosted provider ในวิธี จัดการ special token ของ chat template หาก backend tokenize string literal เช่น <|im_start|>, <|start_header_id|>, หรือ <start_of_turn> เป็น token โครงสร้างของ chat template ภายในเนื้อหาผู้ใช้ ข้อความที่ไม่น่าเชื่อถืออาจพยายาม ปลอมขอบเขตบทบาทที่ชั้น tokenizer ได้ OpenClaw ลบ literal ของ special-token กลุ่มโมเดลที่พบบ่อยออกจาก เนื้อหาภายนอกที่ถูกห่อไว้ก่อนส่งไปยังโมเดล เปิดใช้การห่อเนื้อหาภายนอกไว้ และควรเลือกการตั้งค่า backend ที่แยกหรือ escape special token ในเนื้อหาที่ผู้ใช้ให้มาเมื่อมีให้ใช้ Hosted provider เช่น OpenAI และ Anthropic ใช้การล้างฝั่ง request ของตนเองอยู่แล้ว

ความแข็งแกร่งของโมเดล (หมายเหตุด้านความปลอดภัย)

ความต้านทานต่อ prompt injection ไม่ สม่ำเสมอกันในทุก tier ของโมเดล โดยทั่วไปโมเดลที่เล็กกว่า/ถูกกว่าจะเสี่ยงต่อการใช้เครื่องมือผิดวิธีและการยึดครองคำสั่งมากกว่า โดยเฉพาะภายใต้ prompt เชิงโจมตี
สำหรับ agent ที่เปิดใช้เครื่องมือหรือ agent ที่อ่านเนื้อหาที่ไม่น่าเชื่อถือ ความเสี่ยง prompt-injection กับโมเดลเก่า/เล็กกว่ามักสูงเกินไป อย่าใช้ workload เหล่านั้นบน tier โมเดลที่อ่อนแอ
คำแนะนำ:
  • ใช้โมเดลรุ่นล่าสุด tier ดีที่สุด สำหรับบอตใดๆ ที่เรียกใช้เครื่องมือหรือแตะไฟล์/เครือข่ายได้
  • อย่าใช้ tier ที่เก่ากว่า/อ่อนแอกว่า/เล็กกว่า สำหรับ agent ที่เปิดใช้เครื่องมือหรือ inbox ที่ไม่น่าเชื่อถือ; ความเสี่ยง prompt-injection สูงเกินไป
  • หากจำเป็นต้องใช้โมเดลที่เล็กกว่า ให้ ลดขอบเขตผลกระทบ (เครื่องมืออ่านอย่างเดียว, sandboxing ที่แข็งแกร่ง, การเข้าถึงระบบไฟล์ขั้นต่ำ, รายการอนุญาตที่เข้มงวด)
  • เมื่อเรียกใช้โมเดลขนาดเล็ก ให้ เปิดใช้ sandboxing สำหรับทุก session และ ปิด web_search/web_fetch/browser เว้นแต่ input จะถูกควบคุมอย่างเข้มงวด
  • สำหรับผู้ช่วยส่วนตัวแบบแชทอย่างเดียวที่มี input ที่เชื่อถือได้และไม่มีเครื่องมือ โมเดลที่เล็กกว่ามักใช้ได้

Reasoning และ output แบบ verbose ในกลุ่ม

/reasoning, /verbose, และ /trace อาจเปิดเผย reasoning ภายใน, output ของเครื่องมือ, หรือการวินิจฉัย Plugin ที่ ไม่ได้ตั้งใจให้เผยแพร่ในช่องสาธารณะ ในบริบทกลุ่ม ให้ถือว่าสิ่งเหล่านี้มีไว้สำหรับ debug เท่านั้น และปิดไว้ เว้นแต่คุณต้องการใช้อย่างชัดเจน แนวทาง:
  • ปิด /reasoning, /verbose, และ /trace ไว้ในห้องสาธารณะ
  • หากคุณเปิดใช้ ให้ทำเฉพาะใน DM ที่เชื่อถือได้หรือห้องที่ควบคุมอย่างเข้มงวด
  • จำไว้ว่า: output แบบ verbose และ trace อาจมี args ของเครื่องมือ, URL, การวินิจฉัย Plugin และข้อมูลที่โมเดลเห็น

ตัวอย่างการเสริมความแข็งแรงของการกำหนดค่า

สิทธิ์ของไฟล์

เก็บ config + state ให้เป็นส่วนตัวบนโฮสต์ Gateway:
  • ~/.openclaw/openclaw.json: 600 (ผู้ใช้ read/write เท่านั้น)
  • ~/.openclaw: 700 (ผู้ใช้เท่านั้น)
openclaw doctor สามารถเตือนและเสนอให้ปรับสิทธิ์เหล่านี้ให้เข้มงวดขึ้นได้

การเปิดเผยเครือข่าย (bind, port, firewall)

Gateway multiplex WebSocket + HTTP บนพอร์ตเดียว:
  • ค่าเริ่มต้น: 18789
  • Config/flag/env: gateway.port, --port, OPENCLAW_GATEWAY_PORT
พื้นผิว HTTP นี้รวม Control UI และ canvas host:
  • Control UI (SPA assets) (base path เริ่มต้น /)
  • Canvas host: /__openclaw__/canvas/ และ /__openclaw__/a2ui/ (HTML/JS ใดๆ; ถือว่าเป็นเนื้อหาที่ไม่น่าเชื่อถือ)
หากคุณโหลดเนื้อหา canvas ใน browser ปกติ ให้ปฏิบัติเหมือนเป็นหน้าเว็บที่ไม่น่าเชื่อถืออื่นๆ:
  • อย่าเปิดเผย canvas host ต่อเครือข่าย/ผู้ใช้ที่ไม่น่าเชื่อถือ
  • อย่าทำให้เนื้อหา canvas ใช้ origin เดียวกับพื้นผิวเว็บที่มีสิทธิ์สูง เว้นแต่คุณเข้าใจผลกระทบอย่างครบถ้วน
โหมด bind ควบคุมว่า Gateway รับการเชื่อมต่อที่ใด:
  • gateway.bind: "loopback" (ค่าเริ่มต้น): เฉพาะ client ภายในเครื่องเท่านั้นที่เชื่อมต่อได้
  • การ bind ที่ไม่ใช่ loopback ("lan", "tailnet", "custom") จะขยายพื้นผิวโจมตี ใช้เฉพาะเมื่อมี auth ของ Gateway (token/password ที่ใช้ร่วมกัน หรือ proxy ที่เชื่อถือได้ซึ่งกำหนดค่าอย่างถูกต้อง) และ firewall จริง
หลักปฏิบัติโดยทั่วไป:
  • ควรใช้ Tailscale Serve แทน LAN bind (Serve ทำให้ Gateway อยู่บน loopback และ Tailscale จัดการการเข้าถึง)
  • หากจำเป็นต้อง bind กับ LAN ให้ firewall พอร์ตไปยังรายการอนุญาต source IP ที่แคบ; อย่า port-forward แบบกว้าง
  • ห้ามเปิดเผย Gateway แบบไม่ผ่านการยืนยันตัวตนบน 0.0.0.0

การ publish พอร์ต Docker ด้วย UFW

หากคุณเรียกใช้ OpenClaw ด้วย Docker บน VPS โปรดจำไว้ว่าพอร์ต container ที่ publish (-p HOST:CONTAINER หรือ Compose ports:) จะถูก route ผ่าน forwarding chain ของ Docker ไม่ใช่เฉพาะกฎ INPUT ของ host เท่านั้น เพื่อให้ traffic ของ Docker สอดคล้องกับ policy firewall ของคุณ ให้บังคับใช้กฎใน DOCKER-USER (chain นี้ถูกประเมินก่อนกฎ accept ของ Docker เอง) บน distro สมัยใหม่จำนวนมาก iptables/ip6tables ใช้ frontend iptables-nft และยังคงใช้กฎเหล่านี้กับ backend nftables ตัวอย่างรายการอนุญาตขั้นต่ำ (IPv4):
# /etc/ufw/after.rules (append as its own *filter section)
*filter
:DOCKER-USER - [0:0]
-A DOCKER-USER -m conntrack --ctstate ESTABLISHED,RELATED -j RETURN
-A DOCKER-USER -s 127.0.0.0/8 -j RETURN
-A DOCKER-USER -s 10.0.0.0/8 -j RETURN
-A DOCKER-USER -s 172.16.0.0/12 -j RETURN
-A DOCKER-USER -s 192.168.0.0/16 -j RETURN
-A DOCKER-USER -s 100.64.0.0/10 -j RETURN
-A DOCKER-USER -p tcp --dport 80 -j RETURN
-A DOCKER-USER -p tcp --dport 443 -j RETURN
-A DOCKER-USER -m conntrack --ctstate NEW -j DROP
-A DOCKER-USER -j RETURN
COMMIT
IPv6 มี table แยกต่างหาก เพิ่ม policy ที่ตรงกันใน /etc/ufw/after6.rules หาก เปิดใช้ Docker IPv6 หลีกเลี่ยงการ hardcode ชื่อ interface เช่น eth0 ใน snippet ของ docs ชื่อ interface แตกต่างกันไปตาม image ของ VPS (ens3, enp* ฯลฯ) และการไม่ตรงกันอาจทำให้ ข้ามกฎ deny ของคุณโดยไม่ตั้งใจ การตรวจสอบอย่างรวดเร็วหลัง reload:
ufw reload
iptables -S DOCKER-USER
ip6tables -S DOCKER-USER
nmap -sT -p 1-65535 <public-ip> --open
พอร์ตภายนอกที่คาดหวังควรมีเฉพาะสิ่งที่คุณตั้งใจเปิดเผยเท่านั้น (สำหรับ setup ส่วนใหญ่: SSH + พอร์ต reverse proxy ของคุณ)

การค้นหา mDNS/Bonjour

เมื่อเปิดใช้ Plugin bonjour ที่ bundled มา Gateway จะประกาศตัวตนผ่าน mDNS (_openclaw-gw._tcp บนพอร์ต 5353) เพื่อการค้นหาอุปกรณ์ในเครื่อง ในโหมดเต็ม รูปแบบนี้รวม TXT record ที่อาจเปิดเผยรายละเอียดการดำเนินงาน:
  • cliPath: พาธระบบไฟล์แบบเต็มไปยังไบนารี CLI (เปิดเผยชื่อผู้ใช้และตำแหน่งติดตั้ง)
  • sshPort: ประกาศความพร้อมใช้งานของ SSH บนโฮสต์
  • displayName, lanHost: ข้อมูลชื่อโฮสต์
ข้อควรพิจารณาด้านความปลอดภัยในการปฏิบัติงาน: การกระจายรายละเอียดโครงสร้างพื้นฐานทำให้ใครก็ตามบนเครือข่ายภายในสอดแนมได้ง่ายขึ้น แม้แต่ข้อมูลที่ดู “ไม่มีอันตราย” เช่น พาธระบบไฟล์และความพร้อมใช้งานของ SSH ก็ช่วยให้ผู้โจมตีทำแผนที่สภาพแวดล้อมของคุณได้ คำแนะนำ:
  1. ปิดใช้ Bonjour ไว้ เว้นแต่จำเป็นต้องค้นพบบนอุปกรณ์ LAN Bonjour เริ่มอัตโนมัติบนโฮสต์ macOS และต้องเลือกใช้เองในที่อื่น URL ของ Gateway โดยตรง, Tailnet, SSH หรือ DNS-SD แบบ wide-area ช่วยหลีกเลี่ยงมัลติคาสต์ภายในเครื่องได้
  2. โหมด Minimal (ค่าเริ่มต้นเมื่อเปิดใช้ Bonjour และแนะนำสำหรับ Gateway ที่เปิดเผย): ละเว้นฟิลด์ละเอียดอ่อนจากการกระจายสัญญาณ mDNS:
    {
      discovery: {
        mdns: { mode: "minimal" },
      },
    }
    
  3. ปิดโหมด mDNS หากคุณต้องการเปิด Plugin ไว้แต่ระงับการค้นพบอุปกรณ์ภายในเครื่อง:
    {
      discovery: {
        mdns: { mode: "off" },
      },
    }
    
  4. โหมด Full (เลือกใช้เอง): รวม cliPath + sshPort ไว้ในระเบียน TXT:
    {
      discovery: {
        mdns: { mode: "full" },
      },
    }
    
  5. ตัวแปรสภาพแวดล้อม (ทางเลือก): ตั้งค่า OPENCLAW_DISABLE_BONJOUR=1 เพื่อปิดใช้ mDNS โดยไม่ต้องเปลี่ยนการกำหนดค่า
เมื่อเปิดใช้ Bonjour ในโหมด minimal, Gateway จะกระจายสัญญาณมากพอสำหรับการค้นพบอุปกรณ์ (role, gatewayPort, transport) แต่ละเว้น cliPath และ sshPort แอปที่ต้องใช้ข้อมูลพาธ CLI สามารถดึงข้อมูลนั้นผ่านการเชื่อมต่อ WebSocket ที่ผ่านการยืนยันตัวตนแทนได้

จำกัดการเข้าถึง Gateway WebSocket (การยืนยันตัวตนภายในเครื่อง)

การยืนยันตัวตนของ Gateway เป็นสิ่งที่ จำเป็นตามค่าเริ่มต้น หากไม่ได้กำหนดค่าพาธการยืนยันตัวตน Gateway ที่ถูกต้อง Gateway จะปฏิเสธการเชื่อมต่อ WebSocket (ปิดเมื่อผิดพลาด) การเริ่มต้นใช้งานจะสร้างโทเค็นตามค่าเริ่มต้น (แม้แต่สำหรับ loopback) ดังนั้น ไคลเอนต์ภายในเครื่องต้องยืนยันตัวตน ตั้งค่าโทเค็นเพื่อให้ไคลเอนต์ WS ทั้งหมด ต้องยืนยันตัวตน:
{
  gateway: {
    auth: { mode: "token", token: "your-token" },
  },
}
Doctor สามารถสร้างให้คุณได้: openclaw doctor --generate-gateway-token.
gateway.remote.token และ gateway.remote.password เป็นแหล่งข้อมูลรับรองของไคลเอนต์ พวกมัน ไม่ ปกป้องการเข้าถึง WS ภายในเครื่องด้วยตัวเอง เส้นทางการเรียกภายในเครื่องสามารถใช้ gateway.remote.* เป็น fallback ได้เฉพาะเมื่อไม่ได้ตั้งค่า gateway.auth.* หาก gateway.auth.token หรือ gateway.auth.password ถูกกำหนดค่าอย่างชัดเจนผ่าน SecretRef และแก้ค่าไม่ได้ การแก้ค่าจะล้มเหลวแบบ fail closed (ไม่มี remote fallback มาปิดบัง)
ทางเลือก: ปักหมุด TLS ระยะไกลด้วย gateway.remote.tlsFingerprint เมื่อใช้ wss://. โดยค่าเริ่มต้น Plaintext ws:// ใช้ได้เฉพาะ loopback เท่านั้น สำหรับพาธเครือข่ายส่วนตัวที่เชื่อถือได้ ให้ตั้งค่า OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1 บนโปรเซสไคลเอนต์ในฐานะ มาตรการ break-glass ค่านี้จงใจให้เป็นสภาพแวดล้อมของโปรเซสเท่านั้น ไม่ใช่คีย์กำหนดค่า openclaw.json การจับคู่อุปกรณ์มือถือและเส้นทาง Gateway ของ Android ที่ป้อนเองหรือสแกนเข้มงวดกว่า: ยอมรับ cleartext สำหรับ loopback แต่ private-LAN, link-local, .local และ ชื่อโฮสต์ที่ไม่มีจุดต้องใช้ TLS เว้นแต่คุณจะเลือกใช้พาธ cleartext ของเครือข่ายส่วนตัวที่เชื่อถือได้อย่างชัดเจน การจับคู่อุปกรณ์ภายในเครื่อง:
  • การจับคู่อุปกรณ์จะได้รับอนุมัติอัตโนมัติสำหรับการเชื่อมต่อ local loopback โดยตรงเพื่อให้ ไคลเอนต์บนโฮสต์เดียวกันลื่นไหล
  • OpenClaw ยังมีพาธ self-connect แบบ backend/container-local ที่จำกัดสำหรับ โฟลว์ตัวช่วย shared-secret ที่เชื่อถือได้
  • การเชื่อมต่อ Tailnet และ LAN รวมถึงการ bind tailnet บนโฮสต์เดียวกัน จะถูกปฏิบัติเป็น ระยะไกลสำหรับการจับคู่และยังต้องได้รับอนุมัติ
  • หลักฐาน forwarded-header บนคำขอ loopback ทำให้ locality แบบ loopback ไม่เข้าเงื่อนไข การอนุมัติอัตโนมัติสำหรับ metadata-upgrade ถูกจำกัดขอบเขตอย่างแคบ ดู การจับคู่ Gateway สำหรับกฎทั้งสองข้อ
โหมดการยืนยันตัวตน:
  • gateway.auth.mode: "token": bearer token ที่ใช้ร่วมกัน (แนะนำสำหรับการตั้งค่าส่วนใหญ่)
  • gateway.auth.mode: "password": การยืนยันตัวตนด้วยรหัสผ่าน (ควรตั้งค่าผ่าน env: OPENCLAW_GATEWAY_PASSWORD)
  • gateway.auth.mode: "trusted-proxy": เชื่อถือ reverse proxy ที่รับรู้ตัวตนเพื่อยืนยันตัวตนผู้ใช้และส่งตัวตนผ่าน headers (ดู การยืนยันตัวตนผ่าน Trusted Proxy)
รายการตรวจสอบการหมุนเวียน (โทเค็น/รหัสผ่าน):
  1. สร้าง/ตั้งค่า secret ใหม่ (gateway.auth.token หรือ OPENCLAW_GATEWAY_PASSWORD)
  2. รีสตาร์ท Gateway (หรือรีสตาร์ทแอป macOS หากแอปนั้นควบคุม Gateway)
  3. อัปเดตไคลเอนต์ระยะไกลใด ๆ (gateway.remote.token / .password บนเครื่องที่เรียกเข้า Gateway)
  4. ตรวจสอบว่าคุณไม่สามารถเชื่อมต่อด้วยข้อมูลรับรองเก่าได้อีกต่อไป

ส่วนหัวตัวตนของ Tailscale Serve

เมื่อ gateway.auth.allowTailscale เป็น true (ค่าเริ่มต้นสำหรับ Serve), OpenClaw จะยอมรับส่วนหัวตัวตนของ Tailscale Serve (tailscale-user-login) สำหรับการยืนยันตัวตน UI/WebSocket ควบคุม OpenClaw ตรวจสอบตัวตนโดยแก้ที่อยู่ x-forwarded-for ผ่าน daemon ของ Tailscale ภายในเครื่อง (tailscale whois) และจับคู่กับส่วนหัว เงื่อนไขนี้จะทำงานเฉพาะคำขอที่เข้ามาทาง loopback และมี x-forwarded-for, x-forwarded-proto และ x-forwarded-host ตามที่ Tailscale แทรกเข้ามา สำหรับพาธตรวจสอบตัวตนแบบ async นี้ ความพยายามที่ล้มเหลวสำหรับ {scope, ip} เดียวกัน จะถูกจัดลำดับก่อนที่ limiter จะบันทึกความล้มเหลว ดังนั้นการลองซ้ำที่ไม่ถูกต้องพร้อมกัน จากไคลเอนต์ Serve หนึ่งตัวจึงอาจล็อกความพยายามครั้งที่สองทันที แทนที่จะแข่งกันผ่านไปเป็นการไม่ตรงกันธรรมดาสองครั้ง HTTP API endpoints (เช่น /v1/*, /tools/invoke และ /api/channels/*) ไม่ ใช้การยืนยันตัวตนผ่านส่วนหัวตัวตนของ Tailscale พวกมันยังคงทำตาม โหมดการยืนยันตัวตน HTTP ที่กำหนดไว้ของ Gateway หมายเหตุสำคัญเรื่องขอบเขต:
  • การยืนยันตัวตน HTTP bearer ของ Gateway มีผลเทียบเท่าการเข้าถึงของ operator แบบทั้งหมดหรือไม่มีเลย
  • ปฏิบัติต่อข้อมูลรับรองที่สามารถเรียก /v1/chat/completions, /v1/responses หรือ /api/channels/* เป็น secret ของ operator ที่มีสิทธิ์เต็มสำหรับ Gateway นั้น
  • บนพื้นผิว HTTP ที่เข้ากันได้กับ OpenAI, การยืนยันตัวตน bearer แบบ shared-secret จะคืนค่า scope ของ operator เริ่มต้นเต็มชุด (operator.admin, operator.approvals, operator.pairing, operator.read, operator.talk.secrets, operator.write) และความหมายของ owner สำหรับ agent turns; ค่า x-openclaw-scopes ที่แคบกว่าจะไม่ลดสิทธิ์ของพาธ shared-secret นั้น
  • ความหมายของ scope ต่อคำขอบน HTTP ใช้เฉพาะเมื่อคำขอมาจากโหมดที่มีตัวตน เช่น trusted proxy auth หรือ gateway.auth.mode="none" บน private ingress
  • ในโหมดที่มีตัวตนเหล่านั้น การละเว้น x-openclaw-scopes จะ fallback ไปยังชุด scope เริ่มต้นปกติของ operator; ส่งส่วนหัวนี้อย่างชัดเจนเมื่อคุณต้องการชุด scope ที่แคบกว่า
  • /tools/invoke ทำตามกฎ shared-secret เดียวกัน: การยืนยันตัวตน bearer ด้วยโทเค็น/รหัสผ่านถูกปฏิบัติเป็นการเข้าถึง operator เต็มรูปแบบที่นั่นด้วย ขณะที่โหมดที่มีตัวตนยังคงเคารพ scope ที่ประกาศ
  • อย่าแชร์ข้อมูลรับรองเหล่านี้กับผู้เรียกที่ไม่น่าเชื่อถือ; ควรใช้ Gateway แยกกันต่อขอบเขตความเชื่อถือ
สมมติฐานด้านความเชื่อถือ: การยืนยันตัวตน Serve แบบไม่มีโทเค็นถือว่าโฮสต์ Gateway เชื่อถือได้ อย่าปฏิบัติต่อสิ่งนี้เป็นการป้องกันโปรเซสบนโฮสต์เดียวกันที่เป็นอันตราย หากโค้ดภายในเครื่อง ที่ไม่น่าเชื่อถืออาจรันบนโฮสต์ Gateway ให้ปิดใช้ gateway.auth.allowTailscale และบังคับใช้การยืนยันตัวตนแบบ shared-secret อย่างชัดเจนด้วย gateway.auth.mode: "token" หรือ "password" กฎด้านความปลอดภัย: อย่าส่งต่อส่วนหัวเหล่านี้จาก reverse proxy ของคุณเอง หาก คุณ terminate TLS หรือ proxy ด้านหน้า Gateway ให้ปิดใช้ gateway.auth.allowTailscale และใช้การยืนยันตัวตนแบบ shared-secret (gateway.auth.mode: "token" หรือ "password") หรือ การยืนยันตัวตนผ่าน Trusted Proxy แทน Trusted proxies:
  • หากคุณ terminate TLS ด้านหน้า Gateway ให้ตั้งค่า gateway.trustedProxies เป็น IP ของ proxy ของคุณ
  • OpenClaw จะเชื่อถือ x-forwarded-for (หรือ x-real-ip) จาก IP เหล่านั้นเพื่อระบุ IP ไคลเอนต์สำหรับการตรวจสอบการจับคู่ภายในเครื่องและการตรวจสอบการยืนยันตัวตน HTTP/ภายในเครื่อง
  • ตรวจสอบให้แน่ใจว่า proxy ของคุณ เขียนทับ x-forwarded-for และบล็อกการเข้าถึงพอร์ต Gateway โดยตรง
ดู Tailscale และ ภาพรวมเว็บ

การควบคุมเบราว์เซอร์ผ่านโฮสต์ Node (แนะนำ)

หาก Gateway ของคุณอยู่ระยะไกลแต่เบราว์เซอร์รันอยู่บนอีกเครื่อง ให้รัน โฮสต์ Node บนเครื่องเบราว์เซอร์และให้ Gateway proxy การกระทำของเบราว์เซอร์ (ดู เครื่องมือเบราว์เซอร์) ปฏิบัติต่อการจับคู่ Node เหมือนการเข้าถึงผู้ดูแลระบบ รูปแบบที่แนะนำ:
  • ให้ Gateway และโฮสต์ Node อยู่บน tailnet เดียวกัน (Tailscale)
  • จับคู่ Node อย่างตั้งใจ; ปิดใช้การกำหนดเส้นทาง proxy ของเบราว์เซอร์หากคุณไม่ต้องการใช้
หลีกเลี่ยง:
  • การเปิดเผยพอร์ต relay/control ผ่าน LAN หรืออินเทอร์เน็ตสาธารณะ
  • Tailscale Funnel สำหรับ endpoint ควบคุมเบราว์เซอร์ (การเปิดเผยต่อสาธารณะ)

Secrets บนดิสก์

ให้ถือว่าทุกอย่างภายใต้ ~/.openclaw/ (หรือ $OPENCLAW_STATE_DIR/) อาจมี secrets หรือข้อมูลส่วนตัว:
  • openclaw.json: การกำหนดค่าอาจมีโทเค็น (Gateway, Gateway ระยะไกล), การตั้งค่า provider และ allowlists
  • credentials/**: ข้อมูลรับรองของช่องทาง (ตัวอย่าง: ข้อมูลรับรอง WhatsApp), pairing allowlists, การนำเข้า OAuth แบบเก่า
  • agents/<agentId>/agent/auth-profiles.json: API keys, โปรไฟล์โทเค็น, โทเค็น OAuth และ keyRef/tokenRef แบบทางเลือก
  • agents/<agentId>/agent/codex-home/**: บัญชี app-server ของ Codex ต่อ agent, การกำหนดค่า, skills, plugins, สถานะ native thread และ diagnostics
  • secrets.json (ทางเลือก): payload secret ที่ backed by file ซึ่งใช้โดย provider SecretRef แบบ file (secrets.providers)
  • agents/<agentId>/agent/auth.json: ไฟล์ความเข้ากันได้แบบเก่า รายการ api_key แบบ static จะถูก scrub เมื่อค้นพบ
  • agents/<agentId>/sessions/**: transcript ของ session (*.jsonl) + metadata การกำหนดเส้นทาง (sessions.json) ที่อาจมีข้อความส่วนตัวและผลลัพธ์ของเครื่องมือ
  • แพ็กเกจ Plugin ที่ bundled: plugins ที่ติดตั้งแล้ว (รวมถึง node_modules/ ของพวกมัน)
  • sandboxes/**: workspace sandbox ของเครื่องมือ; อาจสะสมสำเนาไฟล์ที่คุณอ่าน/เขียนภายใน sandbox
เคล็ดลับการทำให้ปลอดภัยขึ้น:
  • จำกัด permissions ให้แน่น (700 สำหรับ dirs, 600 สำหรับ files)
  • ใช้การเข้ารหัสดิสก์ทั้งลูกบนโฮสต์ Gateway
  • ควรใช้บัญชีผู้ใช้ OS เฉพาะสำหรับ Gateway หากโฮสต์ถูกใช้งานร่วมกัน

ไฟล์ .env ของ Workspace

OpenClaw โหลดไฟล์ .env ภายใน workspace สำหรับ agents และเครื่องมือ แต่ไม่ยอมให้ไฟล์เหล่านั้น override การควบคุม runtime ของ Gateway อย่างเงียบ ๆ
  • คีย์ใดก็ตามที่ขึ้นต้นด้วย OPENCLAW_* จะถูกบล็อกจากไฟล์ .env ของ workspace ที่ไม่น่าเชื่อถือ
  • การตั้งค่า endpoint ของช่องทางสำหรับ Matrix, Mattermost, IRC และ Synology Chat ก็ถูกบล็อกจากการ override ผ่าน .env ของ workspace ด้วย ดังนั้น workspace ที่ clone มาไม่สามารถเปลี่ยนเส้นทาง traffic ของ connector ที่ bundled ผ่านการกำหนดค่า endpoint ภายในเครื่องได้ คีย์ env ของ endpoint (เช่น MATRIX_HOMESERVER, MATTERMOST_URL, IRC_HOST, SYNOLOGY_CHAT_INCOMING_URL) ต้องมาจากสภาพแวดล้อมของโปรเซส Gateway หรือ env.shellEnv ไม่ใช่จาก .env ที่โหลดจาก workspace
  • การบล็อกเป็นแบบ fail-closed: ตัวแปรควบคุม runtime ใหม่ที่เพิ่มใน release อนาคตไม่สามารถสืบทอดมาจาก .env ที่ check-in หรือผู้โจมตีจัดหาให้ได้; คีย์จะถูกละเว้นและ Gateway จะคงค่าของตัวเองไว้
  • ตัวแปรสภาพแวดล้อมของโปรเซส/OS ที่เชื่อถือได้ (shell ของ Gateway เอง, launchd/systemd unit, app bundle) ยังมีผล - สิ่งนี้จำกัดเฉพาะการโหลดไฟล์ .env
เหตุผล: ไฟล์ .env ของ workspace มักอยู่ถัดจากโค้ด agent, ถูก commit โดยไม่ตั้งใจ หรือถูกเขียนโดยเครื่องมือ การบล็อก prefix OPENCLAW_* ทั้งหมดหมายความว่าการเพิ่ม flag OPENCLAW_* ใหม่ในภายหลังจะไม่มีทางถอยกลับไปเป็นการสืบทอดจากสถานะ workspace อย่างเงียบ ๆ ได้

Logs และ transcripts (การปกปิดและการเก็บรักษา)

Logs และ transcripts อาจรั่วไหลข้อมูลละเอียดอ่อนได้แม้เมื่อการควบคุมการเข้าถึงถูกต้อง:
  • Logs ของ Gateway อาจมีสรุปเครื่องมือ, ข้อผิดพลาด และ URL
  • Transcripts ของ session อาจมี secrets ที่วางไว้, เนื้อหาไฟล์, ผลลัพธ์คำสั่ง และลิงก์
คำแนะนำ:
  • เปิดการปกปิด logs และ transcripts ไว้ (logging.redactSensitive: "tools"; ค่าเริ่มต้น)
  • เพิ่มรูปแบบแบบกำหนดเองสำหรับสภาพแวดล้อมของคุณผ่าน logging.redactPatterns (โทเค็น, ชื่อโฮสต์, URL ภายใน)
  • เมื่อแชร์ diagnostics ควรใช้ openclaw status --all (วางได้, ปกปิด secrets แล้ว) แทน logs ดิบ
  • ลบ transcripts ของ session และไฟล์ log เก่าหากคุณไม่จำเป็นต้องเก็บไว้นาน
รายละเอียด: Logging

DM: จับคู่ตามค่าเริ่มต้น

{
  channels: { whatsapp: { dmPolicy: "pairing" } },
}

Groups: บังคับให้ mention ทุกที่

{
  "channels": {
    "whatsapp": {
      "groups": {
        "*": { "requireMention": true }
      }
    }
  },
  "agents": {
    "list": [
      {
        "id": "main",
        "groupChat": { "mentionPatterns": ["@openclaw", "@mybot"] }
      }
    ]
  }
}
ในแชตกลุ่ม ให้ตอบกลับเฉพาะเมื่อถูกกล่าวถึงอย่างชัดเจนเท่านั้น

แยกหมายเลขโทรศัพท์ (WhatsApp, Signal, Telegram)

สำหรับช่องทางที่อิงหมายเลขโทรศัพท์ ให้พิจารณารัน AI ของคุณบนหมายเลขโทรศัพท์ที่แยกจากหมายเลขส่วนตัว:
  • หมายเลขส่วนตัว: บทสนทนาของคุณยังคงเป็นส่วนตัว
  • หมายเลขบอต: AI จัดการรายการเหล่านี้ โดยมีขอบเขตที่เหมาะสม

โหมดอ่านอย่างเดียว (ผ่าน sandbox และเครื่องมือ)

คุณสามารถสร้างโปรไฟล์แบบอ่านอย่างเดียวได้โดยรวมสิ่งต่อไปนี้:
  • agents.defaults.sandbox.workspaceAccess: "ro" (หรือ "none" สำหรับไม่มีสิทธิ์เข้าถึง workspace)
  • รายการอนุญาต/ปฏิเสธเครื่องมือที่บล็อก write, edit, apply_patch, exec, process ฯลฯ
ตัวเลือกการเสริมความแข็งแกร่งเพิ่มเติม:
  • tools.exec.applyPatch.workspaceOnly: true (ค่าเริ่มต้น): ทำให้แน่ใจว่า apply_patch ไม่สามารถเขียน/ลบภายนอกไดเรกทอรี workspace แม้เมื่อปิด sandboxing อยู่ ตั้งเป็น false เฉพาะเมื่อคุณตั้งใจให้ apply_patch แตะไฟล์ภายนอก workspace เท่านั้น
  • tools.fs.workspaceOnly: true (ไม่บังคับ): จำกัดพาธ read/write/edit/apply_patch และพาธโหลดรูปภาพ prompt อัตโนมัติแบบ native ให้อยู่ในไดเรกทอรี workspace (มีประโยชน์หากวันนี้คุณอนุญาตพาธแบบ absolute และต้องการแนวป้องกันเดียว)
  • จำกัดราก filesystem ให้แคบ: หลีกเลี่ยงรากที่กว้าง เช่น ไดเรกทอรี home ของคุณ สำหรับ workspace/sandbox workspace ของเอเจนต์ รากที่กว้างอาจเปิดเผยไฟล์ภายในเครื่องที่ละเอียดอ่อน (เช่น state/config ใต้ ~/.openclaw) ให้กับเครื่องมือ filesystem

ค่าพื้นฐานที่ปลอดภัย (คัดลอก/วาง)

คอนฟิก “ค่าเริ่มต้นที่ปลอดภัย” หนึ่งชุดที่ทำให้ Gateway เป็นส่วนตัว ต้องจับคู่ DM และหลีกเลี่ยงบอตกลุ่มที่เปิดตลอดเวลา:
{
  gateway: {
    mode: "local",
    bind: "loopback",
    port: 18789,
    auth: { mode: "token", token: "your-long-random-token" },
  },
  channels: {
    whatsapp: {
      dmPolicy: "pairing",
      groups: { "*": { requireMention: true } },
    },
  },
}
หากคุณต้องการให้การเรียกใช้เครื่องมือ “ปลอดภัยขึ้นโดยค่าเริ่มต้น” ด้วย ให้เพิ่ม sandbox + ปฏิเสธเครื่องมืออันตรายสำหรับเอเจนต์ที่ไม่ใช่เจ้าของ (ตัวอย่างด้านล่างใน “โปรไฟล์การเข้าถึงต่อเอเจนต์”) ค่าพื้นฐานในตัวสำหรับรอบเอเจนต์ที่ขับเคลื่อนด้วยแชต: ผู้ส่งที่ไม่ใช่เจ้าของไม่สามารถใช้เครื่องมือ cron หรือ gateway

Sandboxing (แนะนำ)

เอกสารเฉพาะ: Sandboxing มีสองแนวทางที่เสริมกัน:
  • รัน Gateway ทั้งหมดใน Docker (ขอบเขตคอนเทนเนอร์): Docker
  • Tool sandbox (agents.defaults.sandbox, gateway โฮสต์ + เครื่องมือที่แยกด้วย sandbox; Docker เป็น backend เริ่มต้น): Sandboxing
เพื่อป้องกันการเข้าถึงข้ามเอเจนต์ ให้คง agents.defaults.sandbox.scope เป็น "agent" (ค่าเริ่มต้น) หรือ "session" สำหรับการแยกต่อเซสชันที่เข้มงวดยิ่งขึ้น scope: "shared" ใช้คอนเทนเนอร์หรือ workspace เดียว
ให้พิจารณาการเข้าถึง workspace ของเอเจนต์ภายใน sandbox ด้วย:
  • agents.defaults.sandbox.workspaceAccess: "none" (ค่าเริ่มต้น) ทำให้ workspace ของเอเจนต์เป็นพื้นที่ห้ามเข้าถึง; เครื่องมือจะรันกับ sandbox workspace ใต้ ~/.openclaw/sandboxes
  • agents.defaults.sandbox.workspaceAccess: "ro" เมานต์ workspace ของเอเจนต์แบบอ่านอย่างเดียวที่ /agent (ปิดใช้ write/edit/apply_patch)
  • agents.defaults.sandbox.workspaceAccess: "rw" เมานต์ workspace ของเอเจนต์แบบอ่าน/เขียนที่ /workspace
  • sandbox.docker.binds เพิ่มเติมจะถูกตรวจสอบกับพาธต้นทางที่ normalize และ canonicalize แล้ว เทคนิค parent-symlink และ alias ของ home แบบ canonical จะยังคงปิดอย่างปลอดภัยหาก resolve เข้าไปในรากที่ถูกบล็อก เช่น /etc, /var/run หรือไดเรกทอรีข้อมูลรับรองใต้ home ของ OS
tools.elevated คือช่องทางหลบออกจากค่าพื้นฐานส่วนกลางที่รัน exec ภายนอก sandbox โฮสต์ที่มีผลคือ gateway โดยค่าเริ่มต้น หรือ node เมื่อกำหนดเป้าหมาย exec เป็น node จำกัด tools.elevated.allowFrom ให้แน่น และอย่าเปิดใช้ให้คนแปลกหน้า คุณสามารถจำกัด elevated ต่อเอเจนต์เพิ่มเติมได้ผ่าน agents.list[].tools.elevated ดู โหมดยกระดับสิทธิ์

แนวป้องกันการมอบหมายให้ sub-agent

หากคุณอนุญาตเครื่องมือเซสชัน ให้ถือว่าการรัน sub-agent ที่ถูกมอบหมายเป็นการตัดสินใจเรื่องขอบเขตอีกชั้นหนึ่ง:
  • ปฏิเสธ sessions_spawn เว้นแต่ว่าเอเจนต์จำเป็นต้องมอบหมายงานจริง ๆ
  • จำกัด agents.defaults.subagents.allowAgents และ override ต่อเอเจนต์ใด ๆ ของ agents.list[].subagents.allowAgents ให้อยู่กับเอเจนต์เป้าหมายที่ทราบว่าปลอดภัย
  • สำหรับ workflow ใด ๆ ที่ต้องคงอยู่ใน sandbox ให้เรียก sessions_spawn พร้อม sandbox: "require" (ค่าเริ่มต้นคือ inherit)
  • sandbox: "require" จะล้มเหลวอย่างรวดเร็วเมื่อ runtime ลูกเป้าหมายไม่ได้อยู่ใน sandbox

ความเสี่ยงของการควบคุมเบราว์เซอร์

การเปิดใช้การควบคุมเบราว์เซอร์ทำให้โมเดลสามารถควบคุมเบราว์เซอร์จริงได้ หากโปรไฟล์เบราว์เซอร์นั้นมีเซสชันที่ล็อกอินอยู่แล้ว โมเดลจะสามารถ เข้าถึงบัญชีและข้อมูลเหล่านั้นได้ ถือว่าโปรไฟล์เบราว์เซอร์เป็น สถานะที่ละเอียดอ่อน:
  • ควรใช้โปรไฟล์เฉพาะสำหรับเอเจนต์ (โปรไฟล์เริ่มต้น openclaw)
  • หลีกเลี่ยงการชี้เอเจนต์ไปยังโปรไฟล์ส่วนตัวที่คุณใช้ประจำวัน
  • ปิดการควบคุมเบราว์เซอร์บนโฮสต์สำหรับเอเจนต์ที่อยู่ใน sandbox เว้นแต่ว่าคุณไว้วางใจพวกเขา
  • API ควบคุมเบราว์เซอร์แบบ loopback แบบสแตนด์อโลนยอมรับเฉพาะ shared-secret auth (gateway token bearer auth หรือ gateway password) เท่านั้น ไม่ใช้ trusted-proxy หรือ header identity ของ Tailscale Serve
  • ถือว่าการดาวน์โหลดจากเบราว์เซอร์เป็นอินพุตที่ไม่น่าเชื่อถือ; ควรใช้ไดเรกทอรีดาวน์โหลดที่แยกต่างหาก
  • ปิด browser sync/password manager ในโปรไฟล์เอเจนต์ถ้าเป็นไปได้ (ลดขอบเขตผลกระทบ)
  • สำหรับ gateway ระยะไกล ให้ถือว่า “การควบคุมเบราว์เซอร์” เทียบเท่ากับ “การเข้าถึงของผู้ปฏิบัติการ” ต่อสิ่งใดก็ตามที่โปรไฟล์นั้นเข้าถึงได้
  • ให้ Gateway และโฮสต์ node อยู่เฉพาะใน tailnet; หลีกเลี่ยงการเปิดพอร์ตควบคุมเบราว์เซอร์ให้ LAN หรืออินเทอร์เน็ตสาธารณะ
  • ปิด browser proxy routing เมื่อคุณไม่ต้องการใช้ (gateway.nodes.browser.mode="off")
  • โหมด existing-session ของ Chrome MCP ไม่ได้ “ปลอดภัยกว่า”; มันสามารถกระทำแทนคุณในทุกสิ่งที่โปรไฟล์ Chrome บนโฮสต์นั้นเข้าถึงได้

นโยบาย SSRF ของเบราว์เซอร์ (เข้มงวดโดยค่าเริ่มต้น)

นโยบายการนำทางเบราว์เซอร์ของ OpenClaw เข้มงวดโดยค่าเริ่มต้น: ปลายทาง private/internal จะยังถูกบล็อก เว้นแต่ว่าคุณ opt in อย่างชัดเจน
  • ค่าเริ่มต้น: ไม่ได้ตั้ง browser.ssrfPolicy.dangerouslyAllowPrivateNetwork ดังนั้นการนำทางเบราว์เซอร์จะยังบล็อกปลายทาง private/internal/special-use
  • alias เดิม: browser.ssrfPolicy.allowPrivateNetwork ยังยอมรับเพื่อความเข้ากันได้
  • โหมด opt-in: ตั้ง browser.ssrfPolicy.dangerouslyAllowPrivateNetwork: true เพื่ออนุญาตปลายทาง private/internal/special-use
  • ในโหมดเข้มงวด ให้ใช้ hostnameAllowlist (pattern เช่น *.example.com) และ allowedHostnames (ข้อยกเว้น host แบบ exact รวมถึงชื่อที่ถูกบล็อก เช่น localhost) สำหรับข้อยกเว้นที่ชัดเจน
  • การนำทางจะถูกตรวจสอบก่อนคำขอ และจะพยายามตรวจสอบซ้ำแบบ best-effort บน URL http(s) สุดท้ายหลังการนำทาง เพื่อลด pivot ที่อิง redirect
ตัวอย่างนโยบายเข้มงวด:
{
  browser: {
    ssrfPolicy: {
      dangerouslyAllowPrivateNetwork: false,
      hostnameAllowlist: ["*.example.com", "example.com"],
      allowedHostnames: ["localhost"],
    },
  },
}

โปรไฟล์การเข้าถึงต่อเอเจนต์ (multi-agent)

ด้วยการกำหนดเส้นทางแบบ multi-agent เอเจนต์แต่ละตัวสามารถมี sandbox + นโยบายเครื่องมือของตัวเอง: ใช้สิ่งนี้เพื่อให้ สิทธิ์เข้าถึงเต็มรูปแบบ, อ่านอย่างเดียว หรือ ไม่มีสิทธิ์เข้าถึง ต่อเอเจนต์ ดู Sandbox และเครื่องมือแบบหลายเอเจนต์ สำหรับรายละเอียดทั้งหมด และกฎลำดับความสำคัญ กรณีใช้งานทั่วไป:
  • เอเจนต์ส่วนตัว: สิทธิ์เข้าถึงเต็มรูปแบบ ไม่มี sandbox
  • เอเจนต์ครอบครัว/งาน: อยู่ใน sandbox + เครื่องมืออ่านอย่างเดียว
  • เอเจนต์สาธารณะ: อยู่ใน sandbox + ไม่มีเครื่องมือ filesystem/shell

ตัวอย่าง: สิทธิ์เข้าถึงเต็มรูปแบบ (ไม่มี sandbox)

{
  agents: {
    list: [
      {
        id: "personal",
        workspace: "~/.openclaw/workspace-personal",
        sandbox: { mode: "off" },
      },
    ],
  },
}

ตัวอย่าง: เครื่องมืออ่านอย่างเดียว + workspace อ่านอย่างเดียว

{
  agents: {
    list: [
      {
        id: "family",
        workspace: "~/.openclaw/workspace-family",
        sandbox: {
          mode: "all",
          scope: "agent",
          workspaceAccess: "ro",
        },
        tools: {
          allow: ["read"],
          deny: ["write", "edit", "apply_patch", "exec", "process", "browser"],
        },
      },
    ],
  },
}

ตัวอย่าง: ไม่มีสิทธิ์เข้าถึง filesystem/shell (อนุญาตการรับส่งข้อความของ provider)

{
  agents: {
    list: [
      {
        id: "public",
        workspace: "~/.openclaw/workspace-public",
        sandbox: {
          mode: "all",
          scope: "agent",
          workspaceAccess: "none",
        },
        // Session tools can reveal sensitive data from transcripts. By default OpenClaw limits these tools
        // to the current session + spawned subagent sessions, but you can clamp further if needed.
        // See `tools.sessions.visibility` in the configuration reference.
        tools: {
          sessions: { visibility: "tree" }, // self | tree | agent | all
          allow: [
            "sessions_list",
            "sessions_history",
            "sessions_send",
            "sessions_spawn",
            "session_status",
            "whatsapp",
            "telegram",
            "slack",
            "discord",
          ],
          deny: [
            "read",
            "write",
            "edit",
            "apply_patch",
            "exec",
            "process",
            "browser",
            "canvas",
            "nodes",
            "cron",
            "gateway",
            "image",
          ],
        },
      },
    ],
  },
}

การตอบสนองต่อเหตุการณ์

หาก AI ของคุณทำสิ่งที่ไม่ดี:

จำกัดผลกระทบ

  1. หยุดมัน: หยุดแอป macOS (หากแอปนั้นดูแล Gateway) หรือจบ process openclaw gateway ของคุณ
  2. ปิดการเปิดเผย: ตั้ง gateway.bind: "loopback" (หรือปิดใช้ Tailscale Funnel/Serve) จนกว่าคุณจะเข้าใจว่าเกิดอะไรขึ้น
  3. ระงับการเข้าถึง: เปลี่ยน DM/กลุ่มที่เสี่ยงเป็น dmPolicy: "disabled" / ต้องกล่าวถึง และลบ entry อนุญาตทั้งหมด "*" หากคุณมีอยู่

หมุนเวียนข้อมูลลับ (ถือว่าถูก compromise หาก secret รั่วไหล)

  1. หมุนเวียน Gateway auth (gateway.auth.token / OPENCLAW_GATEWAY_PASSWORD) และ restart
  2. หมุนเวียน secret ของ remote client (gateway.remote.token / .password) บนเครื่องใด ๆ ที่สามารถเรียก Gateway ได้
  3. หมุนเวียนข้อมูลรับรอง provider/API (ข้อมูลรับรอง WhatsApp, token ของ Slack/Discord, คีย์ model/API ใน auth-profiles.json และค่า payload ของ secret ที่เข้ารหัสเมื่อใช้งาน)

ตรวจสอบ

  1. ตรวจสอบ log ของ Gateway: /tmp/openclaw/openclaw-YYYY-MM-DD.log (หรือ logging.file)
  2. ตรวจทาน transcript ที่เกี่ยวข้อง: ~/.openclaw/agents/<agentId>/sessions/*.jsonl
  3. ตรวจทานการเปลี่ยนแปลงคอนฟิกล่าสุด (สิ่งใดก็ตามที่อาจขยายสิทธิ์เข้าถึง: gateway.bind, gateway.auth, นโยบาย dm/group, tools.elevated, การเปลี่ยนแปลง Plugin)
  4. รัน openclaw security audit --deep อีกครั้งและยืนยันว่า findings ระดับวิกฤตได้รับการแก้ไขแล้ว

รวบรวมสำหรับรายงาน

  • Timestamp, OS ของโฮสต์ gateway + เวอร์ชัน OpenClaw
  • Transcript ของเซสชัน + log tail สั้น ๆ (หลัง redact)
  • สิ่งที่ผู้โจมตีส่ง + สิ่งที่เอเจนต์ทำ
  • Gateway ถูกเปิดเผยเกิน loopback หรือไม่ (LAN/Tailscale Funnel/Serve)

การสแกน secret

CI รัน hook pre-commit detect-private-key ครอบคลุม repository หากล้มเหลว ให้ลบหรือหมุนเวียน key material ที่ commit แล้ว จากนั้น reproduce ในเครื่อง:
pre-commit run --all-files detect-private-key

การรายงานปัญหาความปลอดภัย

พบช่องโหว่ใน OpenClaw? โปรดรายงานอย่างรับผิดชอบ:
  1. อีเมล: security@openclaw.ai
  2. อย่าโพสต์ต่อสาธารณะจนกว่าจะแก้ไขแล้ว
  3. เราจะให้เครดิตคุณ (เว้นแต่ว่าคุณต้องการไม่เปิดเผยตัวตน)