Files
codex/codex-rs/app-server/tests/suite/strict_config.rs
Abhinav 2994f545a7 Enforce managed authentication requirements locally (#37132)
## Why

Authentication restrictions must apply before stored or environment-provided credentials can be used, including during bootstrap before cloud requirements are fetched.

## What changed

- Add local `requirements.toml` allowlists for login methods and ChatGPT workspaces. Ignore these fields in cloud-provided requirements.
- Combine managed workspace allowlists with existing workspace restrictions by intersection, and fail closed when the resulting policy permits no usable login method.
- Centralize policy checks in the authentication manager so CLI, TUI, app-server, external-auth, and credential-loading paths consistently reject disallowed authentication before token hydration or network requests.

## Testing

- Cover policy composition, workspace intersection, invalid stored and external credentials, bootstrap enforcement, and login endpoint restrictions.

GitOrigin-RevId: efef22b248f3c3333e9aa55423e539efa2d2dd48
2026-08-05 18:09:26 +00:00

67 lines
2.1 KiB
Rust

use std::process::Command;
use anyhow::Result;
use tempfile::TempDir;
#[test]
fn strict_config_rejects_unknown_config_fields_for_standalone_app_server() -> Result<()> {
let codex_home = TempDir::new()?;
std::fs::write(
codex_home.path().join("config.toml"),
r#"
foo = "bar"
"#,
)?;
let output = Command::new(codex_utils_cargo_bin::cargo_bin("codex-app-server")?)
.env("CODEX_HOME", codex_home.path())
.env(
"CODEX_APP_SERVER_MANAGED_CONFIG_PATH",
codex_home.path().join("managed_config.toml"),
)
.args(["--strict-config", "--listen", "off"])
.output()?;
assert!(!output.status.success());
let stderr = String::from_utf8(output.stderr)?;
assert!(
stderr.contains("unknown configuration field `foo`"),
"expected strict config error in stderr, got: {stderr}"
);
Ok(())
}
#[test]
fn managed_auth_requirements_fail_closed_for_standalone_app_server() -> Result<()> {
for requirements in [
"allowed_login_methods = []\n",
"allowed_login_methods = [\"chatgpt\"]\nallowed_chatgpt_workspaces = []\n",
] {
let codex_home = TempDir::new()?;
std::fs::write(codex_home.path().join("requirements.toml"), requirements)?;
let output = Command::new(codex_utils_cargo_bin::cargo_bin("codex-app-server")?)
.env("CODEX_HOME", codex_home.path())
.env(
"CODEX_APP_SERVER_MANAGED_CONFIG_PATH",
codex_home.path().join("managed_config.toml"),
)
.args(["--listen", "off"])
.output()?;
assert!(!output.status.success());
let stderr = String::from_utf8(output.stderr)?;
assert!(
stderr.contains("authentication requirements do not permit any usable login method"),
"expected managed authentication error in stderr, got: {stderr}"
);
assert!(
!stderr.contains("using defaults"),
"managed authentication requirements must not fall back to defaults"
);
}
Ok(())
}