結論
- Codex CLI に
.envを読ませないには、permission profile(Beta)のdenyを使います。何も設定しない状態や、:workspaceを指定しただけの状態では、.envはそのまま読めました(筆者の環境で確認)。 - 公式ドキュメントの例
"**/*.env" = "deny"だけだと、.env.localは読めました。さらにglob_scan_max_depthより深い階層の.envも読めました(筆者の環境で確認)。 -
.envを一度でもコミットしていると、deny していてもgit show HEAD:.envで中身が出ました(筆者の環境で確認)。 - 設定したら、
codex sandbox -- cat .envがPermission deniedになるかを必ず確かめてください。
この記事は、AIエージェントと秘密情報の話の続きです。AIエージェントに.envを読まれていないか、ファイル名だけで点検する日本語CLIを作った では、Codex について「読める可能性あり」としか言えませんでした。今回はその部分を、実機で埋めます。Claude Code 側の話は Claude Codeに.envを読ませない設定は settings.json の permissions.deny に書く と Claude Codeの会話記録は ~/.claude/projects/ に平文で30日残る にまとめています。
検証環境と範囲
- codex-cli 0.163.0(npm の
@openai/codex) - Debian 13、bubblewrap 0.12.0
- ログインなしで使える
codex sandbox -- <コマンド>(ヘルプの説明は "Run commands within a Codex-provided sandbox")で確認しました。 -
CODEX_HOMEを使い捨てのディレクトリに向け、普段の~/.codexには触れていません。 - 置いたファイルはすべてダミーです(
DUMMY_KEY=dummy-not-a-secretのような値)。検証後に削除しました。
確かめていないこと
- ログインした Codex 本体(エージェントのセッション)が実行するコマンドでの挙動。
codex sandboxと同じ仕組みだと考えていますが、これは推測です。 - macOS(Seatbelt)と Windows。公式によると、Linux と WSL では bubblewrap と seccomp で制限をかけ、macOS では Seatbelt を使います。仕組みが違うので、結果も同じとは限りません。
1. 何も設定しないと、普通に読める
config.toml が空の状態で試しました。
$ codex sandbox -- cat .env
DUMMY_KEY=dummy-not-a-secret
$ codex sandbox -- cat app/.env
DUMMY_KEY=dummy-app
default_permissions = ":workspace" だけを書いた場合も、.env と app/.env は読めました。:workspace は「ワークスペースの中に書き込める」という設定で、読み取りを止めるものではありません(公式: :workspace allows writes inside the active workspace roots and system temp directories)。.gitignore に書いてあるかどうかも関係しません。
2. 全部拒否できた設定
# ~/.codex/config.toml
default_permissions = "no-env"
[permissions.no-env]
extends = ":workspace" # .git などを read-only に保つ既定の保護を引き継ぐ
[permissions.no-env.filesystem]
glob_scan_max_depth = 6 # ** を何階層まで展開するか(1以上)
[permissions.no-env.filesystem.":workspace_roots"]
"**/.env" = "deny"
"**/.env.*" = "deny"
"**/*.env" = "deny"
この設定で試した結果です。
$ codex sandbox -- cat .env
cat: .env: Permission denied
$ codex sandbox -- cat .env.local
cat: .env.local: Permission denied
$ codex sandbox -- cat a/b/c/d/.env
cat: a/b/c/d/.env: Permission denied
$ codex sandbox -- cat README.md
hello
ワークスペース内への新しいファイルの書き込みはできました。拒否されるのは、パターンに合うファイルだけです。
設定するときの注意点です。
-
extendsは書いておくのがおすすめです。公式も、built-in のプロファイルを継承すれば.git、.agents、.codex、.awsを read-only に保てると説明しています。筆者の環境では、extendsなしで独自プロファイルを作ったところ、サンドボックス自体が起動しませんでした。原因は、Codex の実行に必要なパスを読む権限がなかったためだと推測しています。公式の例では":minimal" = "read"を書いています。 -
sandbox_modeや[sandbox_workspace_write]と一緒に書いてはいけません(公式)。sandbox_modeがどこかの設定ファイルにあると、default_permissionsではなく古い設定のほうが使われます。 -
"**/.env.*"は.env.exampleにも当てはまります。筆者の環境でもPermission deniedになりました。サンプルファイルを AI に読ませたいときは、別の名前にするなどの工夫が必要です。 -
glob_scan_max_depthは、数を大きくするほど起動前の走査が増えます(公式)。
3. 抜けたパターン(実機の結果)
| 書き方 | .env |
app/.env |
.env.local |
app/prod.env |
5階層下の .env
|
|---|---|---|---|---|---|
| 設定なし | 読めた | 読めた | 読めた | 読めた | 読めた |
"**/*.env"(公式の例)、depth 3 |
拒否 | 拒否 | 読めた | 拒否 | 読めた |
"**/.env" だけ |
拒否 | 拒否 | 未確認 | 未確認 | 未確認 |
".env"(完全一致) |
拒否 | 読めた | 未確認 | 未確認 | 未確認 |
| 2章の3行、depth 6 | 拒否 | 拒否 | 拒否 | 拒否 | 拒否 |
5階層下は a/b/c/d/.env です。公式の例どおりの設定で試した出力が以下です。
$ codex sandbox -- cat .env
cat: .env: Permission denied
$ codex sandbox -- cat .env.local
DUMMY_KEY=dummy-local
$ codex sandbox -- cat a/b/c/d/.env
DUMMY_KEY=dummy-deep
-
*.envは「.envで終わる名前」なので、.env.localには合いません。 - Linux と WSL では、
**は起動前にglob_scan_max_depthの深さまでしか展開されません(公式)。それより深いファイルは拒否リストに入りませんでした。 -
grep -rで探させた場合も、拒否されたファイルはPermission deniedで飛ばされました。一方で、対象外の.env.localと5階層下の.envは中身が表示されました。
4. それでも残る穴
① コミット済みの .env は、git の履歴から読めた
$ codex sandbox -- git show HEAD:.env
DUMMY_KEY=dummy-not-a-secret
2章の設定でも読めました。.env を拒否しても、.git の中に同じ内容のオブジェクトが残っているためです。extends = ":workspace" は .git を read-only にするだけで、読み取りは禁止しません(公式)。過去に一度でもコミットしたことがあるなら、履歴から消す前に、まず鍵を再発行してください(筆者の提案)。
② 同じプロセスの中で後から作られた .env は読めた
$ codex sandbox -- sh -c 'cat .env; mkdir -p late; echo DUMMY_KEY=dummy-late > late/.env; cat late/.env'
cat: .env: Permission denied
DUMMY_KEY=dummy-late
$ codex sandbox -- cat late/.env
cat: late/.env: Permission denied
公式にも、Linux と WSL では拒否するファイルの一覧を各プロセスの開始時に作ると書かれています。開発サーバーや長く動いているシェルが、起動後に作られた .env を読める点に注意してください。
③ 古い版では効かなかったという報告がある
v0.130.0 で deny のパターンが効かなかったという Issue があります(openai/codex #22179、2026-10-18 時点で open)。0.163.0 では今回効きましたが、どの版から効くようになったかは確かめていません。まず codex --version を確認してください。
5. 確かめ方(30秒)
codex --version
codex sandbox -- cat .env # Permission denied ならOK
codex sandbox -- cat .env.local # 公式の例だけだとここが読める
codex sandbox -- git show HEAD:.env # 中身が出たら、コミット済み
まとめ
- 設定なしや
:workspaceだけでは、.envは読める(筆者の環境で確認)。 - 公式の例
"**/*.env"では、.env.localと深い階層が抜けた(筆者の環境で確認)。**/.env・**/.env.*・**/*.envの3行と、十分なglob_scan_max_depthで全部拒否できた。 - コミット済みの
.envはgit showで読める。鍵の再発行が先。 - 設定後は
codex sandboxで必ず確かめる。
関連記事:
- AIエージェントに.envを読まれていないか、ファイル名だけで点検する日本語CLIを作った
- Claude Codeに.envを読ませない設定は settings.json の permissions.deny に書く
- Claude Codeの会話記録は ~/.claude/projects/ に平文で30日残る
参考(公式):
- Permissions – Codex(Beta。今後変わる可能性があります)
- Configuration Reference – Codex
※ 仕様は 2026-10-18 時点の公式ドキュメントに基づきます。検証は codex-cli 0.163.0 で、Linux の使い捨て環境でのみ行いました。
更新情報やちょっとしたTipsは X(@supportapp3_lab)で発信しています。