給 AI 代理 Discord 存取權意味著它可以發訊息、踢成員、刪除頻道等。權限設定檔與稽核紀錄可讓你設下邊界並保有可追溯性。

為何重要

想像一個自主代理:

  • 解讀錯誤訊息後,原本該警告成員卻誤踢人
  • 進入迴圈後狂發訊息
  • 透過提示注入執行不該有的操作

權限設定檔會限制代理實際可執行的指令,不受訊息內容誤導的影響。

權限設定檔

discli 內建四種設定檔:

完全開放所有指令。 沒有限制。

允許:*
拒絕:無

適用:受控環境中的信任腳本、由人員操作的管理機器人。

訊息、反應、討論串、輸入指示、DM、監聽與伺服器資訊。 不可踢出、封鎖、刪除頻道、破壞性角色管理。

允許:message、reaction、thread、typing、dm、listen、serve、config、server
拒絕:member kick、member ban、member unban、channel delete、role delete、role create、channel create

適用:AI 支援代理、聊天機器人、對話型機器人。建議做為自主代理的預設值。

只讀操作。 可列表、搜尋、查看,但不能傳送或修改訊息。

允許:message list、message get、message search、message history、
channel list、channel info、server list、server info、
role list、member list、member info、reaction list、
thread list、listen、config show
拒絕:*(其他全部)

適用:監控、分析、儀表板、日誌匯出。

完整權限含仲裁。full 相同,但語意上代表仲裁角色。

允許:*
拒絕:無

適用:需要踢出、封鎖、角色管理的仲裁機器人。建議搭配 --triggered-by 做使用者權限驗證。

設定權限設定檔

有三種方式可設定目前啟用的設定檔,以下為優先序由高到低:

1. 指令層級旗標(優先權最高)

Terminal window
discli --profile chat message send "#general" "Hello"
discli --profile readonly serve --events messages

2. 環境變數

Terminal window
export DISCLI_PROFILE=chat
discli serve --events messages

3. 持久化設定

Terminal window
# 設定預設設定檔
discli permission set chat
# 檢查目前設定檔
discli permission show
# 列出所有設定檔
discli permission profiles

設定檔儲存在 ~/.discli/permissions.json

Tip

對於自主代理,建議在子程序啟動時用 --profile 明確傳入。這樣限制會寫在程式邏輯中,不受環境變數或 config 變更影響。

權限判斷流程

discli 在執行命令時會做三步判斷:

  1. 指令是否在 denied 清單?若是則直接阻擋
  2. 指令是否在 allowed 清單?若是則通過
  3. 否則阻擋

採前綴比對:若允許 message,則 message sendmessage listmessage delete、其他所有 message 子指令都會被允許。

萬用字元 * 代表:

  • "allowed": ["*"]:允許全部
  • "denied": ["*"]:全部拒絕,僅允許明確放行的項目
# 在 agent 程式中,以 --profile 啟動 serve
proc = subprocess.Popen(
["discli", "--profile", "chat", "serve", "--events", "messages"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
text=True,
)

若代理嘗試執行被拒絕指令:

錯誤:權限設定檔不允許執行「member kick」指令。

serve 模式會回傳錯誤事件:

{"event": "error", "message": "Command 'serve' is denied by your permission profile."}
{"event": "error", "message": "權限設定檔不允許執行「serve」指令。"}

--triggered-by 旗標

對仲裁相關操作,--triggered-by 會驗證真正觸發動作的 Discord 使用者是否有需要的權限:

Terminal window
discli member kick "My Server" "@spammer" --reason "Spam" --triggered-by 9876543210

檢查順序:

  1. 9876543210 是否是該伺服器成員?
  2. 是否有 kick_members 權限?
  3. 是否是伺服器擁有者或有管理員權限?

若檢查失敗,動作會阻擋且寫入稽核紀錄。

Warning

--triggered-by 僅支援 member kickmember banmember unban。你必須在事件中傳入正確的使用者 ID;代理理論上可能傳入自己或假 ID,因此這屬於「加深防線」而非絕對邊界。

權限對應表

行為需要的 Discord 權限
member kickkick_members
member ban / member unbanban_members

伺服器擁有者與擁有管理員權限的使用者一定通過檢查。

高風險操作確認

某些指令需在執行前確認:

  • member kick
  • member ban
  • member unban
  • member timeout
  • channel delete
  • message delete
  • message bulk-delete
  • role delete
  • webhook delete
  • event delete

互動模式下 discli 會提示:

⚠ 高風險操作:member kick(alice 來自 My Server)。要繼續嗎?[y/N]

在腳本/自動化情境可加旗標略過確認:

Terminal window
discli --yes member kick "My Server" "@spammer" --reason "Spam"
Danger

不要在自主代理中無條件使用 --yes,除非已搭配嚴格限制的權限設定檔。--yes--profile full 結合時,會讓代理可無安全檢查地執行任何高風險動作。

稽核紀錄

每次高風險操作都會以 JSONL 寫入 ~/.discli/audit.log

{
"timestamp": "2025-03-15T10:30:00+00:00",
"command": "member kick",
"args": {"server": "My Server", "member": "alice#1234", "reason": "Spam"},
"result": "ok",
"user": "9876543210"
}

查看稽核紀錄

Terminal window
# 顯示最近 20 筆
discli audit show
# 顯示最近 50 筆
discli audit show --limit 50
# JSON 輸出
discli --json audit show --limit 100
# 匯入 jq 分析
discli --json audit show --limit 1000 | jq 'group_by(.command) | map({command: .[0].command, count: length})'

清空稽核紀錄

Terminal window
discli audit clear

會被記錄的項目

行為會記錄嗎
member kick
member ban
member unban
member timeout
channel delete
message delete
message bulk-delete
role delete
webhook delete
event delete
message send
message list
權限檢查失敗

速率限制

高風險行為(破壞性操作)被限制為 5 次/5 秒。超過上限時 CLI 會暫停並輸出警告:

速率已超過上限。等待 3.2 秒…

這可避免代理失控時大量刪文、批次踢人或泛濫 API。速率限制為單一程序內全域。

Note

速率限制套用在高風險 CLI 指令(kickbandelete)。serve 模式的動作會略過 CLI 這層,但仍受 Discord API 的速率限制;若超限,會回傳 HTTP 錯誤。

客製權限設定檔

可在 ~/.discli/permissions.json 新增自訂設定檔:

{
"active_profile": "support-agent",
"profiles": {
"support-agent": {
"description": "可進行訊息互動與建立討論串,但不能管理成員或頻道",
"allowed": [
"message send",
"message reply",
"message list",
"message get",
"message search",
"thread create",
"thread send",
"thread list",
"reaction add",
"reaction remove",
"dm send",
"typing",
"serve",
"listen",
"channel list",
"channel info",
"server list",
"server info",
"member list",
"member info"
],
"denied": ["*"]
}
}
}

"denied": ["*"] 代表「未明確列入允許者皆禁止」。這是客製設定檔最安全的做法之一。

Tip

建議從最嚴格版本開始,逐步放開權限。補齊缺漏的權限通常比因誤刪頻道後追補後置修復簡單得多。

建議組態

AI 聊天機器人

Terminal window
discli --profile chat serve \
--events messages

可傳訊息、建立討論串、加反應,但不能踢人、封鎖或刪除。

監控儀表板

Terminal window
discli --profile readonly serve \
--events messages,members

可查詢與搜尋,不可傳送、修改或刪除任何資源。

仲裁機器人

Terminal window
discli --profile moderation serve \
--events messages,members

完整存取權,建議搭配 --triggered-by 驗證真人仲裁者權限。

CI 通知器

Terminal window
discli --profile chat \
message send "#deploys" "v2.1.0 deployed"

只需發訊息,通常不需 listenserve 或成員操作。

安全檢查清單

Token 使用環境變數

不建議硬編碼 token,請改用 DISCORD_BOT_TOKEN~/.discli/config.json

設定權限檔

預設為 full。自主代理請改為 chatreadonly

仲裁時傳遞 --triggered-by

代理代替使用者踢人或封鎖時,請先驗證該使用者在 Discord 的權限。

定期查稽核紀錄

定期查 discli audit show,確認代理行為符合預期。

先用 readonly 開發

開發時先跑 --profile readonly,確認流程後再升到 chat

下一步