Thread Windows metadata targets through setup request

This commit is contained in:
Eva Wong
2026-05-04 10:03:53 -07:00
parent df461fd9eb
commit f29e31e27f
7 changed files with 35 additions and 0 deletions

View File

@@ -665,6 +665,7 @@ async fn exec_windows_sandbox(
elevated_read_roots_include_platform_defaults, elevated_read_roots_include_platform_defaults,
write_roots_override: elevated_write_roots_override.as_deref(), write_roots_override: elevated_write_roots_override.as_deref(),
deny_write_paths_override: &elevated_deny_write_paths, deny_write_paths_override: &elevated_deny_write_paths,
protected_metadata_targets: &[],
}, },
) )
} else { } else {

View File

@@ -2,6 +2,8 @@ use std::collections::HashMap;
use std::path::Path; use std::path::Path;
use std::path::PathBuf; use std::path::PathBuf;
use crate::setup::ProtectedMetadataTarget;
pub struct ElevatedSandboxCaptureRequest<'a> { pub struct ElevatedSandboxCaptureRequest<'a> {
pub policy_json_or_preset: &'a str, pub policy_json_or_preset: &'a str,
pub sandbox_policy_cwd: &'a Path, pub sandbox_policy_cwd: &'a Path,
@@ -16,6 +18,7 @@ pub struct ElevatedSandboxCaptureRequest<'a> {
pub read_roots_include_platform_defaults: bool, pub read_roots_include_platform_defaults: bool,
pub write_roots_override: Option<&'a [PathBuf]>, pub write_roots_override: Option<&'a [PathBuf]>,
pub deny_write_paths_override: &'a [PathBuf], pub deny_write_paths_override: &'a [PathBuf],
pub protected_metadata_targets: &'a [ProtectedMetadataTarget],
} }
mod windows_impl { mod windows_impl {
@@ -125,6 +128,7 @@ mod windows_impl {
read_roots_include_platform_defaults, read_roots_include_platform_defaults,
write_roots_override, write_roots_override,
deny_write_paths_override, deny_write_paths_override,
protected_metadata_targets,
} = request; } = request;
let policy = parse_policy(policy_json_or_preset)?; let policy = parse_policy(policy_json_or_preset)?;
normalize_null_device_env(&mut env_map); normalize_null_device_env(&mut env_map);
@@ -147,6 +151,7 @@ mod windows_impl {
read_roots_include_platform_defaults, read_roots_include_platform_defaults,
write_roots_override, write_roots_override,
deny_write_paths_override, deny_write_paths_override,
protected_metadata_targets,
proxy_enforced, proxy_enforced,
)?; )?;
// Build capability SID for ACL grants. // Build capability SID for ACL grants.

View File

@@ -140,6 +140,7 @@ pub fn require_logon_sandbox_creds(
read_roots_include_platform_defaults: bool, read_roots_include_platform_defaults: bool,
write_roots_override: Option<&[PathBuf]>, write_roots_override: Option<&[PathBuf]>,
deny_write_paths_override: &[PathBuf], deny_write_paths_override: &[PathBuf],
protected_metadata_targets: &[crate::setup::ProtectedMetadataTarget],
proxy_enforced: bool, proxy_enforced: bool,
) -> Result<SandboxCreds> { ) -> Result<SandboxCreds> {
let sandbox_dir = crate::setup::sandbox_dir(codex_home); let sandbox_dir = crate::setup::sandbox_dir(codex_home);
@@ -202,6 +203,7 @@ pub fn require_logon_sandbox_creds(
read_roots_include_platform_defaults, read_roots_include_platform_defaults,
write_roots: Some(needed_write.clone()), write_roots: Some(needed_write.clone()),
deny_write_paths: Some(deny_write_paths_override.to_vec()), deny_write_paths: Some(deny_write_paths_override.to_vec()),
protected_metadata_targets: Some(protected_metadata_targets.to_vec()),
}, },
)?; )?;
identity = select_identity(network_identity, codex_home)?; identity = select_identity(network_identity, codex_home)?;
@@ -221,6 +223,7 @@ pub fn require_logon_sandbox_creds(
read_roots_include_platform_defaults, read_roots_include_platform_defaults,
write_roots: Some(needed_write), write_roots: Some(needed_write),
deny_write_paths: Some(deny_write_paths_override.to_vec()), deny_write_paths: Some(deny_write_paths_override.to_vec()),
protected_metadata_targets: Some(protected_metadata_targets.to_vec()),
}, },
)?; )?;
let identity = identity.ok_or_else(|| { let identity = identity.ok_or_else(|| {

View File

@@ -8,6 +8,7 @@ use base64::Engine;
use base64::engine::general_purpose::STANDARD as BASE64; use base64::engine::general_purpose::STANDARD as BASE64;
use codex_otel::StatsigMetricsSettings; use codex_otel::StatsigMetricsSettings;
use codex_windows_sandbox::LOG_FILE_NAME; use codex_windows_sandbox::LOG_FILE_NAME;
use codex_windows_sandbox::ProtectedMetadataTarget;
use codex_windows_sandbox::SETUP_VERSION; use codex_windows_sandbox::SETUP_VERSION;
use codex_windows_sandbox::SetupErrorCode; use codex_windows_sandbox::SetupErrorCode;
use codex_windows_sandbox::SetupErrorReport; use codex_windows_sandbox::SetupErrorReport;
@@ -87,6 +88,9 @@ struct Payload {
write_roots: Vec<PathBuf>, write_roots: Vec<PathBuf>,
#[serde(default)] #[serde(default)]
deny_write_paths: Vec<PathBuf>, deny_write_paths: Vec<PathBuf>,
#[allow(dead_code)]
#[serde(default)]
protected_metadata_targets: Vec<ProtectedMetadataTarget>,
proxy_ports: Vec<u16>, proxy_ports: Vec<u16>,
#[serde(default)] #[serde(default)]
allow_local_binding: bool, allow_local_binding: bool,

View File

@@ -97,6 +97,7 @@ pub struct SetupRootOverrides {
pub read_roots_include_platform_defaults: bool, pub read_roots_include_platform_defaults: bool,
pub write_roots: Option<Vec<PathBuf>>, pub write_roots: Option<Vec<PathBuf>>,
pub deny_write_paths: Option<Vec<PathBuf>>, pub deny_write_paths: Option<Vec<PathBuf>>,
pub protected_metadata_targets: Option<Vec<ProtectedMetadataTarget>>,
} }
/// Layer: Windows enforcement request boundary. These targets are projected by /// Layer: Windows enforcement request boundary. These targets are projected by
@@ -169,6 +170,7 @@ pub fn run_setup_refresh_with_extra_read_roots(
read_roots_include_platform_defaults: false, read_roots_include_platform_defaults: false,
write_roots: Some(Vec::new()), write_roots: Some(Vec::new()),
deny_write_paths: None, deny_write_paths: None,
protected_metadata_targets: None,
}, },
) )
} }
@@ -186,6 +188,8 @@ fn run_setup_refresh_inner(
} }
let (read_roots, write_roots) = build_payload_roots(&request, &overrides); let (read_roots, write_roots) = build_payload_roots(&request, &overrides);
let deny_write_paths = build_payload_deny_write_paths(&request, overrides.deny_write_paths); let deny_write_paths = build_payload_deny_write_paths(&request, overrides.deny_write_paths);
let protected_metadata_targets =
build_payload_protected_metadata_targets(overrides.protected_metadata_targets);
let network_identity = let network_identity =
SandboxNetworkIdentity::from_policy(request.policy, request.proxy_enforced); SandboxNetworkIdentity::from_policy(request.policy, request.proxy_enforced);
let offline_proxy_settings = offline_proxy_settings_from_env(request.env_map, network_identity); let offline_proxy_settings = offline_proxy_settings_from_env(request.env_map, network_identity);
@@ -198,6 +202,7 @@ fn run_setup_refresh_inner(
read_roots, read_roots,
write_roots, write_roots,
deny_write_paths, deny_write_paths,
protected_metadata_targets,
proxy_ports: offline_proxy_settings.proxy_ports, proxy_ports: offline_proxy_settings.proxy_ports,
allow_local_binding: offline_proxy_settings.allow_local_binding, allow_local_binding: offline_proxy_settings.allow_local_binding,
otel: None, otel: None,
@@ -436,6 +441,8 @@ struct ElevationPayload {
write_roots: Vec<PathBuf>, write_roots: Vec<PathBuf>,
#[serde(default)] #[serde(default)]
deny_write_paths: Vec<PathBuf>, deny_write_paths: Vec<PathBuf>,
#[serde(default)]
protected_metadata_targets: Vec<ProtectedMetadataTarget>,
proxy_ports: Vec<u16>, proxy_ports: Vec<u16>,
#[serde(default)] #[serde(default)]
allow_local_binding: bool, allow_local_binding: bool,
@@ -738,6 +745,8 @@ pub fn run_elevated_setup(
})?; })?;
let (read_roots, write_roots) = build_payload_roots(&request, &overrides); let (read_roots, write_roots) = build_payload_roots(&request, &overrides);
let deny_write_paths = build_payload_deny_write_paths(&request, overrides.deny_write_paths); let deny_write_paths = build_payload_deny_write_paths(&request, overrides.deny_write_paths);
let protected_metadata_targets =
build_payload_protected_metadata_targets(overrides.protected_metadata_targets);
let network_identity = let network_identity =
SandboxNetworkIdentity::from_policy(request.policy, request.proxy_enforced); SandboxNetworkIdentity::from_policy(request.policy, request.proxy_enforced);
let offline_proxy_settings = offline_proxy_settings_from_env(request.env_map, network_identity); let offline_proxy_settings = offline_proxy_settings_from_env(request.env_map, network_identity);
@@ -750,6 +759,7 @@ pub fn run_elevated_setup(
read_roots, read_roots,
write_roots, write_roots,
deny_write_paths, deny_write_paths,
protected_metadata_targets,
proxy_ports: offline_proxy_settings.proxy_ports, proxy_ports: offline_proxy_settings.proxy_ports,
allow_local_binding: offline_proxy_settings.allow_local_binding, allow_local_binding: offline_proxy_settings.allow_local_binding,
real_user: std::env::var("USERNAME").unwrap_or_else(|_| "Administrators".to_string()), real_user: std::env::var("USERNAME").unwrap_or_else(|_| "Administrators".to_string()),
@@ -834,6 +844,12 @@ fn build_payload_deny_write_paths(
deny_write_paths deny_write_paths
} }
fn build_payload_protected_metadata_targets(
explicit_targets: Option<Vec<ProtectedMetadataTarget>>,
) -> Vec<ProtectedMetadataTarget> {
explicit_targets.unwrap_or_default()
}
fn expand_user_profile_root(roots: Vec<PathBuf>) -> Vec<PathBuf> { fn expand_user_profile_root(roots: Vec<PathBuf>) -> Vec<PathBuf> {
let Ok(user_profile) = std::env::var("USERPROFILE") else { let Ok(user_profile) = std::env::var("USERPROFILE") else {
return roots; return roots;
@@ -1345,6 +1361,7 @@ mod tests {
read_roots_include_platform_defaults: true, read_roots_include_platform_defaults: true,
write_roots: None, write_roots: None,
deny_write_paths: None, deny_write_paths: None,
protected_metadata_targets: None,
}, },
); );
let expected_helper = let expected_helper =
@@ -1392,6 +1409,7 @@ mod tests {
read_roots_include_platform_defaults: false, read_roots_include_platform_defaults: false,
write_roots: None, write_roots: None,
deny_write_paths: None, deny_write_paths: None,
protected_metadata_targets: None,
}, },
); );
let expected_helper = let expected_helper =

View File

@@ -17,6 +17,7 @@ use crate::policy::SandboxPolicy;
use crate::policy::parse_policy; use crate::policy::parse_policy;
use crate::sandbox_utils::ensure_codex_home_exists; use crate::sandbox_utils::ensure_codex_home_exists;
use crate::sandbox_utils::inject_git_safe_directory; use crate::sandbox_utils::inject_git_safe_directory;
use crate::setup::ProtectedMetadataTarget;
use crate::token::convert_string_sid_to_sid; use crate::token::convert_string_sid_to_sid;
use crate::token::create_readonly_token_with_cap; use crate::token::create_readonly_token_with_cap;
use crate::token::create_workspace_write_token_with_caps_from; use crate::token::create_workspace_write_token_with_caps_from;
@@ -264,6 +265,7 @@ pub(crate) fn prepare_elevated_spawn_context(
cwd: &Path, cwd: &Path,
env_map: &mut HashMap<String, String>, env_map: &mut HashMap<String, String>,
command: &[String], command: &[String],
protected_metadata_targets: &[ProtectedMetadataTarget],
) -> Result<ElevatedSpawnContext> { ) -> Result<ElevatedSpawnContext> {
let common = prepare_spawn_context_common( let common = prepare_spawn_context_common(
policy_json_or_preset, policy_json_or_preset,
@@ -298,6 +300,7 @@ pub(crate) fn prepare_elevated_spawn_context(
/*read_roots_include_platform_defaults*/ false, /*read_roots_include_platform_defaults*/ false,
write_roots_override, write_roots_override,
&deny_write_paths, &deny_write_paths,
protected_metadata_targets,
/*proxy_enforced*/ false, /*proxy_enforced*/ false,
)?; )?;
let caps = load_or_create_cap_sids(codex_home)?; let caps = load_or_create_cap_sids(codex_home)?;

View File

@@ -38,6 +38,7 @@ pub(crate) async fn spawn_windows_sandbox_session_elevated(
cwd, cwd,
&mut env_map, &mut env_map,
&command, &command,
&[],
)?; )?;
let spawn_request = SpawnRequest { let spawn_request = SpawnRequest {