04 · 核准與沙盒:它能動什麼
這是整本手冊最該先讀的一篇。
兩層控制,管的不是一回事
Codex 的安全控制由兩層配合完成,很多人一開始會把它們搞混:
- 沙盒模式(
--sandbox):它執行指令時,技術上能做到什麼——能寫哪些位置、能不能聯網。 - 核准策略(
--ask-for-approval):哪些動作必須先停下來問你——離開沙盒、存取網路、執行不受信任的指令。
一個是能力上限,一個是打斷你的頻率。兩者是乘法關係: read-only + never 是最安靜也最無害的組合;danger-full-access + never 是完全放開。
預設情況下,智慧體在關閉網路存取的狀態下執行,寫入範圍限制在當前工作區內。
沙盒模式
| 模式 | 能做什麼 |
|---|---|
read-only | 只能讀。想改檔案、跑指令、聯網都得走核准 |
workspace-write | 在工作區裡讀寫、跑指令;預設不能聯網 |
danger-full-access | 沒有沙盒限制 |
「工作區」不只是當前目錄——還包括 /tmp 之類的臨時目錄。 拿不準的時候用 /status 看一眼當前工作階段到底把哪些目錄算進了工作區。
可寫根目錄裡仍然有隻讀的地方
即使在 workspace-write 下,這幾個路徑仍然受只讀保護,而且是遞迴的:
<可写根目录>/.git(無論它是目錄還是gitdir: ...指標檔案;是指標的話,解析出來的真實 Git 目錄也一起保護)<可写根目录>/.agents(作為目錄存在時)<可写根目录>/.codex(作為目錄存在時)
這個設計很實在:智慧體可以在你的倉庫裡隨便改程式碼,但改不了 Git 後設資料本身, 所以 git diff / git checkout 這條退路始終有效。
聯網是單獨一個開關
workspace-write 預設禁網。要開:
[sandbox_workspace_write]
network_access = true開了之後如果還想限制它能連哪裡,再開啟網路代理:
[features.network_proxy]
enabled = true
domains = { "api.openai.com" = "allow", "example.com" = "deny" }注意:只加域名規則不會自動啟用代理,enabled = true 得單獨寫。
核准策略
| 值 | 什麼時候問你 |
|---|---|
untrusted | 只自動執行已知安全的讀取操作,其餘都問 |
on-request | 需要越過沙盒邊界時問(預設的 Auto 用的就是它) |
never | 從不問;在你設的沙盒限制內盡力執行 |
--ask-for-approval never(簡寫 -a never)不等於放開權限——它對所有 --sandbox 模式都適用, 沙盒該攔還是攔。真正放開是 --sandbox danger-full-access。
用 untrusted 時,可能改變狀態或觸發外部執行路徑的指令都要核准, 包括破壞性的 Git 操作,以及帶 Git 輸出標誌、配置覆蓋標誌的指令。
六種常見組合
| 用途 | 指令 | 效果 |
|---|---|---|
| 自動(預設) | codex,等價於 --sandbox workspace-write --ask-for-approval on-request | 工作區內隨便幹;出界或聯網要核准 |
| 只讀討論 | --sandbox read-only --ask-for-approval on-request | 能讀能答;要改要跑要聯網都得核准 |
| CI 裡只讀跑 | --sandbox read-only --ask-for-approval never | 只讀,絕不打斷 |
| 自動改但指令要審 | --sandbox workspace-write --ask-for-approval untrusted | 檔案隨便改,不受信任的指令先問 |
| 自動稽核 | --sandbox workspace-write -a on-request -c approvals_reviewer=auto_review | 邊界不變,但核准交給審查智慧體,不彈給你 |
| 危險的完全放開 | --dangerously-bypass-approvals-and-sandbox(別名 --yolo) | 無沙盒、無核准(不推薦) |
關於 --yolo
它確實好用,尤其在一個你隨時能扔掉的容器裡。 但在你自己的開發機上、在有未提交改動的倉庫裡用它,本質上是拿工作賭它這次不會跑錯指令。 真需要放開,先想想能不能換成 Dev Container 或工作樹,把風險關在一個盒子裡。
把核准交給審查智慧體
如果核准提示太多、但又不想直接 never,還有一條中間路:
approval_policy = "on-request"
approvals_reviewer = "auto_review"設成 auto_review 之後,符合條件的核准請求會先交給一個審查智慧體, 它按策略檢查資料外洩、憑據探測、削弱安全防護、破壞性操作這幾類風險: 低風險和中風險放行,嚴重風險拒絕,高風險需要充分的使用者授權。 提示構建、審查工作階段或解析失敗時預設拒絕。
代價是它會額外呼叫模型,所以會多花額度。管理員可以用 allowed_approvals_reviewers 限制誰能用。
還有一種更細的做法,讓某些類別保持互動式、其餘自動拒絕:
approval_policy = { granular = {
sandbox_approval = true,
rules = true,
mcp_elicitations = true,
request_permissions = false,
skill_approval = false
} }寫進 config.toml,別每次敲標誌
# ~/.codex/config.toml
approval_policy = "on-request"
sandbox_mode = "workspace-write"
[sandbox_workspace_write]
network_access = false也可以存成多個配置方案,按場景切換:
# ~/.codex/readonly_quiet.config.toml
approval_policy = "never"
sandbox_mode = "read-only"codex --profile readonly_quiet我的建議
- 日常在自己倉庫裡:預設的
Auto就挺好,別急著調。 - 看一個不熟的倉庫:
--sandbox read-only,先讓它讀懂再說。 - 跑在 CI 裡:
--sandbox read-only --ask-for-approval never,要寫的話再單獨放開。 - 核准煩到影響幹活:先試
auto_review或細粒度策略,再考慮never。 - 想徹底放開:先把工作放進容器或 Git 工作樹。