Files
codex/codex-rs/shell-command/src/shell_snapshot.rs
T
viyatb-oai 1c5ca2a979 Support remote credential masking with Zsh shell snapshots (#54432)
## Why

Remote credential masking previously supported only Bash commands without login startup or shell snapshots, leaving Zsh commands with unmasked credentials.

## What changed

- Enable masking for Zsh login commands using shell snapshots on Linux and macOS.
- Capture trusted startup profiles per launch, bind the credential broker to the resulting environment, and replace credentials and supported aliases with placeholders before snapshot replay.
- Preserve explicit environment overrides, credential unsets, and launcher-managed proxy settings during replay.
- Warn and fall back to unmasked startup when a snapshot cannot safely replay credentials; stop execution if protected snapshot restoration fails.

## Testing

Extend remote execution tests for inherited and profile-defined credentials, overrides, destination changes, and unsupported-profile fallback. Add a Zsh scenario snapshot showing a credential placeholder in command output.

GitOrigin-RevId: 83193d6cbc05f3deb0d6d0b9ae80974b353ce900
2026-10-15 22:25:58 +00:00

119 lines
4.0 KiB
Rust

//! Capture, prepare credential-safe state, and render restorable shell snapshots.
#[path = "shell_snapshot_capture.rs"]
mod capture;
#[path = "shell_snapshot_credentials.rs"]
mod credentials;
#[path = "shell_snapshot_exports.rs"]
mod exports;
#[path = "shell_snapshot_literals.rs"]
mod literals;
#[path = "shell_snapshot_render.rs"]
mod render;
#[path = "shell_snapshot_restore.rs"]
mod restore;
pub use capture::CapturedSnapshot;
pub use capture::CapturedStartupEnvironment;
pub use capture::SnapshotCaptureOptions;
pub use capture::snapshot_capture_script;
pub use capture::snapshot_source_capture_script;
pub use credentials::PreparedSnapshot;
pub use credentials::SnapshotCredentialEnvironment;
pub use credentials::prepare_snapshot_credentials;
pub use restore::SNAPSHOT_BROKERED_UNSET_ENV_PREFIX;
pub use restore::SNAPSHOT_BROKERED_VALUE_ENV_PREFIX;
pub use restore::build_brokered_credential_exports;
use capture::BASH_SH_SNAPSHOT_HEADER;
#[cfg(all(test, unix))]
#[path = "shell_snapshot_tests.rs"]
mod tests;
/// Returns the POSIX shell helper used to resolve supported `ENV` startup paths.
///
/// The helper deliberately supports only non-evaluating path forms. Unsupported
/// shell expressions are returned unchanged rather than executed.
pub fn posix_env_path_expansion_function() -> &'static str {
r#"__codex_snapshot_expand_env() (
set +u
__codex_snapshot_getenv() {
# Preserve the value separately from lookup status and its formatting newline.
__codex_env_expanded=$(
if command -v printenv >/dev/null 2>&1; then
printenv "$1"
elif [ "$1" = PATH ]; then
[ "${PATH+x}" = x ] && printf '%s\n' "$PATH"
else
command -p printenv "$1"
fi && printf '.'
) || return 1
__codex_env_expanded=${__codex_env_expanded%?}
__codex_env_expanded=${__codex_env_expanded%?}
}
__codex_env_file=$1
case "$__codex_env_file" in
'~/'*) __codex_env_file="${HOME-}/${__codex_env_file#*/}" ;;
'${PATH%%:*}') __codex_env_file="${PATH%%:*}" ;;
'${PATH%%:*}/'*) __codex_env_file="${PATH%%:*}/${__codex_env_file#*/}" ;;
'${'*)
__codex_env_body=${__codex_env_file#\$\{}
case "$__codex_env_body" in
*\}*)
__codex_env_name=${__codex_env_body%%\}*}
__codex_env_suffix=${__codex_env_body#*\}}
case "$__codex_env_name" in
*:-*)
__codex_env_default=${__codex_env_name#*:-}
__codex_env_name=${__codex_env_name%%:-*}
__codex_env_has_default=1
;;
*) __codex_env_has_default= ;;
esac
case "$__codex_env_name" in
''|[0-9]*|*[!A-Za-z0-9_]*) ;;
*)
case "$__codex_env_suffix" in
''|/*)
if __codex_snapshot_getenv "$__codex_env_name" 2>/dev/null &&
{ [ -n "$__codex_env_expanded" ] || [ -z "$__codex_env_has_default" ]; }; then
__codex_env_file="$__codex_env_expanded$__codex_env_suffix"
elif [ -n "$__codex_env_has_default" ]; then
__codex_env_default=$(__codex_snapshot_expand_env "$__codex_env_default")
__codex_env_file="$__codex_env_default$__codex_env_suffix"
fi
;;
esac
;;
esac
;;
esac
;;
'$'*)
__codex_env_name=${__codex_env_file%%/*}
__codex_env_name=${__codex_env_name#\$}
case "$__codex_env_name" in
''|[0-9]*|*[!A-Za-z0-9_]*) ;;
*)
if __codex_snapshot_getenv "$__codex_env_name" 2>/dev/null; then
if [ "$__codex_env_file" = "\$$__codex_env_name" ]; then
__codex_env_file=$__codex_env_expanded
else
__codex_env_file="$__codex_env_expanded/${__codex_env_file#*/}"
fi
fi
;;
esac
;;
esac
printf '%s' "$__codex_env_file"
)"#
}
#[derive(Clone, Copy)]
pub enum SnapshotStartup {
Interactive,
NonInteractive,
}