はじめに
普段はClaude Codeを使っており、.claude/settings.json の permissions に手動承認なしで実行できるツールやコマンドを設定しています。
最近Codexにも入門したので、同じように「このコマンドは毎回確認しなくてよい」という設定ができないか調べてみました。
結論
結論として、Codexでは rules/ 配下に .rules ファイルを作成し、prefix_rule() でサンドボックス外での実行を自動承認したいコマンドの接頭辞を定義します。
CodexのRulesは公式ドキュメント上でexperimentalとされています。今後仕様が変わる可能性があるため、この記事の内容は2026年5月6日時点の確認内容として読んでください。
Claude Codeの場合
Claude Codeでは、公式ドキュメント上でも settings.json が設定ファイルとして案内されています。
ユーザー全体に効く設定は ~/.claude/settings.json、プロジェクトで共有する設定は .claude/settings.json、個人用のローカル設定は .claude/settings.local.json に書く形です。
例えば、PRの内容確認で使う gh pr view を許可する場合は以下のようなイメージです。
{
"permissions": {
"allow": [
"Bash(gh pr view:*)"
],
"ask": [
"Bash(git push:*)"
],
"deny": [
"Bash(rm -rf:*)",
"Bash(sudo:*)",
"Read(.env)"
]
}
}
指定されていないツールについては設定されている権限モードに従って処理されます。私は default の設定のため、ask を明示的に書かなくても記載がないツールは確認が必要になります。そのため、現在は ask の設定はしておりません。
CodexのRulesとは
CodexのRulesは、Codexがサンドボックス外で実行しようとするコマンドを制御する仕組みです。MCPツールやアプリ連携ツール全般ではなく、コマンド実行に対する例外ルールとして考えると分かりやすいです。allow / prompt / forbidden で承認の判断が変わります。
簡単にまとめると、以下の整理になります。
| 処理 | Claude Code | Codex |
|---|---|---|
| 自動承認 | allow | allow |
| 確認を求める | ask | prompt |
| 拒否 | deny | forbidden |
Codexで明記がされていないコマンドの実行時は、sandbox_mode や approval_policy の設定により変わります。
| 内容 | 説明 |
|---|---|
| sandbox_mode | 読み取りのみ許可(read-only)、プロジェクト内は読み込み書き込み許可(workspace-write)、フルアクセス(danger-full-access)の設定ができます |
| approval_policy | 必要なときに承認が発生する on-request、承認が発生しない never、信頼できるセット以外のコマンドを実行時に承認が発生する untrusted、カテゴリごとに制御する { granular = { ... } } 形式があります |
untrusted における、信頼できるコマンドがなんなのかは特に記載を見つけられませんでした。ユーザーが編集できるものでもなさそうなので、Codex内部でなんらかの設定がありそうです。
prefix_ruleを書いてみる
公式ドキュメントでは、アクティブな設定レイヤーの横に rules/ ディレクトリを作成し、その中に .rules ファイルを置くと説明されています。
ユーザー全体に適用したい場合は、以下のようなパスになります。
~/.codex/rules/default.rules
プロジェクト単位で管理したい場合は、リポジトリ内に置くこともできます。
<repo>/.codex/rules/default.rules
.rules ファイルはPythonに似た構文ですが、実際にはStarlark形式で書きます。
以下は、gh pr view コマンドを自動承認し、git push は毎回確認、rm -rf は拒否する例です。
prefix_rule(
pattern = ["gh", "pr", "view"],
decision = "allow",
justification = "PR内容の確認用コマンドのため自動実行を許可する",
match = [
"gh pr view 61",
"gh pr view --repo owner/repo",
"gh pr view 61 --json title,body,comments",
],
not_match = [
"gh pr --repo owner/repo view 61",
"gh pr list",
],
)
# pushは毎回確認する
prefix_rule(
pattern = ["git", "push"],
decision = "prompt",
justification = "リモートリポジトリへ変更を送るため確認する",
match = [
"git push origin main",
],
)
# 危険な削除は拒否する
prefix_rule(
pattern = ["rm", "-rf"],
decision = "forbidden",
justification = "削除範囲を確認できる別の方法を使う",
match = [
"rm -rf node_modules",
],
)
設定後はCodexを再起動します。
prefix_ruleの基本
prefix_rule() でよく使われるフィールドは以下です。
| フィールド | 必須 | 設定する内容 | 例 | 補足 |
|---|---|---|---|---|
pattern |
必須 | コマンドの先頭から一致させる引数リスト | ["gh", "pr", "view"] |
文字列全体ではなく、コマンドを空白で分割した引数の並びとして考えます |
decision |
任意 | 一致したときの判定 | "allow" |
allow / prompt / forbidden のいずれかです。省略した場合は allow になります |
justification |
任意 | そのルールを設定する理由 | "PR内容の確認用コマンドのため許可する" |
承認プロンプトや拒否メッセージに表示される場合があるため、あとから見ても分かる説明を書いておくとよさそうです |
match |
任意 | このルールに一致してほしいコマンド例 | ["gh pr view 61"] |
インラインのテストケースです。ルール読み込み時に検証されます |
not_match |
任意 | このルールに一致してほしくないコマンド例 | ["gh pr list"] |
意図しない広すぎるルールを防ぎやすくなります |
同時に複数のルールに一致した場合は、より制限の強い判定が優先されます。優先度は forbidden > prompt > allow です。
注意点として、pattern = ["gh"] は gh pr view だけではなく、gh pr list や gh repo view のように gh から始まるコマンドにも一致します。特定のサブコマンドだけを許可したい場合は、広い ["gh"] のルールを書かず、次のように引数まで含めて指定します。
pattern = ["gh", "pr", "view"]
このルールは、以下には一致します。
gh pr view 123
gh pr view --repo openai/codex
一方、以下には一致しません。
gh pr --repo openai/codex view 123
pattern は「含まれていたらOK」ではなく「先頭から完全に一致する接頭辞」と考えると分かりやすいです。
複数候補をまとめたい場合
同じ位置に複数候補を持たせたい場合は、配列の中に配列を書きます。
prefix_rule(
pattern = ["ls", ["-la", "-lh", "-lt"]],
decision = "allow",
justification = "よく使うlsのオプションを許可する",
)
これで以下のようなコマンドに一致します。
ls -la
ls -lh
ls -lt
ルールをテストする
Rulesファイルは codex execpolicy check でテストできます。
codex execpolicy check --pretty \
--rules ~/.codex/rules/default.rules \
-- gh pr view 61
公式ドキュメントでは、出力はJSONで、最終的な判定や一致したルールの justification などを確認できると説明されています。
Rulesを書いたら、Codexを再起動する前にこのコマンドで確認しておくと安心です。
シェル経由のコマンドには注意
Codexでは、bash -lc や zsh -c のようにシェルを経由するコマンドが特別扱いされます。
例えば以下のようなコマンドです。
bash -lc "git add . && rm -rf /"
公式ドキュメントによると、単純な単語と安全な演算子(&&, ||, ;, |)だけで構成されている場合、Codexは中身を分解して個別にルール判定します。
上の例であれば、概念的には以下の2つとして評価されます。
["git", "add", "."]
["rm", "-rf", "/"]
そのため、仮に git add を許可していても、後半の rm -rf / が拒否されれば全体は自動承認されません。
一方で、リダイレクト、環境変数、ワイルドカード、コマンド置換、制御構文などを含む複雑なシェルスクリプトは、安全に分解せず、["bash", "-lc", "<full script>"] のような1つの呼び出しとして扱われます。
この仕様があるため、Rulesに登録するコマンドはできるだけシンプルな形にしておくのがよさそうです。
実際に設定してみる
設定前は以下の通りです。コマンド実行に承認が必要になります。
> gh pr view 61 を実行して
• 了解です。まず作業開始ルールどおり git status --short を確認してから、gh pr view 61 を実行します。
• Ran git status --short
└ (no output)
(中略)
• Running gh pr view 61
Would you like to run the following command?
Reason: GitHub API に接続して PR #61 の内容を取得してもよいですか?
$ gh pr view 61
› 1. Yes, proceed (y)
2. Yes, and don't ask again for commands that start with `gh pr view` (p)
3. No, and tell Codex what to do differently (esc)
以下のRulesを設定します。
prefix_rule(
pattern = ["gh", "pr", "view"],
decision = "allow",
justification = "PR details can be viewed without approval",
match = [
"gh pr view 61",
"gh pr view --repo owner/repo",
"gh pr view 61 --json title,body,comments",
],
not_match = [
"gh pr --repo owner/repo view 61",
"gh pr list",
],
)
再起動後、同様の質問をしてみます。
› gh pr view 61 を実行して
• gh pr view 61 を実行して、結果の要点を日本語で共有します。
• Ran gh pr view 61
└ GraphQL: Resource not accessible by personal access token (repository.pullRequest.statusCheckRollup.nodes.0.commit.statusCheckRollup.contexts.nodes.0), Resource not accessible by personal
access token (repository.pullRequest.statusCheckRollup.nodes.0.commit.statusCheckRollup.contexts.nodes.1), Resource not accessible by personal access token
(repository.pullRequest.statusCheckRollup.nodes.0.commit.statusCheckRollup.contexts.nodes.2)
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
• 通常表示はステータスチェック情報の取得で PAT 権限に引っかかりました。PR本文など権限不要の項目だけに絞って、内容を取れるか試します。
• Ran gh pr view 61 --json number,title,state,author,headRefName,baseRefName,url,body,isDraft,mergeable,reviewDecision,createdAt,updatedAt
└ {"author":{"id":"U_xxxxxxxxxx","is_bot":false,"login":"example-user","name":"Example User"},"baseRefName":"main","body":"- サンプル機能を追加\n- 関連ドキュメントを更新\n- (#60)","updatedAt":"2026-05-01T10:09:04Z","url":"XXXXXXXXXXXXXXXXXXXXXX"}
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
• gh pr view 61 は実行しましたが、PAT の権限不足でステータスチェック情報の取得に失敗しました。
権限不要の項目に絞って再取得した結果です。
- PR: #61
- タイトル: サンプル機能を追加 (#60)
- 状態: OPEN
- Draft: false
- mergeable: CONFLICTING
- base: main
- head: feature/sample-update
- URL: XXXXXXXXXXXXXXXXXXXXXX
本文の概要:
- サンプル機能を追加
- 関連ドキュメントを更新
- 動作確認の内容を追記
一部、PATの権限不足によるエラーは出ていますが、承認なしで gh pr view が実行されました!
まとめ
今回、Codexに入門するにあたりClaude Codeで設定していた項目を適用しました。記載方法は異なるものの、考え方は似ている部分もありさほど難しくはなかったです。今後もClaude CodeとCodexの二刀流で色々検証したいと思います。
参考