Files
codex/codex-rs/config/src/loader
acrognale-oai 22a3f6d5d8 Enforce application network policy across app-server requests (#47407)
## What changed

- Load `application.network` requirements at startup and explicit config/account reloads, applying local policy before authentication and cloud configuration bootstrap.
- Block traffic when policy loading fails, cancel requests that a new policy no longer permits, and reject configuration loads based on superseded policy snapshots. Local requirements edits take effect on the next explicit reload or restart.
- Bind authenticated clients to the current account and revoke them when account ownership changes. Carry policy enforcement through backend requests, realtime connections, workload identity exchanges, and code-mode gRPC streams while preserving gRPC trailers.
- Treat denied credential refreshes as policy errors without retrying them or invalidating stored credentials.

## Testing

Add regression coverage for startup restrictions, reload ordering, cancellation after restrictive or malformed requirements edits, account revocation, gRPC destination denial, workload identity cancellation, and credential preservation after denied OAuth refresh.

GitOrigin-RevId: 0cb4c720a906397e9df06675f01ecf60d741101f
2026-09-23 00:47:07 +00:00
..

codex-config loader

This module is the canonical place to load and describe Codex configuration layers (user config, CLI/session overrides, cloud-managed config, managed config, and MDM-managed preferences) and to produce:

  • An effective merged TOML config.
  • Per-key origins metadata (which layer “wins” for a given key).
  • Per-layer versions (stable fingerprints) used for optimistic concurrency / conflict detection.

Public surface

Exported from codex_config::loader:

  • load_config_layers_state(fs, codex_home, cwd_opt, cli_overrides, options, thread_config_loader) -> ConfigLayerStack
  • ConfigLayerStack
    • effective_config() -> toml::Value
    • origins() -> HashMap<String, ConfigLayerMetadata>
    • layers_high_to_low() -> impl Iterator<Item = &ConfigLayerEntry>
    • with_user_config(user_config) -> ConfigLayerStack
  • ConfigLayerEntry (one layer’s {name, config, version, disabled_reason}; name carries source metadata)
  • ConfigLoadOptions (user-facing load behavior such as strict config validation)
  • LoaderOverrides (test/override hooks for managed config sources)
  • merge_toml_values(base, overlay) (public helper used elsewhere)

Layering model

Precedence is top overrides bottom:

  1. LegacyManagedConfigTomlFromMdm (MDM-delivered managed_config.toml, while it is being phased out)
  2. LegacyManagedConfigTomlFromFile (managed_config.toml, while it is being phased out)
  3. SessionFlags (CLI overrides, applied as dotted-path TOML writes)
  4. Project config (.codex/config.toml)
  5. User profile config, when present
  6. User config (config.toml)
  7. EnterpriseManaged cloud-managed config bundle layers
  8. System config (/etc/codex/config.toml or the Windows system config path)

ConfigLayerStack stores layers in the opposite order internally: lowest precedence first, highest precedence last, so later layers override earlier layers when folded. Thread config entries supplied by thread_config_loader are inserted according to their translated ConfigLayerSource precedence.

Project-root discovery and project trust use the applicable non-project layers, including legacy managed-file and MDM config at their normal precedence. The managed layers remain above project and session layers in the final stack. Executor-local reads use their own system, base-user, and legacy managed sources; they do not include cloud config, selected profiles, or session flags.

Layers with a disabled_reason are still surfaced for UI, but are ignored when computing the effective config and origins metadata. This is what ConfigLayerStack::effective_config() implements.

Typical usage

Most callers want the effective config plus metadata:

use codex_config::LoaderOverrides;
use codex_config::NoopThreadConfigLoader;
use codex_config::loader::load_config_layers_state;
use codex_exec_server::LOCAL_FS;
use codex_utils_absolute_path::AbsolutePathBuf;
use toml::Value as TomlValue;

let cli_overrides: Vec<(String, TomlValue)> = Vec::new();
let cwd = AbsolutePathBuf::current_dir()?;
let layers = load_config_layers_state(
    LOCAL_FS.as_ref(),
    &codex_home,
    Some(cwd),
    &cli_overrides,
    LoaderOverrides::default(),
    &NoopThreadConfigLoader,
).await?;

let effective = layers.effective_config();
let origins = layers.origins();
let layers_for_ui = layers.layers_high_to_low().collect::<Vec<_>>();

Internal layout

Implementation is split by concern:

  • state.rs: public types (ConfigLayerEntry, ConfigLayerStack) + merge/origins convenience methods.
  • layer_io.rs: reading config.toml, managed config, and managed preferences inputs.
  • project_discovery.rs: shared managed-config composition for project-root and trust discovery.
  • overrides.rs: CLI dotted-path overrides → TOML “session flags” layer.
  • merge.rs: recursive TOML merge.
  • fingerprint.rs: stable per-layer hashing and per-key origins traversal.
  • macos.rs: managed preferences integration (macOS only).