Files
codex/codex-rs/cli/src/debug_sandbox/cloud_config.rs
T
Abhinav 51e3f94b2b Load cloud config for sandbox and remote exec-server commands (#57270)
## Why

Sandbox invocations without an explicit permissions profile and remote `exec-server` connections using ChatGPT auth need access to cloud-defined model providers and managed requirements. Cloud bootstrap requests must also respect local application network policy.

## What changed

- Bootstrap sandbox cloud config whenever managed config is included, even without an explicit profile. Skip bootstrap when `--sandbox-state-json` supplies the sandbox state.
- Load cloud config for remote executors beyond workload identity, while skipping forwarders and executors using stdin credentials, AWS SigV4, or agent identity auth. Honor `CODEX_API_KEY` selection so API key connections skip ChatGPT cloud config.
- Apply local application network policy during cloud bootstrap and activate effective application network policy before exec-server clients are created.

## Testing

Add coverage for cloud-defined providers in sandbox and remote exec-server invocations, API key bypass, local policy blocking bundle requests, cloud policy blocking remote registration, and bootstrap exclusions.

GitOrigin-RevId: e8bd6210751e96161f575ade309ebf41bf10f8b5
2026-10-26 21:31:28 +00:00

58 lines
1.9 KiB
Rust

use codex_app_server::in_process::EmbeddedNetworkPolicy;
use codex_cloud_config::chatgpt_config_bundle_loader_for_storage;
use codex_config::CloudConfigBundleLoader;
use codex_config::ConfigLoadOptions;
use codex_core::config::bootstrap_auth_config;
use codex_core::config::load_config_toml_with_layer_stack;
use codex_utils_absolute_path::AbsolutePathBuf;
use toml::Value as TomlValue;
use super::DebugSandboxConfigOptions;
use super::ManagedRequirementsMode;
pub(super) async fn bootstrap_cloud_config_bundle(
cli_overrides: &[(String, TomlValue)],
options: &DebugSandboxConfigOptions,
resolve_codex_home: impl FnOnce() -> std::io::Result<AbsolutePathBuf>,
strict_config: bool,
) -> anyhow::Result<CloudConfigBundleLoader> {
if options.sandbox_state.sandbox_state_json.is_some()
|| !matches!(
options.managed_requirements_mode,
ManagedRequirementsMode::Include
)
{
return Ok(CloudConfigBundleLoader::default());
}
let codex_home = resolve_codex_home()?;
let cwd = match options.cwd.as_deref() {
Some(cwd) => AbsolutePathBuf::relative_to_current_dir(cwd)?,
None => AbsolutePathBuf::current_dir()?,
};
let network_policy = EmbeddedNetworkPolicy::load(&options.loader_overrides).await;
let bootstrap_config = load_config_toml_with_layer_stack(
codex_home.as_path(),
Some(&cwd),
cli_overrides.to_vec(),
ConfigLoadOptions {
loader_overrides: options.loader_overrides.clone(),
strict_config,
cloud_config_bundle: CloudConfigBundleLoader::default(),
},
)
.await?;
Ok(chatgpt_config_bundle_loader_for_storage(
network_policy.bind_bootstrap_auth(bootstrap_auth_config(
codex_home.as_path(),
&bootstrap_config,
)?),
/*enable_codex_api_key_env*/ false,
)
.await?)
}
#[cfg(test)]
#[path = "cloud_config_tests.rs"]
mod tests;