mirror of
https://github.com/openai/codex.git
synced 2026-10-21 17:48:44 +00:00
Honor managed login shell restrictions consistently
This commit is contained in:
@@ -67,10 +67,6 @@ const RESERVED_MODEL_PROVIDER_IDS: [&str; 4] = [
|
||||
|
||||
pub const DEFAULT_PROJECT_DOC_MAX_BYTES: usize = 32 * 1024;
|
||||
|
||||
const fn default_allow_login_shell() -> Option<bool> {
|
||||
Some(true)
|
||||
}
|
||||
|
||||
fn default_history() -> Option<History> {
|
||||
Some(History::default())
|
||||
}
|
||||
@@ -178,7 +174,6 @@ pub struct ConfigToml {
|
||||
/// If `false`, the model can never use a login shell: `login = true`
|
||||
/// requests are rejected, and omitting `login` defaults to a non-login
|
||||
/// shell.
|
||||
#[serde(default = "default_allow_login_shell")]
|
||||
pub allow_login_shell: Option<bool>,
|
||||
|
||||
/// Sandbox mode to use.
|
||||
|
||||
@@ -4407,7 +4407,6 @@
|
||||
"description": "Agent-related settings (thread limits, etc.)."
|
||||
},
|
||||
"allow_login_shell": {
|
||||
"default": true,
|
||||
"description": "Whether the model may request a login shell for shell-based tools. Default to `true`\n\nIf `true`, the model may request a login shell (`login = true`), and omitting `login` defaults to using a login shell. If `false`, the model can never use a login shell: `login = true` requests are rejected, and omitting `login` defaults to a non-login shell.",
|
||||
"type": "boolean"
|
||||
},
|
||||
|
||||
@@ -10928,3 +10928,18 @@ sandbox_private_desktop = false
|
||||
}));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn absent_allow_login_shell_does_not_report_an_override() -> std::io::Result<()> {
|
||||
let codex_home = TempDir::new()?;
|
||||
let config = load_with_enterprise_requirement(&codex_home, "allow_login_shell = false").await?;
|
||||
|
||||
assert!(!config.permissions.allow_login_shell);
|
||||
assert!(
|
||||
config
|
||||
.startup_warnings
|
||||
.iter()
|
||||
.all(|warning| !warning.contains("allow_login_shell"))
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1150,6 +1150,36 @@ async fn user_shell_commands_do_not_inherit_managed_network_proxy() -> anyhow::R
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn user_shell_commands_honor_disabled_login_shells() -> anyhow::Result<()> {
|
||||
let (session, rx) = make_session_with_config_and_rx(|config| {
|
||||
config.permissions.allow_login_shell = false;
|
||||
})
|
||||
.await?;
|
||||
let turn_context = session.new_default_turn().await;
|
||||
let command = "echo managed-login-shell".to_string();
|
||||
let expected_command = session.user_shell().derive_exec_args(&command, false);
|
||||
|
||||
execute_user_shell_command(
|
||||
Arc::clone(&session),
|
||||
turn_context,
|
||||
command,
|
||||
CancellationToken::new(),
|
||||
UserShellCommandMode::StandaloneTurn,
|
||||
)
|
||||
.await;
|
||||
|
||||
loop {
|
||||
let event = rx.recv().await.expect("channel open");
|
||||
if let EventMsg::ExecCommandBegin(event) = event.msg {
|
||||
assert_eq!(event.command, expected_command);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn get_base_instructions_no_user_content() {
|
||||
let prompt_with_apply_patch_instructions =
|
||||
|
||||
@@ -142,7 +142,7 @@ pub(crate) async fn execute_user_shell_command(
|
||||
// Execute the user's script under the environment's shell; this
|
||||
// allows commands that use shell features (pipes, &&, redirects, etc.).
|
||||
// We do not source rc files or otherwise reformat the script.
|
||||
let use_login_shell = true;
|
||||
let use_login_shell = turn_context.config.permissions.allow_login_shell;
|
||||
let display_command = environment_shell.derive_exec_args(&command, use_login_shell);
|
||||
let shell_snapshot_location = turn_environment.shell_snapshot(turn_environment.cwd());
|
||||
let mut exec_env_map = create_env(
|
||||
|
||||
Reference in New Issue
Block a user