Permissions
概要
ローカルで実行されるコマンドに最小権限の境界を与える仕組み。permission profile は Beta で、活発に開発中であり変わりうると公式に明記されている。profile は filesystem ルール(何を読み書きできるか)と network ルール(どの宛先に到達できるか)を組み合わせた名前付きポリシー。
このページは 2 つのドキュメントセクション(permission mode の UI 説明と、permission profile の仕様)を扱う。permission profile に関する記述はすべて Beta 扱い。
仕様
permission mode(UI 側の説明)
- permissions は、ChatGPT(desktop app)と Codex(CLI / IDE)がファイル編集・コマンド実行・インターネット利用といったローカルのアクションをどう扱うかを制御する
- ほとんどの作業では Ask for approval から始めることが推奨されている。現在のワークスペース内で作業し、その境界を越える前に一時停止する
- ChatGPT desktop app の初回利用時は、アプリ設定でモードを有効にする必要がある
- Ask for approval は常に利用できる
- Approve for me(設定上の名称は Auto-review)と Full access をメニューに出すには、Settings > General の Permissions で有効にする
- モードを有効にしてもメニューに出るだけで、そのモードが選択されたり既存のチャットが変わったりはしない
- 利用できるモードはローカル設定と組織の requirements に依存する。 許可されていないモードは無効表示になる
- sandbox がアクセスできるファイルとネットワークを定め、approvals が一時停止するか自動レビューに送るかを決める
- 誰がレビューするかを変えても sandbox は広がらない。 例えば Approve for me は Ask for approval と同じワークスペース境界を保ち、境界を越える要求を自動レビューに送るだけ
- CLI では
/permissionsを使う
permission profile と旧 sandbox 設定の関係(重要)
- permission profile は旧来の sandbox 設定と組み合わせられない。
default_permissionsと[permissions]を使うか、sandbox_mode/sandbox_workspace_writeを使うかのどちらかで、両方は使えない - 読み込まれたいずれかの config ファイルに
sandbox_modeがあるか、--sandboxを渡したか、選択した config profile がsandbox_modeを設定している場合、Codex はdefault_permissionsではなく旧来の sandbox 設定を使う - 例外は managed の
allowed_permission_profiles。これがあると Codex は permission profile を使う。managed の profile allowlist を配る前にsandbox_modeや[sandbox_workspace_write]などの旧設定を消しておく - バージョンが混在するエンタープライズ展開では、すべてのクライアントが Codex 0.138.0 以降になるまで、managed の
allowed_sandbox_modesrequirement を一時的な互換制約として残せる
組み込み profile
| profile | 内容 |
|---|---|
:read-only | ローカルコマンドの実行を read-only に保つ |
:workspace | 有効な workspace root とシステムの temp ディレクトリ内への書き込みを許す |
:danger-full-access | ローカルの sandbox 制限を外す。広いアクセスを意図する場合にのみ使う |
- ローカルの permission profile は macOS、Linux、WSL、Windows ネイティブで対応している
- エンタープライズ管理者は managed
requirements.tomlで profile を定義し、ユーザーが選べる profile を制限できる。allowed_permission_profilesがあると、そこに書かれていない profile はすべて拒否される(省略された組み込みや、将来の Codex バージョンで追加される profile も含む)
profile の定義
[permissions.<name>]で名前付き profile を作り、トップレベルのdefault_permissionsにその名前か組み込み名を設定する[permissions.<name>.workspace_roots]は、その profile で workspace root として扱う具体的なディレクトリを足す[permissions.<name>.filesystem.":workspace_roots"]は、有効なすべての workspace root(現在のセッションのランタイム workspace root + profile が定義した root)の内側に適用する filesystem ルールを定める- profile も通常の config レイヤーモデルに従う。優先度の高いレイヤーは、profile 全体を書き直さずに同じ profile 名のエントリを追加・置換できる
extends
- 組み込みまたは他の名前付き profile とほぼ同じ場合に使う。ベースラインの保護を引き継ぐため、ゼロから始めるより組み込みの拡張が推奨されている
- 例えば
:workspaceを拡張すると、明示的に上書きしない限り workspace root の.codexディレクトリは read-only のまま :read-only、:workspace、他の名前付き profile を拡張できる。:danger-full-accessは拡張できない。未知の親と継承の循環も拒否されるdescriptionはextendsで親から継承されない
設定項目
| エントリ | 型 / 値 | 既定 | 内容 |
|---|---|---|---|
default_permissions | profile 名の文字列 | なし | 既定で適用する profile。[permissions] 配下の profile か :workspace のような組み込みと一致する必要がある。managed requirements が :workspace と :read-only の両方を明示的に許可している場合にのみ省略しうる |
[permissions.<name>] | テーブル | なし | 名前付き profile を定義する |
permissions.<name>.description | 文字列 | なし | 人間向けの説明 |
permissions.<name>.extends | profile 名の文字列 | なし | 他の名前付き profile、または :read-only / :workspace から始める |
[permissions.<name>.workspace_roots] | テーブル | なし | profile が定義する workspace root を足す |
permissions.<name>.workspace_roots."<path>" | 真偽値 | false | true のときそのパスを profile の workspace root 集合に加える。false のエントリは無効のまま |
[permissions.<name>.filesystem] | テーブル | なし | パスをアクセス値またはスコープ付きサブパスマップに対応づける。テーブルが無い/空のときは filesystem アクセスを制限したままにし、起動時に警告を出す |
permissions.<name>.filesystem.glob_scan_max_depth | 数値 | なし | Linux / WSL / Windows ネイティブで、sandbox 起動前に一致をスナップショットするときの deny-read glob 展開を制限する。大きい値は起動時のスキャン負荷を増やす。境界の無い ** パターンには最低 1 を使う |
[permissions.<name>.filesystem]."<path>" | read / write / deny | なし | 対応パスへの直接のアクセス。deny は同じ具体度の write / read に勝つ。有効なランタイムが強制できない直接の write ルールは拒否される |
[permissions.<name>.filesystem."<path>"]."<subpath>" | read / write / deny | なし | <path> の子孫へのアクセス。ベースパスには . を使う。他のサブパスは相対の子孫でなければならず、. や .. のコンポーネントを含められない |
[permissions.<name>.network] | テーブル | なし | profile のネットワーク sandbox proxy と sandbox network policy |
permissions.<name>.network.enabled | 真偽値 | false | sandbox 化されたコマンドのネットワークアクセスを有効にする。sandbox の network policy を変えるだけで、それ自体が network proxy を起動するわけではない |
[permissions.<name>.network.domains] | テーブル | なし | ホストパターンを allow / deny に対応づける。allow エントリが無ければドメインへのリクエストはブロックされる。deny が allow を上書きする |
permissions.<name>.network.domains."<pattern>" | allow / deny | なし | 完全ホスト、*.example.com(サブドメインのみ)、**.example.com(apex +サブドメイン)、*(allow 専用のグローバルワイルドカード)。ホストパターンはトリム・小文字化・末尾ドット除去・単純なポートや括弧の除去で正規化される |
[permissions.<name>.network.unix_sockets] | テーブル | なし | Unix socket allowlist の上書き。Docker のようなローカル連携でのみ使う |
permissions.<name>.network.unix_sockets."<path>" | allow / deny | なし | 絶対 Unix socket パスを allowlist に追加/拒否する。拒否されたエントリは有効な allowlist から外れる |
permissions.<name>.network.proxy_url | URL 文字列 | http://127.0.0.1:3128 | HTTP_PROXY / HTTPS_PROXY / websocket proxy 変数などに使う HTTP proxy listener |
permissions.<name>.network.enable_socks5 | 真偽値 | true | ALL_PROXY と FTP proxy 変数に使う SOCKS5 listener を有効にする |
permissions.<name>.network.socks_url | URL 文字列 | http://127.0.0.1:8081 | SOCKS5 listener のアドレス |
permissions.<name>.network.enable_socks5_udp | 真偽値 | true | SOCKS5 listener が有効なとき UDP をサポートする |
permissions.<name>.network.allow_upstream_proxy | 真偽値 | true | outbound リクエストで upstream の HTTP(S)_PROXY / ALL_PROXY を尊重する |
permissions.<name>.network.allow_local_binding | 真偽値 | false | true でローカル/プライベートネットワークのガードを無効化する。false のときは localhost や 127.0.0.1 などの正確なリテラルを明示的に allowlist する必要があり、ローカル/プライベート IP に解決されるホスト名はブロックされたまま |
permissions.<name>.network.dangerously_allow_non_loopback_proxy | 真偽値 | false | proxy listener を非 loopback アドレスにバインドさせる。通常のローカル開発では未設定のままにする |
permissions.<name>.network.dangerously_allow_all_unix_sockets | 真偽値 | false | Unix socket allowlist を迂回する。広いローカル escape hatch |
filesystem のアクセス値
| 値 | 意味 |
|---|---|
read | そのパス配下のファイル読み取りとディレクトリ一覧を許す。作成・変更・改名・削除はできない |
write | そのパス配下の読み取りと変更を許す。OS が許すなら作成・改名・削除も含む |
deny | そのパス配下の読み書きを両方拒否する。広い read / write の中から拒否するサブパスを切り出すのに使う |
- より具体的なエントリが広いエントリを上書きする。同じパスを指す 2 つのエントリでは
deny>write>read - 広い deny の中で、より具体的なパスにより狭い部分木を再度開くこともできる
- 有効な profile の内側では、広いパスが読み書き可能でも、より狭い deny ルールは効き続ける
パスの書き方
| パス | 意味 | スコープ付きサブパス |
|---|---|---|
:root | ファイルシステムのルート | . のみ |
:minimal | よく使うツールが必要とするプラットフォーム/ランタイムのパス | . のみ |
:workspace_roots | 現在のセッションの workspace root +有効な profile 定義の workspace root | 可 |
:tmpdir | $TMPDIR の場所(存在する場合) | . のみ |
:slash_tmp | /tmp フォルダ(存在する場合) | . のみ |
/absolute/path | プラットフォームの絶対パス(macOS/Linux/WSL の /path、Windows ネイティブの C:\path) | 可 |
~/path | 現在のユーザーのホーム配下のパス | 可 |
- Windows ネイティブでは、ホーム相対パスにバックスラッシュも使える(
~\work) - Windows ネイティブでは、ドライブレターのパス(
D:\work)と UNC パス(\\server\share)を絶対パスとして扱える :workspace_roots配下のネストしたサブパスは workspace root の内側に留まる必要がある。../other-repoのような親への遡上は拒否される
deny と glob
- 近くの広いルールがアクセスを与えていても、読ませたくないファイル/部分木には
denyを使う。~/.sshのような安定した場所には正確なパス、リポジトリごとに位置が変わる機微ファイル群には glob が向く :workspace_roots配下の glob は、有効な workspace root ごとの相対として解釈されるdenyの glob パターンは deny-read ルールとして対応している。read/writeの glob は Linux / WSL / Windows ネイティブの sandbox で移植性が低いため、可能なら正確なパスや"docs/**" = "read"のような部分木ルールを使う- Linux / WSL / Windows ネイティブでは、境界の無い
**の deny-read パターンは sandbox 起動前に境界付きの事前展開が必要になることがある。"**/*.env" = "deny"のようなパターンではglob_scan_max_depthを設定する glob_scan_max_depthは最低1。値を上げると sandbox 起動前により深くスキャンし、Linux / WSL / Windows ネイティブでは起動時の負荷が増える。境界付き展開を使いたくない場合は*.env、*/*.env、*/*/*.envのように深さを列挙する
network permissions
enabled = trueでその profile のネットワークアクセスを許可する。有効にすると既定ではフルのネットワーク挙動になるため、ほとんどの profile はドメインルールも定義すべきとされている- ネットワーク sandbox proxy は既定でローカル listener にバインドされる。特定のランタイムと統合する場合を除き、listener 設定は既定のままにする
dangerously_*のネットワークキーは特殊環境向けの escape hatch であり、通常のローカル開発で使うべきではない- DNS rebinding とローカルサービスへの偶発アクセスへの防御として、既定でローカル/プライベートネットワークのガードが適用される。意図的に許すには正確なホストまたは IP リテラルを allowlist する
allow_local_binding = trueは、ローカル/プライベートアドレスに解決される allowlist 済みホスト名に到達する必要があるときにだけ設定する- Unix socket proxying は Docker などのためのローカル escape hatch。
denyは継承された allow エントリも含めて socket パスを拒否する。Unix socket を有効にするときは proxy listener を loopback にバインドしたままにする
強制の仕組み
| プラットフォーム | 強制 |
|---|---|
| macOS | Seatbelt sandbox profile。選択したポリシーをプラットフォーム sandbox が強制できない場合、黙って sandbox 無しで実行するのではなくコマンドの実行を拒否する |
| Linux / WSL | bubblewrap + seccomp。互換のフォールバック経路として Landlock が使える。最も強い強制経路は user namespace とカーネルのサポートに依存し、制限されたコンテナホストでは互換経路に落ちる。未対応の split ポリシーは拒否される |
| Windows ネイティブ | elevated sandboxing が最も強い(専用の低特権 sandbox ユーザー、ファイルシステムの権限境界、ファイアウォールルールを使える)。unelevated はネットワーク隔離が弱く、すべての読み書き分割の carve-out を強制できないフォールバックで、未対応のポリシーは拒否される。Linux sandbox モデルが必要なら WSL を使う |
profile が制御する範囲
- ローカルのコマンド実行のみ。connector、MCP サーバー、browser / computer-use の各サーフェス、Codex cloud の環境設定、承認された escalation はそれぞれ独自の制御を使う
- write 可能な profile は永続的な変更を作れる。スクリプト、ビルド手順、パッケージマネージャの hook、シェルの起動ファイル、共有ディレクトリへの書き込みは、後で別のツールやユーザーが元の sandbox の外で実行しうるため機微として扱う
- ネットワークのドメインルールは、network proxy を通る sandbox コマンドの通信先を制約する。許可した宛先が信頼できるかどうかを決めるものではなく、ワイルドカードの allow は広いまま
- ローカル/プライベートネットワークの宛先は既定でブロックされる
設定
default_permissions = "project-edit"
[permissions.project-edit.workspace_roots]
"~/code/app" = true
"~/code/shared-lib" = true
[permissions.project-edit.filesystem]
":minimal" = "read"
[permissions.project-edit.filesystem.":workspace_roots"]
"." = "write"
".devcontainer" = "read"
"**/*.env" = "deny"
[permissions.project-edit.network]
enabled = true
[permissions.project-edit.network.domains]
"api.openai.com" = "allow"
"*.github.com" = "allow"
"tracking.example.com" = "deny"
# 組み込みを拡張する
default_permissions = "project-edit"
[permissions.project-edit]
description = "Project editing with OpenAI API access."
extends = ":workspace"
[permissions.project-edit.filesystem.":workspace_roots"]
"**/*.env" = "deny"
# ワークスペースだけ書き込み可、他はすべて読み取り拒否
default_permissions = "workspace-only"
[permissions.workspace-only]
extends = ":workspace"
[permissions.workspace-only.filesystem]
":root" = "deny"
":minimal" = "read"
":tmpdir" = "deny"
":slash_tmp" = "deny"
# 境界の無い glob には glob_scan_max_depth を併用する
[permissions.project-edit.filesystem]
glob_scan_max_depth = 3
[permissions.project-edit.filesystem.":workspace_roots"]
"**/*.env" = "deny"
制約・注意点
- permission profile は Beta。仕様は変わりうる
- 1 セッションでは permission profile か旧 sandbox 設定のどちらか一方を使う
- 書き込みや outbound ネットワークを許すときは、タスクが完了する最も狭い profile を選ぶ。approval policy、秘密情報の扱い、allow ルールをそのアクセス水準に合わせる
- 組織の managed requirements は制限を追加でき、ユーザー設定でそれを緩めるべきではない
- グローバルな
"*"の allow ルールは、パブリックネットワークアクセスを意図する場合にのみ使う
関連
facts/codex/sandbox.mdfacts/codex/approvals-and-security.mdfacts/codex/configuration-reference.mdfacts/codex/config-basics.md