文件 v1.0.9

安全模型

Localhost 綁定

HTTP server 僅綁定 127.0.0.1:17989 — 區網 client 無法連到 daemon。Web 儀表板內嵌於執行檔,由同一個 daemon 在 / 提供,因此一般情況下瀏覽器來源就是你自己的機器。CORS middleware 接受 loopback 來源(localhost127.0.0.1::1),另加兩個固定的託管來源 https://web.agenvoy.comhttps://agenvoy-board.pardn.workers.dev,並以 Access-Control-Allow-Private-Network 回應 Chrome Private Network Access,讓這些頁面能從瀏覽器呼叫本機 API。

碰到憑證、設定檔或行程狀態的端點,在綁定之外另有 localhostOnly() 守門。它檢查的是連線的 remote address(127.0.0.1 / ::1),不是 Origin header。

沒有提權模式

不存在 /sudo 指令,也沒有 session 層級的提權。/dangerous 指令已移除;請改用下述的逐次確認或 TUI 的直接操作。兩者皆由逐請求授權取代:越過安全邊界的呼叫只為那一次呼叫升起確認,授權範圍限於該 session 加上該特定路徑。

$HOME 一律可寫,無需設定。兩種情況落在其外:

情況 行為
$HOME 之外的路徑,或 $HOME 內的敏感路徑 boundary.Restricted 收集後升起確認,且要求作業系統密碼。核准後該路徑授權給該 session
需要寫到 $HOME 之外的指令 Agent 在該次 run_command 附上 write_paths;這些路徑要等同一道密碼確認通過後才綁進 sandbox

密碼檢查集中在 internal/sudosudo -n -v 探測 sudo ticket 是否仍在快取(上限 3 秒),sudo -S -v 驗證輸入的密碼(上限 30 秒)。sudo ticket 是唯一的計時器——沒有第二層 TTL。ticket 仍在快取時,提示不會要求輸入密碼;以 root 執行的 daemon 則直接略過檢查。

TUI 與本機 web 儀表板可以收集密碼;web 確認端點只接受來自 loopback 連線的密碼。無法收集密碼的通道——Telegram、Discord、遠端 HTTP 呼叫端——會拿回 skipped,不會被提權。通道可以核准提示,但缺少驗證的受限呼叫不會執行。

sudo 本身無法在 run_command 內執行,不論直接呼叫或放在 sh -c 內:呼叫會被拒絕,並指引改用 write_paths 與密碼確認。

讀取不受路徑限制。Sandbox 約束的是寫入而非讀取,因此指令只有在作業系統本身拒絕時才會在某路徑失敗。

永久拒絕

config.jsondenied_path 是硬性拒絕清單:這些路徑讀寫皆不可,任何提示都無法核准,重試同一路徑會以相同方式失敗。項目必須是絕對路徑或以 ~/ 開頭;檔案系統根目錄會被拒收。denied_command 是其指令側的對應——清單上的 binary 一律拒絕,sh -c 內亦然。

敏感檔案防護

符合敏感集合的檔案——SSH keys、.pem.key.env 與憑證檔——比照 $HOME 之外的路徑處理:read_filesedit_fileopen_filefind_filesfile_history,以及帶 save_tofetch_page,在碰觸前都會升起需密碼驗證的確認。該集合為 sensitive_pathdirs / files / prefixes / extensions),編譯進執行檔並與 config.json 中的使用者項目合併。此防護由 Go 強制,非基於 prompt。

權限模式

Agenvoy 支援兩種權限模式:single-confirm(每次寫入/執行呼叫都要確認)與 always-allow(寫入/執行工具不需逐次確認)。在 always-allow 下,system prompt 仍要求七類真正不可逆的操作先經明確 ask_user

mode 的工具由 mode 決定閘門:list / read / search 視為唯讀並跳過確認,而 remove / restore 即使在已自動核准的工具上仍一律確認。

依來源路由的確認

每個互動請求都帶有來源前綴——cli-chat-tg-dc-。CLI 的確認只由 TUI 消費,web 請求由 web 確認串流消費,Telegram 或 Discord 請求由對應的通道 listener 消費。確認 5 分鐘未回覆即視為 skipped,任務保留為待決,因此一個通道既無法攔截、也無法無限期占住另一個通道的提示。

System prompt 保護

System prompt(configs/prompts/system_prompt/system_prompt.md)結尾有一段優先於 skill、使用者指示與對話脈絡的規則。符合下列任一類別的請求只會得到 [KARAPPO] 作為回覆:

這些是 prompt 中的 policy,非 Go 端硬編碼的 filter — 新增一個類別只需編輯 prompt。

Keychain

憑證(provider API keys、OAuth tokens)透過 go-pkg/filesystem/keychain 儲存,service 名為 agenvoy

平台 後端
macOS security CLI
Linux / 其他 secret-tool(libsecret),失敗時回退到純文字 KEY=value~/.config/agenvoy/.secrets

找不到已儲存的值時,改用同名環境變數。Service 名稱 "agenvoy" 為固定值,不得變更。

指令執行

run_command 永遠不會拿到原始 shell 字串。argv-only 輸入、強制裸指令名,以及經解析(而非樣式比對)的 sh -c 腳本,構成三道防線——完整規則見沙箱頁。位於唯讀清單的指令(git statuslscat ...)跳過 confirm gate;其餘皆由當前權限模式控管。

指令政策是拒絕清單而非允許清單:config.jsondenied_command 是唯一清單,不在其上的指令都可執行,但仍受 sandbox 與確認機制約束。舊的 white_list / path_white_list 鍵已不再讀取,sensitive_map 已更名為 sensitive_path——設定檔若仍留有這些鍵,daemon 會記一則警告。

MCP 隔離考量

MCP server 是行為無法驗證的第三方行程。Agenvoy 預設將其視為不受信任,且不提供 per-server 的「trusted」旗標。所有 MCP 工具呼叫都經過與內建工具相同的 confirm gate。若要批次執行,請透過 /mcp → permission(或 POST /v1/allowlisttool 區塊)把特定工具標記為自動核准,而非信任整台 server。


[!NOTE] 本文件由 Claude 在讀取完整原始碼後自動生成。

EN