---
read_when:
    - การกำหนดค่า safe bins หรือโปรไฟล์ safe-bin แบบกำหนดเอง
    - การส่งต่อการอนุมัติไปยัง Slack/Discord/Telegram หรือช่องทางแชตอื่นๆ
    - การสร้างไคลเอนต์การอนุมัติแบบเนทีฟสำหรับช่องทาง
summary: 'การอนุมัติ exec ขั้นสูง: ไบนารีที่ปลอดภัย, การผูกตัวแปลคำสั่ง, การส่งต่อการอนุมัติ, การส่งมอบแบบเนทีฟ'
title: การอนุมัติการดำเนินการ — ขั้นสูง
x-i18n:
    generated_at: "2026-06-27T18:27:09Z"
    model: gpt-5.5
    postprocess_version: locale-links-v1
    provider: openai
    source_hash: 3d936e1a1567d204981eec7c3262cf11f2af8fc1ed6213182954c2324718a270
    source_path: tools/exec-approvals-advanced.md
    workflow: 16
---

หัวข้อขั้นสูงของการอนุมัติ exec: fast-path ของ `safeBins`, การผูกกับอินเทอร์พรีเตอร์/รันไทม์
และการส่งต่อการอนุมัติไปยังช่องแชท (รวมถึงการส่งแบบเนทีฟ)
สำหรับนโยบายหลักและโฟลว์การอนุมัติ โปรดดู [การอนุมัติ Exec](/th/tools/exec-approvals)

## ไบนารีที่ปลอดภัย (stdin เท่านั้น)

`tools.exec.safeBins` กำหนดรายการขนาดเล็กของไบนารี **stdin เท่านั้น** (เช่น
`cut`) ที่สามารถทำงานในโหมด allowlist ได้ **โดยไม่ต้องมี** รายการ allowlist
ที่ระบุชัดเจน ไบนารีที่ปลอดภัยจะปฏิเสธอาร์กิวเมนต์ไฟล์แบบตำแหน่งและโทเค็นที่มีลักษณะเป็นพาธ ดังนั้นจึง
ทำงานได้เฉพาะกับสตรีมขาเข้าเท่านั้น ให้ถือว่านี่เป็น fast-path แบบแคบสำหรับ
ตัวกรองสตรีม ไม่ใช่รายการความเชื่อถือทั่วไป

<Warning>
**อย่า** เพิ่มไบนารีอินเทอร์พรีเตอร์หรือรันไทม์ (เช่น `python3`, `node`,
`ruby`, `bash`, `sh`, `zsh`) ลงใน `safeBins` หากคำสั่งสามารถประเมินโค้ด
เรียกใช้คำสั่งย่อย หรืออ่านไฟล์ได้โดยการออกแบบ ให้ใช้รายการ allowlist ที่ระบุชัดเจนแทน
และเปิดใช้พรอมป์การอนุมัติไว้ ไบนารีที่ปลอดภัยแบบกำหนดเองต้องกำหนดโปรไฟล์ที่ชัดเจน
ใน `tools.exec.safeBinProfiles.<bin>`
</Warning>

ไบนารีที่ปลอดภัยตามค่าเริ่มต้น:

[//]: # "SAFE_BIN_DEFAULTS:START"

`cut`, `uniq`, `head`, `tail`, `tr`, `wc`

[//]: # "SAFE_BIN_DEFAULTS:END"

`grep` และ `sort` ไม่ได้อยู่ในรายการค่าเริ่มต้น หากคุณเลือกใช้ ให้คงรายการ
allowlist ที่ชัดเจนไว้สำหรับเวิร์กโฟลว์ที่ไม่ใช่ stdin ของคำสั่งเหล่านั้น สำหรับ `grep` ในโหมด safe-bin
ให้ระบุแพตเทิร์นด้วย `-e`/`--regexp`; รูปแบบแพตเทิร์นแบบตำแหน่งจะถูกปฏิเสธ
เพื่อไม่ให้โอเปอแรนด์ไฟล์ถูกลักลอบส่งผ่านเป็นอาร์กิวเมนต์ตำแหน่งที่กำกวมได้

### การตรวจสอบ argv และแฟล็กที่ถูกปฏิเสธ

การตรวจสอบเป็นแบบกำหนดแน่นอนจากรูปทรงของ argv เท่านั้น (ไม่มีการตรวจสอบว่าไฟล์มีอยู่จริงบนระบบโฮสต์)
ซึ่งป้องกันพฤติกรรม oracle การมีอยู่ของไฟล์จากความแตกต่างระหว่าง allow/deny
อ็อปชันที่มุ่งกับไฟล์จะถูกปฏิเสธสำหรับไบนารีที่ปลอดภัยตามค่าเริ่มต้น; อ็อปชันแบบยาว
จะถูกตรวจสอบแบบ fail-closed (แฟล็กที่ไม่รู้จักและตัวย่อที่กำกวมจะถูก
ปฏิเสธ)

แฟล็กที่ถูกปฏิเสธตามโปรไฟล์ safe-bin:

[//]: # "SAFE_BIN_DENIED_FLAGS:START"

- `grep`: `--dereference-recursive`, `--directories`, `--exclude-from`, `--file`, `--recursive`, `-R`, `-d`, `-f`, `-r`
- `jq`: `--argfile`, `--from-file`, `--library-path`, `--rawfile`, `--slurpfile`, `-L`, `-f`
- `sort`: `--compress-program`, `--files0-from`, `--output`, `--random-source`, `--temporary-directory`, `-T`, `-o`
- `wc`: `--files0-from`

[//]: # "SAFE_BIN_DENIED_FLAGS:END"

ไบนารีที่ปลอดภัยยังบังคับให้โทเค็น argv ถูกปฏิบัติเป็น **ข้อความตามตัวอักษร** ขณะดำเนินการ
(ไม่มี globbing และไม่มีการขยาย `$VARS`) สำหรับเซกเมนต์แบบ stdin เท่านั้น ดังนั้นแพตเทิร์น
เช่น `*` หรือ `$HOME/...` จึงไม่สามารถใช้ลักลอบอ่านไฟล์ได้

### ไดเรกทอรีไบนารีที่เชื่อถือได้

ไบนารีที่ปลอดภัยต้อง resolve จากไดเรกทอรีไบนารีที่เชื่อถือได้ (ค่าเริ่มต้นของระบบรวมกับ
`tools.exec.safeBinTrustedDirs` ที่เลือกเพิ่มได้) รายการใน `PATH` จะไม่ถูกเชื่อถือโดยอัตโนมัติ
ไดเรกทอรีที่เชื่อถือได้ตามค่าเริ่มต้นถูกตั้งใจให้มีน้อยที่สุด: `/bin`, `/usr/bin` หาก
ไฟล์ปฏิบัติการ safe-bin ของคุณอยู่ในพาธของ package-manager/ผู้ใช้ (เช่น
`/opt/homebrew/bin`, `/usr/local/bin`, `/opt/local/bin`, `/snap/bin`) ให้เพิ่มพาธเหล่านั้น
ลงใน `tools.exec.safeBinTrustedDirs` อย่างชัดเจน

### การเชื่อมคำสั่งเชลล์, wrapper และ multiplexer

การเชื่อมคำสั่งเชลล์ (`&&`, `||`, `;`) อนุญาตเมื่อทุกเซกเมนต์ระดับบนสุด
ผ่าน allowlist (รวมถึงไบนารีที่ปลอดภัยหรือ skill auto-allow) การ redirect
ยังไม่รองรับในโหมด allowlist การแทนที่คำสั่ง (`$()` / backticks) จะถูก
ปฏิเสธระหว่างการแยกวิเคราะห์ allowlist รวมถึงภายในเครื่องหมายคำพูดคู่; ใช้เครื่องหมายคำพูดเดี่ยว
หากคุณต้องการข้อความ `$()` ตามตัวอักษร

ในการอนุมัติ companion-app บน macOS ข้อความเชลล์ดิบที่มีไวยากรณ์ควบคุมหรือ
ขยายเชลล์ (`&&`, `||`, `;`, `|`, `` ` ``, `$`, `<`, `>`, `(`, `)`) จะ
ถูกถือว่าไม่ตรงกับ allowlist เว้นแต่ไบนารีเชลล์เองจะอยู่ใน allowlist

สำหรับ shell wrapper (`bash|sh|zsh ... -c/-lc`) env override ที่มีขอบเขตตามคำขอจะ
ถูกลดเหลือ allowlist ขนาดเล็กที่ระบุชัดเจน (`TERM`, `LANG`, `LC_*`, `COLORTERM`,
`NO_COLOR`, `FORCE_COLOR`)

สำหรับการตัดสินใจ `allow-always` ในโหมด allowlist wrapper สำหรับ dispatch ที่รู้จัก (`env`,
`flock`, `nice`, `nohup`, `stdbuf`, `timeout`) จะบันทึกพาธไฟล์ปฏิบัติการภายใน
แทนพาธ wrapper shell multiplexer (`busybox`, `toybox`) จะถูก
unwrap สำหรับแอปเพล็ตเชลล์ (`sh`, `ash` เป็นต้น) ในแบบเดียวกัน หาก wrapper หรือ
multiplexer ไม่สามารถ unwrap ได้อย่างปลอดภัย จะไม่มีการบันทึกรายการ allowlist
โดยอัตโนมัติ

หากคุณเพิ่มอินเทอร์พรีเตอร์อย่าง `python3` หรือ `node` ลงใน allowlist ให้ใช้
`tools.exec.strictInlineEval=true` เพื่อให้ inline eval ยังคงต้องขอ
การอนุมัติอย่างชัดเจน ในโหมด strict `allow-always` ยังสามารถบันทึกการเรียกใช้
อินเทอร์พรีเตอร์/สคริปต์ที่ไม่เป็นอันตรายได้ แต่ตัวพา inline-eval จะไม่ถูกบันทึก
โดยอัตโนมัติ

### ไบนารีที่ปลอดภัยเทียบกับ allowlist

| หัวข้อ            | `tools.exec.safeBins`                                  | Allowlist (`exec-approvals.json`)                                                  |
| ---------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------- |
| เป้าหมาย             | อนุญาตตัวกรอง stdin แบบแคบโดยอัตโนมัติ                        | เชื่อถือไฟล์ปฏิบัติการที่ระบุโดยชัดเจน                                              |
| ประเภทการจับคู่       | ชื่อไฟล์ปฏิบัติการ + นโยบาย argv ของ safe-bin                 | glob พาธไฟล์ปฏิบัติการที่ resolve แล้ว หรือ glob ชื่อคำสั่งเปล่าสำหรับคำสั่งที่เรียกผ่าน PATH |
| ขอบเขตอาร์กิวเมนต์   | จำกัดโดยโปรไฟล์ safe-bin และกฎ literal-token | จับคู่พาธโดยค่าเริ่มต้น; `argPattern` ที่เลือกเพิ่มได้สามารถจำกัด argv ที่แยกวิเคราะห์แล้ว              |
| ตัวอย่างทั่วไป | `head`, `tail`, `tr`, `wc`                             | `jq`, `python3`, `node`, `ffmpeg`, CLI แบบกำหนดเอง                                     |
| การใช้งานที่เหมาะที่สุด         | การแปลงข้อความความเสี่ยงต่ำใน pipeline                  | เครื่องมือใดก็ตามที่มีพฤติกรรมกว้างกว่าหรือมีผลข้างเคียง                                     |

ตำแหน่งการกำหนดค่า:

- `safeBins` มาจาก config (`tools.exec.safeBins` หรือ `agents.list[].tools.exec.safeBins` แบบต่อ agent)
- `safeBinTrustedDirs` มาจาก config (`tools.exec.safeBinTrustedDirs` หรือ `agents.list[].tools.exec.safeBinTrustedDirs` แบบต่อ agent)
- `safeBinProfiles` มาจาก config (`tools.exec.safeBinProfiles` หรือ `agents.list[].tools.exec.safeBinProfiles` แบบต่อ agent) คีย์โปรไฟล์ต่อ agent จะ override คีย์ส่วนกลาง
- รายการ allowlist อยู่ในไฟล์ approvals เฉพาะโฮสต์ภายใต้ `agents.<id>.allowlist` (หรือผ่าน Control UI / `openclaw approvals allowlist ...`)
- `openclaw security audit` เตือนด้วย `tools.exec.safe_bins_interpreter_unprofiled` เมื่อไบนารีอินเทอร์พรีเตอร์/รันไทม์ปรากฏใน `safeBins` โดยไม่มีโปรไฟล์ที่ชัดเจน
- `openclaw doctor --fix` สามารถ scaffold รายการ `safeBinProfiles.<bin>` แบบกำหนดเองที่ขาดหายเป็น `{}` (ตรวจทานและทำให้เข้มงวดภายหลัง) ไบนารีอินเทอร์พรีเตอร์/รันไทม์จะไม่ถูก scaffold โดยอัตโนมัติ

ตัวอย่างโปรไฟล์แบบกำหนดเอง:
__OC_I18N_900000__
หากคุณเลือกเพิ่ม `jq` ลงใน `safeBins` อย่างชัดเจน OpenClaw ยังคงปฏิเสธ `env` builtin ในโหมด safe-bin
เพื่อให้ `jq -n env` ไม่สามารถ dump environment ของโปรเซสโฮสต์ได้หากไม่มีพาธ allowlist
หรือพรอมป์การอนุมัติที่ชัดเจน

## คำสั่งอินเทอร์พรีเตอร์/รันไทม์

การรันอินเทอร์พรีเตอร์/รันไทม์ที่รองรับด้วยการอนุมัติถูกออกแบบให้ระมัดระวังโดยตั้งใจ:

- บริบท argv/cwd/env ที่แน่นอนจะถูกผูกไว้เสมอ
- รูปแบบไฟล์สคริปต์เชลล์โดยตรงและไฟล์รันไทม์โดยตรงจะพยายามผูกกับสแนปช็อตไฟล์ภายในเครื่องที่เป็นรูปธรรมหนึ่งไฟล์อย่างดีที่สุด
- รูปแบบ wrapper ของ package-manager ทั่วไปที่ยัง resolve ไปยังไฟล์ภายในเครื่องโดยตรงหนึ่งไฟล์ (เช่น
  `pnpm exec`, `pnpm node`, `npm exec`, `npx`) จะถูก unwrap ก่อนผูก
- หาก OpenClaw ไม่สามารถระบุไฟล์ภายในเครื่องที่เป็นรูปธรรมได้อย่างแน่นอนหนึ่งไฟล์สำหรับคำสั่งอินเทอร์พรีเตอร์/รันไทม์
  (เช่น package scripts, รูปแบบ eval, เชน loader เฉพาะรันไทม์ หรือรูปแบบหลายไฟล์ที่กำกวม)
  การดำเนินการที่รองรับด้วยการอนุมัติจะถูกปฏิเสธแทนการอ้างว่าครอบคลุมเชิงความหมายในสิ่งที่ไม่ได้ครอบคลุม
- สำหรับเวิร์กโฟลว์เหล่านั้น ให้ใช้ sandboxing, ขอบเขตโฮสต์แยกต่างหาก หรือ
  allowlist/เวิร์กโฟลว์เต็มที่เชื่อถือโดยชัดเจน ซึ่ง operator ยอมรับ semantic ของรันไทม์ที่กว้างกว่า

เมื่อจำเป็นต้องมีการอนุมัติ เครื่องมือ exec จะคืนค่าทันทีพร้อม approval id ใช้ id นั้นเพื่อ
เชื่อมโยงกับอีเวนต์ระบบ approved-run ภายหลัง (`Exec finished`, และ `Exec running` เมื่อกำหนดค่าไว้)
หากไม่มีการตัดสินใจมาถึงก่อน timeout คำขอจะถูกถือว่าเป็น approval timeout และ
แสดงผลเป็นการปฏิเสธ host-command ระดับ terminal สำหรับการอนุมัติ async ของ main-agent ที่มี
session ต้นทาง OpenClaw ยัง resume session นั้นด้วย followup ภายในเพื่อให้ agent เห็นว่า
คำสั่งไม่ได้รัน แทนที่จะไปซ่อมผลลัพธ์ที่หายไปภายหลัง

### พฤติกรรมการส่ง followup

หลังจาก async exec ที่ได้รับอนุมัติเสร็จสิ้น OpenClaw จะส่งเทิร์น `agent` แบบ followup ไปยัง session เดิม
การอนุมัติ async ที่ถูกปฏิเสธใช้พาธ followup ของ main-session เดียวกันสำหรับสถานะการปฏิเสธ แต่จะไม่
ลงทะเบียน handoff รันไทม์แบบยกระดับ และจะไม่รันคำสั่ง การปฏิเสธที่ไม่มี main session ที่ resume ได้
จะถูก suppress หรือรายงานผ่านเส้นทางตรงที่ปลอดภัยเมื่อมีอยู่

- หากมีเป้าหมายการส่งภายนอกที่ถูกต้อง (ช่องทางที่ส่งได้พร้อมเป้าหมาย `to`) การส่ง followup จะใช้ช่องทางนั้น
- ในโฟลว์ webchat-only หรือ internal-session ที่ไม่มีเป้าหมายภายนอก การส่ง followup จะอยู่เฉพาะใน session (`deliver: false`)
- หาก caller ขอการส่งภายนอกแบบ strict อย่างชัดเจนโดยไม่มีช่องทางภายนอกที่ resolve ได้ คำขอจะล้มเหลวด้วย `INVALID_REQUEST`
- หากเปิดใช้ `bestEffortDeliver` และไม่สามารถ resolve ช่องทางภายนอกได้ การส่งจะถูกลดระดับเป็นเฉพาะ session แทนที่จะล้มเหลว

## การส่งต่อการอนุมัติไปยังช่องแชท

คุณสามารถส่งต่อพรอมป์การอนุมัติ exec ไปยังช่องแชทใดก็ได้ (รวมถึงช่องทาง Plugin) และอนุมัติ
ด้วย `/approve` สิ่งนี้ใช้ pipeline การส่งขาออกปกติ

Config:
__OC_I18N_900001__
ตอบกลับในแชท:
__OC_I18N_900002__
คำสั่ง `/approve` รองรับทั้งการอนุมัติ exec และการอนุมัติ Plugin หาก ID ไม่ตรงกับการอนุมัติ exec ที่รอดำเนินการ ระบบจะตรวจสอบการอนุมัติ Plugin แทนโดยอัตโนมัติ

### การส่งต่อการอนุมัติ Plugin

การส่งต่อการอนุมัติ Plugin ใช้ pipeline การส่งเดียวกับการอนุมัติ exec แต่มี
config อิสระของตนเองภายใต้ `approvals.plugin` การเปิดหรือปิดหนึ่งรายการจะไม่กระทบอีกรายการ
สำหรับพฤติกรรมการเขียน Plugin, ฟิลด์คำขอ และ semantic การตัดสินใจ โปรดดู
[คำขอสิทธิ์ Plugin](/plugins/plugin-permission-requests)
__OC_I18N_900003__
รูปทรง config เหมือนกับ `approvals.exec`: `enabled`, `mode`, `agentFilter`,
`sessionFilter` และ `targets` ทำงานเหมือนกัน

ช่องทางที่รองรับการตอบกลับแบบ interactive ร่วมจะแสดงปุ่มอนุมัติเดียวกันสำหรับทั้งการอนุมัติ exec และ
Plugin ช่องทางที่ไม่มี shared interactive UI จะ fallback เป็นข้อความธรรมดาพร้อมคำแนะนำ `/approve`
คำขออนุมัติ Plugin อาจจำกัดการตัดสินใจที่มีอยู่ได้ พื้นผิวการอนุมัติใช้ชุดการตัดสินใจที่คำขอ
ประกาศไว้ และ Gateway จะปฏิเสธความพยายามส่งการตัดสินใจที่ไม่ได้ถูกเสนอ

### การอนุมัติในแชทเดียวกันบนทุกช่องทาง

เมื่อคำขออนุมัติ exec หรือ Plugin มีต้นทางจากพื้นผิวแชทที่ส่งได้ แชทเดียวกัน
จะสามารถอนุมัติด้วย `/approve` ได้โดยค่าเริ่มต้นแล้ว สิ่งนี้ใช้กับช่องทางอย่าง Slack, Matrix และ
Microsoft Teams นอกเหนือจากโฟลว์ Web UI และ terminal UI ที่มีอยู่แล้ว

เส้นทางคำสั่งแบบข้อความที่ใช้ร่วมกันนี้ใช้โมเดลการยืนยันตัวตนของช่องทางปกติสำหรับการสนทนานั้น หากแชต
ต้นทางสามารถส่งคำสั่งและรับคำตอบได้อยู่แล้ว คำขออนุมัติจะไม่ต้องมี
อะแดปเตอร์การส่งแบบเนทีฟแยกต่างหากเพียงเพื่อคงสถานะรอดำเนินการ

Discord และ Telegram ยังรองรับ `/approve` ในแชตเดียวกันด้วย แต่ช่องทางเหล่านั้นยังคงใช้
รายการผู้อนุมัติที่ resolve แล้วสำหรับการอนุญาต แม้จะปิดการส่งการอนุมัติแบบเนทีฟไว้ก็ตาม

สำหรับ Telegram และไคลเอนต์การอนุมัติแบบเนทีฟอื่นที่เรียก Gateway โดยตรง
fallback นี้ถูกจำกัดไว้เฉพาะความล้มเหลวแบบ "ไม่พบการอนุมัติ" โดยตั้งใจ การปฏิเสธ/ข้อผิดพลาดของ
การอนุมัติ exec จริงจะไม่ลองใหม่แบบเงียบ ๆ ในฐานะการอนุมัติ Plugin

### การส่งการอนุมัติแบบเนทีฟ

บางช่องทางยังสามารถทำหน้าที่เป็นไคลเอนต์การอนุมัติแบบเนทีฟได้ด้วย ไคลเอนต์แบบเนทีฟเพิ่ม DM ของผู้อนุมัติ การกระจายไปยังแชตต้นทาง
และ UX การอนุมัติแบบโต้ตอบเฉพาะช่องทางไว้บนโฟลว์ `/approve`
ในแชตเดียวกันที่ใช้ร่วมกัน

เมื่อมีการ์ด/ปุ่มอนุมัติแบบเนทีฟ UI แบบเนทีฟนั้นจะเป็นเส้นทางหลัก
ที่ agent เห็น agent ไม่ควร echo คำสั่งแชตธรรมดา
`/approve` ซ้ำอีก เว้นแต่ผลลัพธ์ของเครื่องมือจะบอกว่าใช้การอนุมัติผ่านแชตไม่ได้ หรือ
การอนุมัติด้วยตนเองเป็นเส้นทางเดียวที่เหลืออยู่

หากมีการกำหนดค่าไคลเอนต์การอนุมัติแบบเนทีฟไว้ แต่ไม่มีรันไทม์แบบเนทีฟที่ทำงานอยู่สำหรับ
ช่องทางต้นทาง OpenClaw จะยังแสดงพรอมป์ `/approve`
แบบ local deterministic ไว้ หากรันไทม์แบบเนทีฟทำงานอยู่และพยายามส่งแล้ว แต่ไม่มี
เป้าหมายใดได้รับการ์ด OpenClaw จะส่งประกาศ fallback ในแชตเดียวกันพร้อมคำสั่ง
`/approve <id> <decision>` แบบตรงตัว เพื่อให้คำขอยังสามารถถูก resolve ได้

โมเดลทั่วไป:

- นโยบาย exec ของโฮสต์ยังคงตัดสินว่าจำเป็นต้องมีการอนุมัติ exec หรือไม่
- `approvals.exec` ควบคุมการส่งต่อพรอมป์อนุมัติไปยังปลายทางแชตอื่น
- `channels.<channel>.execApprovals` ควบคุมว่าจะเปิดใช้ไคลเอนต์แบบเนทีฟเฉพาะช่องทางของ Discord, Slack, Telegram และช่องทางที่คล้ายกันหรือไม่
- การอนุมัติ Plugin ของ Slack สามารถใช้ไคลเอนต์การอนุมัติแบบเนทีฟของ Slack ได้เมื่อคำขอมาจาก Slack
  และ resolve ผู้อนุมัติ Plugin ของ Slack ได้; `approvals.plugin` ยังสามารถ route การอนุมัติ Plugin ไปยังเซสชันหรือเป้าหมายของ Slack
  ได้ แม้จะปิดการอนุมัติ exec ของ Slack ไว้
- การ์ดอนุมัติแบบเนทีฟของ Google Chat จัดการการอนุมัติ exec และ Plugin ที่มีต้นทางจาก space หรือ thread ของ Google
  Chat เมื่อ resolve ผู้อนุมัติ `users/<id>` ที่เสถียรจาก `dm.allowFrom` หรือ
  `defaultTo` ได้; การ์ดเหล่านี้ไม่ใช้เหตุการณ์ reaction ในการตัดสินใจ
- การส่งการอนุมัติผ่าน reaction ของ WhatsApp และ Signal ถูกกั้นด้วย `approvals.exec` และ
  `approvals.plugin`; ทั้งสองไม่มีบล็อก `channels.<channel>.execApprovals`

ไคลเอนต์การอนุมัติแบบเนทีฟจะเปิดใช้การส่งแบบ DM ก่อนโดยอัตโนมัติเมื่อทั้งหมดนี้เป็นจริง:

- ช่องทางรองรับการส่งการอนุมัติแบบเนทีฟ
- สามารถ resolve ผู้อนุมัติจาก `execApprovals.approvers` ที่ระบุไว้ชัดเจน หรือ identity ของเจ้าของ
  เช่น `commands.ownerAllowFrom`
- ไม่ได้ตั้งค่า `channels.<channel>.execApprovals.enabled` ไว้ หรือเป็น `"auto"`

ตั้ง `enabled: false` เพื่อปิดไคลเอนต์การอนุมัติแบบเนทีฟอย่างชัดเจน ตั้ง `enabled: true` เพื่อบังคับ
เปิดเมื่อ resolve ผู้อนุมัติได้ การส่งไปยังแชตต้นทางสาธารณะยังคงต้องระบุอย่างชัดเจนผ่าน
`channels.<channel>.execApprovals.target`

คำถามที่พบบ่อย: [ทำไมจึงมีการกำหนดค่าการอนุมัติ exec สองรายการสำหรับการอนุมัติผ่านแชต?](/help/faq-first-run#why-are-there-two-exec-approval-configs-for-chat-approvals)

- Discord: `channels.discord.execApprovals.*`
- Slack: `channels.slack.execApprovals.*`
- Telegram: `channels.telegram.execApprovals.*`
- Google Chat: กำหนดค่าผู้อนุมัติที่เสถียรด้วย `channels.googlechat.dm.allowFrom` หรือ
  `channels.googlechat.defaultTo`; ไม่จำเป็นต้องมีบล็อก `execApprovals`
- WhatsApp: ใช้ `approvals.exec` และ `approvals.plugin` เพื่อ route พรอมป์อนุมัติไปยัง WhatsApp
- Signal: ใช้ `approvals.exec` และ `approvals.plugin` เพื่อ route พรอมป์อนุมัติไปยัง Signal

ไคลเอนต์การอนุมัติแบบเนทีฟเหล่านี้เพิ่มการ route DM และการกระจายไปยังช่องทางแบบเลือกได้ไว้บนโฟลว์
`/approve` ในแชตเดียวกันที่ใช้ร่วมกัน และปุ่มอนุมัติที่ใช้ร่วมกัน

พฤติกรรมที่ใช้ร่วมกัน:

- Slack, Matrix, Microsoft Teams และแชตที่ส่งได้ลักษณะคล้ายกันใช้โมเดลการยืนยันตัวตนของช่องทางปกติ
  สำหรับ `/approve` ในแชตเดียวกัน
- เมื่อไคลเอนต์การอนุมัติแบบเนทีฟเปิดใช้อัตโนมัติ เป้าหมายการส่งแบบเนทีฟเริ่มต้นคือ DM ของผู้อนุมัติ
- สำหรับ Discord และ Telegram เฉพาะผู้อนุมัติที่ resolve แล้วเท่านั้นที่สามารถอนุมัติหรือปฏิเสธได้
- ผู้อนุมัติ Discord สามารถระบุชัดเจน (`execApprovals.approvers`) หรืออนุมานจาก `commands.ownerAllowFrom`
- ผู้อนุมัติ Telegram สามารถระบุชัดเจน (`execApprovals.approvers`) หรืออนุมานจาก `commands.ownerAllowFrom`
- ผู้อนุมัติ Slack สามารถระบุชัดเจน (`execApprovals.approvers`) หรืออนุมานจาก `commands.ownerAllowFrom`
- DM การอนุมัติ Plugin ของ Slack ใช้ผู้อนุมัติ Plugin ของ Slack จาก `allowFrom` และการ route เริ่มต้นของบัญชี
  ไม่ใช่ผู้อนุมัติ exec ของ Slack
- ปุ่มเนทีฟของ Slack เก็บชนิด id การอนุมัติไว้ ดังนั้น id `plugin:` จึงสามารถ resolve การอนุมัติ Plugin
  ได้โดยไม่ต้องมีชั้น fallback แบบ local ของ Slack อีกชั้น
- การ์ดเนทีฟของ Google Chat เก็บ fallback `/approve` แบบทำเองไว้ในข้อความ แต่ callback ของปุ่มการ์ด
  จะพกเฉพาะ token การกระทำแบบ opaque; id การอนุมัติและการตัดสินใจจะถูกกู้คืนจากสถานะรอดำเนินการฝั่งเซิร์ฟเวอร์
- การอนุมัติด้วยอีโมจิ WhatsApp จัดการทั้งพรอมป์ exec และ Plugin เฉพาะเมื่อ family การส่งต่อระดับบนสุด
  ที่ตรงกันเปิดใช้อยู่และ route ไปยัง WhatsApp; การส่งต่อไปยัง WhatsApp แบบระบุเป้าหมายเท่านั้นยังอยู่บน
  เส้นทางการส่งต่อที่ใช้ร่วมกัน เว้นแต่จะตรงกับเป้าหมายต้นทางแบบเนทีฟเดียวกัน
- การอนุมัติผ่าน reaction ของ Signal จัดการทั้งพรอมป์ exec และ Plugin เฉพาะเมื่อ family การส่งต่อระดับบนสุด
  ที่ตรงกันเปิดใช้อยู่และ route ไปยัง Signal การอนุมัติ exec ของ Signal ในแชตเดียวกันโดยตรงสามารถ
  suppress fallback `/approve` แบบ local ได้โดยไม่ต้องมีผู้อนุมัติที่ระบุชัดเจน; การ resolve reaction ของ Signal
  ยังต้องมีผู้อนุมัติ Signal ที่ระบุชัดเจนจาก `channels.signal.allowFrom` หรือ `defaultTo`
- การ route DM/ช่องทางแบบเนทีฟของ Matrix และ shortcut ผ่าน reaction จัดการทั้งการอนุมัติ exec และ Plugin;
  การอนุญาต Plugin ยังคงมาจาก `channels.matrix.dm.allowFrom`
- พรอมป์เนทีฟของ Matrix รวมเนื้อหาเหตุการณ์กำหนดเอง `com.openclaw.approval` ไว้ในเหตุการณ์พรอมป์แรก
  เพื่อให้ไคลเอนต์ Matrix ที่รู้จัก OpenClaw สามารถอ่านสถานะการอนุมัติแบบมีโครงสร้างได้ ขณะที่ไคลเอนต์มาตรฐาน
  ยังคงมี fallback `/approve` แบบข้อความธรรมดา
- ผู้ร้องขอไม่จำเป็นต้องเป็นผู้อนุมัติ
- แชตต้นทางสามารถอนุมัติโดยตรงด้วย `/approve` ได้เมื่อแชตนั้นรองรับคำสั่งและการตอบกลับอยู่แล้ว
- ปุ่มอนุมัติแบบเนทีฟของ Discord จะ route ตามชนิด id การอนุมัติ: id `plugin:` จะไปยังการอนุมัติ Plugin
  โดยตรง ส่วนอย่างอื่นทั้งหมดจะไปยังการอนุมัติ exec
- ปุ่มอนุมัติแบบเนทีฟของ Telegram ใช้ fallback จาก exec ไป Plugin แบบจำกัดเดียวกับ `/approve`
- เมื่อ `target` แบบเนทีฟเปิดใช้การส่งไปยังแชตต้นทาง พรอมป์อนุมัติจะรวมข้อความคำสั่งไว้ด้วย
- การอนุมัติ exec ที่รอดำเนินการจะหมดอายุหลัง 30 นาทีตามค่าเริ่มต้น
- หากไม่มี UI สำหรับ operator หรือไคลเอนต์อนุมัติที่กำหนดค่าไว้ใดสามารถรับคำขอได้ พรอมป์จะ fallback ไปยัง `askFallback`

คำสั่งกลุ่มที่ละเอียดอ่อนและให้เฉพาะเจ้าของใช้ เช่น `/diagnostics` และ `/export-trajectory` ใช้การ route
เจ้าของแบบส่วนตัวสำหรับพรอมป์อนุมัติและผลลัพธ์สุดท้าย OpenClaw จะลอง route แบบส่วนตัวบน
พื้นผิวเดียวกับที่เจ้าของรันคำสั่งก่อน หากพื้นผิวนั้นไม่มี route เจ้าของแบบส่วนตัว ระบบจะ
fallback ไปยัง route เจ้าของรายการแรกที่พร้อมใช้งานจาก `commands.ownerAllowFrom` ดังนั้นคำสั่งกลุ่มใน Discord
จึงยังสามารถส่งการอนุมัติและผลลัพธ์ไปยัง DM ของ Telegram ของเจ้าของได้ เมื่อ Telegram เป็นอินเทอร์เฟซส่วนตัวหลัก
ที่กำหนดค่าไว้ แชตกลุ่มจะได้รับเพียง acknowledgement สั้น ๆ

Telegram ใช้ค่าเริ่มต้นเป็น DM ของผู้อนุมัติ (`target: "dm"`) คุณสามารถสลับเป็น `channel` หรือ `both` เมื่อคุณ
ต้องการให้พรอมป์อนุมัติปรากฏในแชต/หัวข้อ Telegram ต้นทางด้วย สำหรับหัวข้อฟอรัม Telegram
OpenClaw จะรักษาหัวข้อไว้สำหรับพรอมป์อนุมัติและการติดตามผลหลังอนุมัติ

ดูเพิ่มเติม:

- [Discord](/channels/discord)
- [Telegram](/channels/telegram)

### โฟลว์ IPC ของ macOS
__OC_I18N_900004__
หมายเหตุด้านความปลอดภัย:

- โหมด Unix socket `0600`, token เก็บไว้ใน `exec-approvals.json`
- ตรวจสอบ peer ที่มี UID เดียวกัน
- challenge/response (nonce + HMAC token + request hash) + TTL สั้น

## คำถามที่พบบ่อย

### `accountId` และ `threadId` จะถูกใช้บนเป้าหมายการอนุมัติเมื่อใด?

ใช้ `accountId` เมื่อช่องทางมี identity ที่กำหนดค่าไว้หลายรายการ และพรอมป์อนุมัติต้อง
ออกผ่านบัญชีเฉพาะบัญชีหนึ่ง ใช้ `threadId` เมื่อปลายทางรองรับหัวข้อหรือ
thread และพรอมป์ควรอยู่ภายใน thread นั้นแทนที่จะอยู่ในแชตระดับบนสุด

กรณี Telegram ที่ชัดเจนคือ supergroup สำหรับงานปฏิบัติการที่มีหัวข้อฟอรัมและบัญชีบอต Telegram
สองบัญชี ค่า `to` ระบุชื่อ supergroup, `accountId` เลือกบัญชีบอต และ `threadId`
เลือกหัวข้อฟอรัม:
__OC_I18N_900005__
ด้วยการตั้งค่านั้น การอนุมัติ exec ที่ส่งต่อจะถูกโพสต์โดยบัญชี Telegram `ops-bot` เข้าไปในหัวข้อ
`77` ของแชต `-1001234567890` เป้าหมายที่ไม่มี `accountId` จะใช้บัญชีเริ่มต้นของช่องทาง และ
เป้าหมายที่ไม่มี `threadId` จะโพสต์ไปยังปลายทางระดับบนสุด

### เมื่อการอนุมัติถูกส่งไปยังเซสชัน ทุกคนในเซสชันนั้นสามารถอนุมัติได้หรือไม่?

ไม่ได้ การส่งไปยังเซสชันควบคุมเฉพาะตำแหน่งที่พรอมป์ปรากฏเท่านั้น โดยตัวมันเองไม่ได้อนุญาตให้
ผู้เข้าร่วมทุกคนในแชตนั้นอนุมัติได้

สำหรับ `/approve` ในแชตเดียวกันแบบทั่วไป ผู้ส่งต้องได้รับอนุญาตให้ใช้คำสั่งใน
เซสชันของช่องทางนั้นอยู่แล้ว หากช่องทางเปิดเผยผู้อนุมัติการอนุมัติแบบชัดเจน ผู้อนุมัติเหล่านั้นสามารถอนุญาต
การกระทำ `/approve` ได้ แม้โดยปกติพวกเขาจะไม่ได้รับอนุญาตให้ใช้คำสั่งในเซสชันนั้นก็ตาม

บางช่องทางเข้มงวดกว่า Discord, Telegram, Matrix, DM การอนุมัติแบบเนทีฟของ Slack และ
ไคลเอนต์การอนุมัติแบบเนทีฟที่คล้ายกันใช้รายการผู้อนุมัติที่ resolve แล้วสำหรับการอนุญาตการอนุมัติ ตัวอย่างเช่น
พรอมป์อนุมัติในหัวข้อฟอรัม Telegram อาจมองเห็นได้สำหรับทุกคนในหัวข้อนั้น แต่เฉพาะ ID ผู้ใช้ Telegram
แบบตัวเลขที่ resolve จาก `channels.telegram.execApprovals.approvers` หรือ
`commands.ownerAllowFrom` เท่านั้นที่สามารถอนุมัติหรือปฏิเสธได้

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

- [การอนุมัติ exec](/th/tools/exec-approvals) — นโยบายหลักและโฟลว์การอนุมัติ
- [เครื่องมือ exec](/th/tools/exec)
- [โหมด elevated](/th/tools/elevated)
- [Skills](/th/tools/skills) — พฤติกรรม auto-allow ที่หนุนด้วย skill
