---
title: "用 Rules 控制命令边界"
description: "Rules 用来控制 Codex 可以在 sandbox 外运行哪些 commands。"
verifiedAt: "2026-05-07"
---

> [!NOTE]
> **这一篇用 10 分钟换什么**：把 Rules 从"复杂的 DSL"重新理解成**三档命令决策**——`allow` / `prompt` / `forbidden`，按风险层级分配。读完后你写出来的 `.rules` 是短的、可测试的、能被 `codex execpolicy check` 自证的边界文件，不是另一个臃肿的 allow list。

Rules 用来控制 Codex 可以在 sandbox 外运行哪些 commands。

Rules 目前是 experimental，未来可能变化。

```mermaid
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 的总开关。正常顺序是：

1. 先用 `sandbox_mode` 和 `approval_policy` 定义总体边界。
2. 再用 writable roots 或 named permissions 扩展必要目录。
3. 最后用 rules 处理少量 command prefix 例外。

这样规则文件才会短、可读、可测试。

## Create a rules file

1. 在 active config layer 旁边的 `rules/` folder 下创建 `.rules` file。例如：

```text
~/.codex/rules/default.rules
```

2. 添加 rule。下面示例会在允许 `gh pr view` 跑出 sandbox 前先 prompt：

```python
# 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",
    ],
)
```

3. 重启 Codex。

Codex 会在 startup 时扫描每个 active config layer 下的 `rules/`，包括 [Team Config](https://developers.openai.com/codex/enterprise/admin-setup#team-config) locations，以及 user layer：

```text
~/.codex/rules/
```

project-local rules 位于：

```text
<repo>/.codex/rules/
```

只有当 project `.codex/` layer 被 trusted 时，project-local rules 才会加载。

你在 TUI 中把 command 加入 allow list 时，Codex 会写入 user layer：

```text
~/.codex/rules/default.rules
```

这样未来 runs 可以跳过 prompt。

当 Smart approvals 启用时，这是默认行为，Codex 可能在 escalation requests 中为你建议 `prefix_rule`。接受前要认真 review suggested prefix。

Admins 也可以从 [`requirements.toml`](https://developers.openai.com/codex/enterprise/managed-configuration#admin-enforced-requirements-requirementstoml) 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 中，例如：

```text
["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：

```text
["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：

```text
["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 展示在拒绝信息里。

一个更贴近工程仓库的例子：

```python
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：

```shell
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 仍然提示或仍然阻止，按这个顺序查：

1. 确认文件位置在 active config layer 旁边的 `rules/` folder。
2. 重启 Codex，因为 rules 在 startup 时扫描。
3. 如果是 project-local rules，确认 `<repo>/.codex/` layer 已被 trusted。
4. 用 `/debug-config` 查看当前配置层和 policy sources。
5. 用 `codex execpolicy check --pretty` 对具体命令做最小复现。
6. 检查是不是 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](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 被允许、提示或禁止。

## 官方资料

- [Rules](https://developers.openai.com/codex/rules)
- [Sandbox](https://developers.openai.com/codex/concepts/sandboxing)
- [Configuration reference](https://developers.openai.com/codex/config-reference)
- [Admin setup](https://developers.openai.com/codex/enterprise/admin-setup)

## 接下来去哪

<Cards>
  <Card title="Sandbox 边界" href="/docs/codex/official/02-config-security/49-sandbox-boundaries" description="rules 是 sandbox 的例外层，先理顺主层" />
  <Card title="批准与安全模式" href="/docs/codex/official/02-config-security/07-approval-security" description="rules 与 approval 怎么配合" />
  <Card title="基础配置" href="/docs/codex/official/02-config-security/06-basic-config" description="config.toml 是规则的总入口" />
  <Card title="自定义行为" href="/docs/codex/official/02-config-security/48-customize-behavior" description="把规则与项目偏好编排到一起" />
  <Card title="Managed config" href="/docs/codex/official/06-team-integration/55-managed-config" description="企业用 requirements.toml 强制 prefix_rule" />
</Cards>
