Files
codex/codex-rs/cloud-config/src/validation.rs
T
alexsong-oai 1aaa453ce2 Enforce managed model provider selection and definitions (#44650)
## What changed

- Support `model_provider` and `model_providers` in managed requirements. Required selection overrides local and session configuration; each required provider definition replaces the corresponding local entry, including its authentication and headers.
- Merge provider requirement fragments before validation, preserving source-relative `auth.cwd` paths. Reject invalid cloud provider definitions before replacing the cached bundle, including unsupported Bedrock overrides.
- Expose `modelProvider` and `modelProviders` through the configuration requirements API and generated schemas. Reject writes to managed provider settings and omit their local origins, including for provider IDs containing dots.

## Testing

Add tests for requirement precedence, authentication fragment merging, path resolution, cloud cache preservation, and read-only configuration RPCs. Integration tests verify that model discovery and inference use the required gateway and ChatGPT authentication without leaking local headers, and that provider requirements survive configuration rebuilds.

GitOrigin-RevId: d1448604d4ef5662ebb5df7b693712d3b8ad6d54
2026-09-10 21:41:39 +00:00

49 lines
1.7 KiB
Rust

use codex_config::AbsolutePathBuf;
use codex_config::CloudConfigBundle;
use codex_config::CloudConfigBundleLayers;
use codex_config::CloudConfigBundleLoadError;
use codex_config::CloudConfigBundleLoadErrorCode;
use codex_config::compose_requirements;
use codex_config::config_toml::validate_model_providers;
pub(crate) fn validate_bundle(
bundle: &CloudConfigBundle,
base_dir: &AbsolutePathBuf,
) -> Result<(), CloudConfigBundleLoadError> {
let bundle_layers =
CloudConfigBundleLayers::from_bundle(bundle.clone(), base_dir).map_err(|err| {
CloudConfigBundleLoadError::new(
CloudConfigBundleLoadErrorCode::InvalidBundle,
/*status_code*/ None,
format!("invalid cloud config bundle: {err}"),
)
})?;
let CloudConfigBundleLayers {
enterprise_managed_config: _,
enterprise_managed_requirements,
} = bundle_layers;
let requirements = compose_requirements(enterprise_managed_requirements).map_err(|err| {
CloudConfigBundleLoadError::new(
CloudConfigBundleLoadErrorCode::InvalidBundle,
/*status_code*/ None,
format!("invalid cloud config bundle: {err}"),
)
})?;
if let Some(providers) = requirements.and_then(|requirements| requirements.model_providers) {
validate_model_providers(&providers).map_err(|err| {
CloudConfigBundleLoadError::new(
CloudConfigBundleLoadErrorCode::InvalidBundle,
/*status_code*/ None,
format!("invalid cloud config bundle: {err}"),
)
})?;
}
Ok(())
}
#[cfg(test)]
#[path = "validation_tests.rs"]
mod tests;