feat: add support for CODEX_SECURE_MODE=1 to restrict process observability (#4220)
Because the `codex` process could contain sensitive information in memory, such as API keys, we add logic so that when `CODEX_SECURE_MODE=1` is specified, we avail ourselves of whatever the operating system provides to restrict observability/tampering, which includes: - disabling `ptrace(2)`, so it is not possible to attach to the process with a debugger, such as `gdb` - disabling core dumps Admittedly, a user with root privileges can defeat these safeguards. For now, we only add support for this in the `codex` multitool, but we may ultimately want to support this in some of the smaller CLIs that are buildable out of our Cargo workspace.
This commit is contained in:
@@ -21,6 +21,7 @@ use std::path::PathBuf;
|
||||
use supports_color::Stream;
|
||||
|
||||
mod mcp_cmd;
|
||||
mod pre_main_hardening;
|
||||
|
||||
use crate::mcp_cmd::McpCli;
|
||||
use crate::proto::ProtoCli;
|
||||
@@ -194,6 +195,34 @@ fn print_exit_messages(exit_info: AppExitInfo) {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) const CODEX_SECURE_MODE_ENV_VAR: &str = "CODEX_SECURE_MODE";
|
||||
|
||||
/// As early as possible in the process lifecycle, apply hardening measures
|
||||
/// if the CODEX_SECURE_MODE environment variable is set to "1".
|
||||
#[ctor::ctor]
|
||||
fn pre_main_hardening() {
|
||||
let secure_mode = match std::env::var(CODEX_SECURE_MODE_ENV_VAR) {
|
||||
Ok(value) => value,
|
||||
Err(_) => return,
|
||||
};
|
||||
|
||||
if secure_mode == "1" {
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
crate::pre_main_hardening::pre_main_hardening_linux();
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
crate::pre_main_hardening::pre_main_hardening_macos();
|
||||
|
||||
#[cfg(windows)]
|
||||
crate::pre_main_hardening::pre_main_hardening_windows();
|
||||
}
|
||||
|
||||
// Always clear this env var so child processes don't inherit it.
|
||||
unsafe {
|
||||
std::env::remove_var(CODEX_SECURE_MODE_ENV_VAR);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
arg0_dispatch_or_else(|codex_linux_sandbox_exe| async move {
|
||||
cli_main(codex_linux_sandbox_exe).await?;
|
||||
|
||||
Reference in New Issue
Block a user