mirror of
https://github.com/openai/codex.git
synced 2026-11-07 20:30:33 +00:00
## What changed Keep untrusted project configuration and MCP servers disabled in exec runs, even with `--sandbox workspace-write`, and warn when project configuration is disabled. Add `--trust` to `codex exec` and `codex review` to save project trust for the current and future chats, including MCP commands outside the sandbox. The grant persists with `--ephemeral`, refuses explicitly untrusted projects, and cannot be combined with `--ignore-user-config`. Pass the working directory as a configuration default so embedded server startup does not implicitly grant trust. Preserve the selected `--oss` provider across configuration reloads. ## Testing Extend CLI parsing and MCP integration coverage for explicit trust, persistence across ephemeral runs, disabled project configuration with write access, and rejection of conflicting or explicitly untrusted settings. GitOrigin-RevId: b57f4f8829f98d77c5487fa8405c7f29b5d70d0c
70 lines
2.9 KiB
Rust
70 lines
2.9 KiB
Rust
use codex_core::config::set_project_trust_level;
|
|
use codex_protocol::config_types::TrustLevel;
|
|
use core_test_support::responses;
|
|
use core_test_support::test_codex_exec::test_codex_exec;
|
|
use predicates::str::contains;
|
|
use pretty_assertions::assert_eq;
|
|
use std::fs;
|
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn exits_non_zero_when_required_mcp_server_fails_to_initialize() -> anyhow::Result<()> {
|
|
let test = test_codex_exec();
|
|
|
|
let config_toml = r#"
|
|
[mcp_servers.required_broken]
|
|
command = "codex-definitely-not-a-real-binary"
|
|
required = true
|
|
"#;
|
|
let user_config = test.home_path().join("config.toml");
|
|
fs::write(&user_config, config_toml)?;
|
|
let project = test.cwd_path().join("repo");
|
|
let cwd = project.join("subdir");
|
|
fs::create_dir_all(&cwd)?;
|
|
fs::create_dir(project.join(".codex"))?;
|
|
fs::create_dir(project.join(".git"))?;
|
|
fs::write(project.join(".git/HEAD"), "ref: refs/heads/main\n")?;
|
|
|
|
let server = responses::start_mock_server().await;
|
|
responses::mount_sse_once(&server, responses::sse_completed("resp_1")).await;
|
|
let run = |args: &[&str]| {
|
|
test.cmd_with_server(&server)
|
|
.arg("--cd")
|
|
.arg(&cwd)
|
|
.args(["--ephemeral", "--experimental-json"])
|
|
.args(args)
|
|
.arg("hello")
|
|
.assert()
|
|
};
|
|
let expect_mcp_failure = |args: &[&str]| {
|
|
run(args).code(1).stderr(contains(
|
|
"required MCP servers failed to initialize: required_broken",
|
|
));
|
|
};
|
|
|
|
expect_mcp_failure(&[]);
|
|
// The same server in project config requires explicit consent, even with write access.
|
|
fs::rename(&user_config, project.join(".codex/config.toml"))?;
|
|
let first = run(&["--sandbox", "workspace-write"]).success();
|
|
let stderr = std::str::from_utf8(&first.get_output().stderr)?;
|
|
let warning = stderr
|
|
.lines()
|
|
.find(|line| line.contains("codex exec --trust"))
|
|
.expect("project trust warning");
|
|
insta::assert_snapshot!(warning, @"warning: Untrusted project-local configuration is disabled. Run `codex exec --trust` to allow project configuration and MCP servers for this and future chats in the project, including MCP commands outside the sandbox. Explicitly untrusted projects must have their trust setting updated first.");
|
|
expect_mcp_failure(&["--sandbox", "read-only", "--trust"]);
|
|
expect_mcp_failure(&[]);
|
|
|
|
set_project_trust_level(test.home_path(), &project, TrustLevel::Untrusted)?;
|
|
let refusal = fs::read_to_string(&user_config)?;
|
|
run(&["--trust"])
|
|
.failure()
|
|
.stderr(contains("is marked as untrusted"));
|
|
run(&["--ignore-user-config", "resume", "--last", "--trust"])
|
|
.failure()
|
|
.stderr(contains(
|
|
"--trust cannot be combined with --ignore-user-config",
|
|
));
|
|
assert_eq!(fs::read_to_string(user_config)?, refusal);
|
|
Ok(())
|
|
}
|