用 Rules 控制命令邊界
Rules 用來控制 Codex 可以在 sandbox 外執行哪些 commands。
這一篇用 10 分鐘換什麼:把 Rules 從"複雜的 DSL"重新理解成三檔命令決策——allow / prompt / forbidden,按風險層級分配。讀完後你寫出來的 .rules 是短的、可測試的、能被 codex execpolicy check 自證的邊界檔案,不是另一個臃腫的 allow list。
Rules 用來控制 Codex 可以在 sandbox 外執行哪些 commands。
Rules 目前是 experimental,未來可能變化。
flowchart LR
SB["1️⃣ sandbox_mode<br/>+ approval_policy"]
Roots["2️⃣ writable roots<br/>named permissions"]
Rules["3️⃣ .rules<br/>command prefix 例外"]
SB --> Roots --> Rules
Rules --> A["allow<br/>低風險只讀"]
Rules --> P["prompt<br/>有副作用"]
Rules --> F["forbidden<br/>不可挽回"]
它解決的是一個很具體的問題:有些命令可以安全地跳過反覆審批,有些命令應該每次提示,有些命令無論如何都不該在 sandbox 外執行。Rules 讓你用可審查的檔案表達這些邊界,而不是靠臨時口頭記憶。
不要把 rules 當成替代 sandbox 的總開關。正常順序是:
- 先用
sandbox_mode和approval_policy定義總體邊界。 - 再用 writable roots 或 named permissions 擴充套件必要目錄。
- 最後用 rules 處理少量 command prefix 例外。
這樣規則檔案才會短、可讀、可測試。
Create a rules file
- 在 active config layer 旁邊的
rules/folder 下建立.rulesfile。例如:
~/.codex/rules/default.rules- 新增 rule。下面示例會在允許
gh pr view跑出 sandbox 前先 prompt:
# Prompt before running commands with the prefix `gh pr view` outside the sandbox.
prefix_rule(
# The prefix to match.
pattern = ["gh", "pr", "view"],
# The action to take when Codex requests to run a matching command.
decision = "prompt",
# Optional rationale for why this rule exists.
justification = "Viewing PRs is allowed with approval",
# `match` and `not_match` are optional "inline unit tests" where you can
# provide examples of commands that should (or should not) match this rule.
match = [
"gh pr view 7888",
"gh pr view --repo openai/codex",
"gh pr view 7888 --json title,body,comments",
],
not_match = [
# Does not match because the `pattern` must be an exact prefix.
"gh pr --repo openai/codex view 7888",
],
)- 重啟 Codex。
Codex 會在 startup 時掃描每個 active config layer 下的 rules/,包括 Team Config locations,以及 user layer:
~/.codex/rules/project-local rules 位於:
<repo>/.codex/rules/只有當 project .codex/ layer 被 trusted 時,project-local rules 才會載入。
你在 TUI 中把 command 加入 allow list 時,Codex 會寫入 user layer:
~/.codex/rules/default.rules這樣未來 runs 可以跳過 prompt。
當 Smart approvals 啟用時,這是預設行為,Codex 可能在 escalation requests 中為你建議 prefix_rule。接受前要認真 review suggested prefix。
Admins 也可以從 requirements.toml enforce restrictive prefix_rule entries。
Understand rule fields
prefix_rule() 支援這些欄位:
| 欄位 | 說明 |
|---|---|
pattern | required。非空 list,定義要匹配的 command prefix。每個 element 可以是 literal string,例如 "pr",也可以是 literal union,例如 ["view", "list"],用於匹配該 argument position 的多個備選。 |
decision | 預設 "allow"。rule 匹配時採取的 action。多個 rules 同時匹配時,Codex 採用最嚴格 decision:forbidden > prompt > allow。 |
justification | optional。非空、人類可讀的 reason。Codex 可能在 approval prompts 或 rejection messages 中顯示它。使用 forbidden 時,適合在 justification 中包含推薦替代方式,例如 "Use \rg` instead of `grep`."`。 |
match / not_match | 預設 []。Codex 載入 rules 時會驗證這些 examples,用來在 rule 生效前發現錯誤。 |
decision 可選值:
| decision | 行為 |
|---|---|
allow | 在 sandbox 外執行 matching command,不 prompt。 |
prompt | 每次 matching invocation 前 prompt。 |
forbidden | 不 prompt,直接 block request。 |
Codex 判斷 command 能否執行時,會把 command 的 argument list 和 pattern 比較。內部會把 command 當作 arguments list 處理,類似 execvp(3) 接收的形式。
Shell wrappers and compound commands
有些 tools 會把多個 shell commands 包在一次 invocation 中,例如:
["bash", "-lc", "git add . && rm -rf /"]這種 command 可以把多個 actions 藏在一個 string 裡。因此 Codex 會特殊處理 bash -lc、bash -c,以及對應的 zsh / sh equivalents。
When Codex can safely split the script
如果 shell script 是 linear chain,並且只包含:
- plain words,也就是沒有 variable expansion、沒有
VAR=...、$FOO、*等 - 透過 safe operators 連線:
&&、||、;或|
Codex 會用 tree-sitter parse 它,並在應用 rules 前拆成 individual commands。
上面的 script 會被視為兩個獨立 commands:
["git", "add", "."]
["rm", "-rf", "/"]然後 Codex 會把每個 command 分別和 rules 比較,並採用最嚴格結果。
即使你 allow pattern=["git", "add"],Codex 也不會自動 allow git add . && rm -rf /,因為 rm -rf / 部分會被單獨評估,並阻止整個 invocation 自動透過。
這能防止 dangerous commands 被夾帶在 safe commands 旁邊。
When Codex does not split the script
如果 script 使用更高階 shell features,Codex 不會嘗試 interpret 或 split。
例子:
- redirection:
>、>>、< - substitutions:
$(...)或 backticks - environment variables:
FOO=bar - wildcard patterns:
*、? - control flow:
if、for、帶 assignments 的&&等
這種情況下,整個 invocation 會被視為一個 command:
["bash", "-lc", "<full script>"]rules 也會應用到這個 single invocation 上。
這種處理方式在可以安全拆分時提供 per-command evaluation;不能安全拆分時,保持 conservative behavior。
推薦規則策略
規則檔案要按風險分層,而不是把所有命令都寫成 allow。
| 場景 | 推薦 decision | 例子 |
|---|---|---|
| 只讀查詢 | allow 或 prompt | git status、gh pr view、npm view。 |
| 對遠端狀態有影響 | prompt | gh pr create、git push、vercel deploy。 |
| 危險刪除或許可權修改 | forbidden | rm -rf /、chmod -R 777、未知 curl pipe shell。 |
| 團隊策略必須統一 | admin requirements | 企業環境中強制禁止或提示。 |
寫 allow 時,prefix 要儘量窄。例如 ["gh", "pr", "view"] 比 ["gh"] 安全得多。寫 forbidden 時,justification 最好給替代方案,因為 Codex 可能把這段 reason 展示在拒絕資訊裡。
一個更貼近工程儲存庫的例子:
prefix_rule(
pattern = ["git", "status"],
decision = "allow",
justification = "Read-only Git inspection is allowed",
match = ["git status", "git status --short"],
)
prefix_rule(
pattern = ["git", "push"],
decision = "prompt",
justification = "Pushing changes affects the remote repository",
match = ["git push", "git push origin main"],
)
prefix_rule(
pattern = ["rm", "-rf", "/"],
decision = "forbidden",
justification = "Do not delete filesystem roots; remove scoped project files instead.",
match = ["rm -rf /"],
)這種寫法的關鍵不是“多寫規則”,而是每條規則都能被 match 和 not_match 自證邊界。
Test a rule file
用 codex execpolicy check 測試 rules 如何應用到 command:
codex execpolicy check --pretty \
--rules ~/.codex/rules/default.rules \
-- gh pr view 7888 --json title,body,comments這個命令會輸出 JSON,顯示 strictest decision,以及匹配到的 rules,包括 matched rules 中的 justification values。
可以用多個 --rules flags 組合多個 files,並加 --pretty 格式化輸出。
排查規則為什麼沒有生效
如果你寫了 rules 但 Codex 仍然提示或仍然阻止,按這個順序查:
- 確認檔案位置在 active config layer 旁邊的
rules/folder。 - 重啟 Codex,因為 rules 在 startup 時掃描。
- 如果是 project-local rules,確認
<repo>/.codex/layer 已被 trusted。 - 用
/debug-config檢視當前配置層和 policy sources。 - 用
codex execpolicy check --pretty對具體命令做最小復現。 - 檢查是不是 shell wrapper 沒被拆分,導致匹配的是
bash -lc <full script>。
如果同一個 command 同時匹配多條規則,Codex 採用最嚴格結果。因此“明明有 allow 還被 prompt/forbidden”通常不是 allow 失效,而是另一條更嚴格的 rule 同時命中。
Understand the rules language
.rules file format 使用 Starlark。語言規範見:
https://github.com/bazelbuild/starlark/blob/master/spec.md
它的語法類似 Python,但設計目標是 safe to run:rules engine 可以無副作用地執行它,例如不會觸碰 filesystem。
完成標準
一套可上線的 rules 配置至少要滿足:
- 每條高風險 allow 都有
match/not_match示例。 - 遠端寫入、部署、釋出、刪除類命令預設
prompt或forbidden。 - rules 檔案可以透過
codex execpolicy check對核心命令做驗證。 - 團隊共享規則放在專案或 Team Config 位置,個人偏好放在
~/.codex/rules/。 - 文件中寫清為什麼某條 command prefix 被允許、提示或禁止。