Motivation
Sigil's Codex parser reads ~/.codex/config.toml and treats approval_policy / trust_level as its autonomy signals. Codex has since layered its configuration and added new approval surfaces, so a single-file read now misses config that actually governs the session. Verified against openai/codex main (codex-rs/config/src/loader/mod.rs, config_requirements.rs, mcp_types.rs) and https://learn.chatgpt.com/docs/config-file/config-reference , plus this machine running codex-cli 0.137.0.
Gaps
1. approval_policy is no longer always a string. Besides "untrusted" | "on-request" | "never" it accepts a table: { granular = { sandbox_approval, rules, mcp_elicitations, request_permissions, skill_approval } }. A parser assuming a scalar either misses it or errors. ("on-failure" is now documented as deprecated.)
2. Config is a layer stack, not a file. Ascending precedence: platform managed prefs → /etc/codex/config.toml (or %ProgramData%\OpenAI\Codex\config.toml) → enterprise bundle → ${CODEX_HOME}/config.toml → profile ${CODEX_HOME}/<name>.config.toml → ${PWD}/config.toml → ./.codex/config.toml walking up to the git root. Project-local layers are skipped for untrusted dirs, and the project-local denylist covers openai_base_url, model_provider(s), notify, profile(s), otel — but not mcp_servers, hooks, or approval_policy. So a cloned repo can contribute MCP servers and lifecycle hooks. That is the same shape as the Amazon Q issue (CVE-2026-12957), where a workspace-supplied .amazonq/mcp.json auto-loaded without consent. Sigil should read the layers it can and report which contributed a finding.
3. New file: ~/.codex/rules/*.rules. Confirmed present on this machine as ~/.codex/rules/default.rules containing a command-approval DSL:
prefix_rule(pattern=["codex", "mcp", "login"], decision="allow")
A decision="allow" entry on a broad or dangerous prefix is a persistent auto-approval that never prompts — readable, and squarely in the same family as defaultMode/approval_policy. Needs a small parser for the DSL (or at minimum, extraction of decision="allow" prefixes).
4. codex remote-control — headless app-server orchestration with daemon start/stop and pairing, i.e. the CLI can be driven unattended from elsewhere. The admin constraint is allow_remote_control in requirements.toml. Pairing/daemon state on disk is a candidate detection surface (exact location not yet verified — needs hardware confirmation before any rule is written).
5. requirements.toml (/etc/codex/, %ProgramData%\OpenAI\Codex\) — admin-enforceable constraints including approval_policy, permission_profile, allow_managed_hooks_only, allow_remote_control, mcp_servers, plugins, marketplaces, exec_policy, network, filesystem. Presence is a hardening signal worth reporting positively.
6. Lifecycle hooks in Codex config — events PreToolUse, PermissionRequest, PostToolUse, PreCompact, PostCompact, SessionStart, SubagentStart, SubagentStop, UserPromptSubmit, Stop; discovered per config layer in both TOML and JSON folder form, including plugin-provided hooks. Two consequences: repo-local hooks are an injection surface to flag, and this is also where a Codex enforcement adapter would eventually attach. (The key was renamed features.codex_hooks → features.hooks.)
7. MCP per-server config grew — bearer_token / bearer_token_env_var (plaintext credentials in config), auth, enabled_tools/disabled_tools, and per-tool approval_mode. default_tools_approval_mode is auto | prompt | writes | approve with serde default Auto. Note writes mode keys off readOnlyHint, which is server-supplied metadata — a poisoned tool can declare itself read-only to skip approval. That detection belongs with the tool-metadata work (see the #148 follow-up issue), but the config-side signal (writes mode in use) is readable here.
8. /import migrates settings, MCP servers, and plugins from Cursor and Claude Code, so a finding in one agent's config can propagate into Codex. Worth noting in remediation text rather than a separate check.
Scope
Mechanism only. Codex parser: tolerate the table form of approval_policy, walk the layer stack, add the rules DSL source, surface requirements.toml as a hardening signal, and record which layer produced each finding. Remote-control detection is gated on hardware verification of where its state lands.
Motivation
Sigil's Codex parser reads
~/.codex/config.tomland treatsapproval_policy/trust_levelas its autonomy signals. Codex has since layered its configuration and added new approval surfaces, so a single-file read now misses config that actually governs the session. Verified againstopenai/codexmain (codex-rs/config/src/loader/mod.rs,config_requirements.rs,mcp_types.rs) and https://learn.chatgpt.com/docs/config-file/config-reference , plus this machine running codex-cli 0.137.0.Gaps
1.
approval_policyis no longer always a string. Besides"untrusted" | "on-request" | "never"it accepts a table:{ granular = { sandbox_approval, rules, mcp_elicitations, request_permissions, skill_approval } }. A parser assuming a scalar either misses it or errors. ("on-failure"is now documented as deprecated.)2. Config is a layer stack, not a file. Ascending precedence: platform managed prefs →
/etc/codex/config.toml(or%ProgramData%\OpenAI\Codex\config.toml) → enterprise bundle →${CODEX_HOME}/config.toml→ profile${CODEX_HOME}/<name>.config.toml→${PWD}/config.toml→./.codex/config.tomlwalking up to the git root. Project-local layers are skipped for untrusted dirs, and the project-local denylist coversopenai_base_url,model_provider(s),notify,profile(s),otel— but notmcp_servers,hooks, orapproval_policy. So a cloned repo can contribute MCP servers and lifecycle hooks. That is the same shape as the Amazon Q issue (CVE-2026-12957), where a workspace-supplied.amazonq/mcp.jsonauto-loaded without consent. Sigil should read the layers it can and report which contributed a finding.3. New file:
~/.codex/rules/*.rules. Confirmed present on this machine as~/.codex/rules/default.rulescontaining a command-approval DSL:A
decision="allow"entry on a broad or dangerous prefix is a persistent auto-approval that never prompts — readable, and squarely in the same family asdefaultMode/approval_policy. Needs a small parser for the DSL (or at minimum, extraction ofdecision="allow"prefixes).4.
codex remote-control— headless app-server orchestration with daemon start/stop and pairing, i.e. the CLI can be driven unattended from elsewhere. The admin constraint isallow_remote_controlinrequirements.toml. Pairing/daemon state on disk is a candidate detection surface (exact location not yet verified — needs hardware confirmation before any rule is written).5.
requirements.toml(/etc/codex/,%ProgramData%\OpenAI\Codex\) — admin-enforceable constraints includingapproval_policy,permission_profile,allow_managed_hooks_only,allow_remote_control,mcp_servers,plugins,marketplaces,exec_policy,network,filesystem. Presence is a hardening signal worth reporting positively.6. Lifecycle hooks in Codex config — events
PreToolUse,PermissionRequest,PostToolUse,PreCompact,PostCompact,SessionStart,SubagentStart,SubagentStop,UserPromptSubmit,Stop; discovered per config layer in both TOML and JSON folder form, including plugin-provided hooks. Two consequences: repo-local hooks are an injection surface to flag, and this is also where a Codex enforcement adapter would eventually attach. (The key was renamedfeatures.codex_hooks→features.hooks.)7. MCP per-server config grew —
bearer_token/bearer_token_env_var(plaintext credentials in config),auth,enabled_tools/disabled_tools, and per-toolapproval_mode.default_tools_approval_modeisauto | prompt | writes | approvewith serde defaultAuto. Notewritesmode keys offreadOnlyHint, which is server-supplied metadata — a poisoned tool can declare itself read-only to skip approval. That detection belongs with the tool-metadata work (see the #148 follow-up issue), but the config-side signal (writesmode in use) is readable here.8.
/importmigrates settings, MCP servers, and plugins from Cursor and Claude Code, so a finding in one agent's config can propagate into Codex. Worth noting in remediation text rather than a separate check.Scope
Mechanism only. Codex parser: tolerate the table form of
approval_policy, walk the layer stack, add therulesDSL source, surfacerequirements.tomlas a hardening signal, and record which layer produced each finding. Remote-control detection is gated on hardware verification of where its state lands.