mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
permissions: constrain requirements as profiles (#19736)
This commit is contained in:
@@ -27,8 +27,8 @@ use codex_config::version_for_toml;
|
||||
use codex_exec_server::LOCAL_FS;
|
||||
use codex_protocol::config_types::TrustLevel;
|
||||
use codex_protocol::config_types::WebSearchMode;
|
||||
use codex_protocol::models::PermissionProfile;
|
||||
use codex_protocol::protocol::AskForApproval;
|
||||
#[cfg(target_os = "macos")]
|
||||
use codex_protocol::protocol::SandboxPolicy;
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
use pretty_assertions::assert_eq;
|
||||
@@ -577,8 +577,8 @@ allowed_sandbox_modes = ["read-only"]
|
||||
AskForApproval::Never
|
||||
);
|
||||
assert_eq!(
|
||||
*state.requirements().sandbox_policy.get(),
|
||||
SandboxPolicy::new_read_only_policy()
|
||||
state.requirements().permission_profile.get(),
|
||||
&PermissionProfile::read_only()
|
||||
);
|
||||
assert!(
|
||||
state
|
||||
@@ -590,13 +590,15 @@ allowed_sandbox_modes = ["read-only"]
|
||||
assert!(
|
||||
state
|
||||
.requirements()
|
||||
.sandbox_policy
|
||||
.can_set(&SandboxPolicy::WorkspaceWrite {
|
||||
writable_roots: Vec::new(),
|
||||
network_access: false,
|
||||
exclude_tmpdir_env_var: false,
|
||||
exclude_slash_tmp: false,
|
||||
})
|
||||
.permission_profile
|
||||
.can_set(&PermissionProfile::from_legacy_sandbox_policy(
|
||||
&SandboxPolicy::WorkspaceWrite {
|
||||
writable_roots: Vec::new(),
|
||||
network_access: false,
|
||||
exclude_tmpdir_env_var: false,
|
||||
exclude_slash_tmp: false,
|
||||
},
|
||||
))
|
||||
.is_err()
|
||||
);
|
||||
|
||||
@@ -867,6 +869,55 @@ allowed_approval_policies = ["on-request"]
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
async fn system_remote_sandbox_config_keeps_cloud_sandbox_modes() -> anyhow::Result<()> {
|
||||
let tmp = tempdir()?;
|
||||
let requirements_file = tmp.path().join("requirements.toml");
|
||||
tokio::fs::write(
|
||||
&requirements_file,
|
||||
r#"
|
||||
[[remote_sandbox_config]]
|
||||
hostname_patterns = ["*"]
|
||||
allowed_sandbox_modes = ["read-only", "workspace-write"]
|
||||
"#,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let cloud_source = RequirementSource::CloudRequirements;
|
||||
let mut config_requirements_toml = ConfigRequirementsWithSources::default();
|
||||
config_requirements_toml.merge_unset_fields(
|
||||
cloud_source.clone(),
|
||||
toml::from_str(
|
||||
r#"
|
||||
allowed_sandbox_modes = ["read-only"]
|
||||
"#,
|
||||
)?,
|
||||
);
|
||||
load_requirements_toml(
|
||||
LOCAL_FS.as_ref(),
|
||||
&mut config_requirements_toml,
|
||||
&AbsolutePathBuf::try_from(requirements_file)?,
|
||||
)
|
||||
.await?;
|
||||
let config_requirements: ConfigRequirements = config_requirements_toml.try_into()?;
|
||||
|
||||
assert_eq!(
|
||||
config_requirements.permission_profile.can_set(
|
||||
&PermissionProfile::from_legacy_sandbox_policy(
|
||||
&SandboxPolicy::new_workspace_write_policy()
|
||||
)
|
||||
),
|
||||
Err(ConstraintError::InvalidValue {
|
||||
field_name: "sandbox_mode",
|
||||
candidate: "WorkspaceWrite".into(),
|
||||
allowed: "[ReadOnly]".into(),
|
||||
requirement_source: cloud_source,
|
||||
})
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
async fn load_requirements_toml_resolves_deny_read_against_parent() -> anyhow::Result<()> {
|
||||
let tmp = tempdir()?;
|
||||
@@ -1088,6 +1139,54 @@ async fn load_config_layers_includes_cloud_hook_requirements() -> anyhow::Result
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn load_config_layers_applies_matching_remote_sandbox_config() -> anyhow::Result<()> {
|
||||
let tmp = tempdir()?;
|
||||
let codex_home = tmp.path().join("home");
|
||||
tokio::fs::create_dir_all(&codex_home).await?;
|
||||
let cwd = AbsolutePathBuf::from_absolute_path(tmp.path())?;
|
||||
|
||||
let requirements: ConfigRequirementsToml = toml::from_str(
|
||||
r#"
|
||||
allowed_sandbox_modes = ["read-only"]
|
||||
|
||||
[[remote_sandbox_config]]
|
||||
hostname_patterns = ["*"]
|
||||
allowed_sandbox_modes = ["read-only", "workspace-write"]
|
||||
"#,
|
||||
)?;
|
||||
let cloud_requirements = CloudRequirementsLoader::new(async move { Ok(Some(requirements)) });
|
||||
let layers = load_config_layers_state(
|
||||
LOCAL_FS.as_ref(),
|
||||
&codex_home,
|
||||
Some(cwd),
|
||||
&[] as &[(String, TomlValue)],
|
||||
LoaderOverrides::default(),
|
||||
cloud_requirements,
|
||||
&codex_config::NoopThreadConfigLoader,
|
||||
)
|
||||
.await?;
|
||||
|
||||
assert_eq!(
|
||||
layers.requirements_toml().allowed_sandbox_modes,
|
||||
Some(vec![
|
||||
codex_config::SandboxModeRequirement::ReadOnly,
|
||||
codex_config::SandboxModeRequirement::WorkspaceWrite,
|
||||
])
|
||||
);
|
||||
assert!(
|
||||
layers
|
||||
.requirements()
|
||||
.permission_profile
|
||||
.can_set(&PermissionProfile::from_legacy_sandbox_policy(
|
||||
&SandboxPolicy::new_workspace_write_policy()
|
||||
))
|
||||
.is_ok()
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn load_config_layers_fails_when_cloud_requirements_loader_fails() -> anyhow::Result<()> {
|
||||
let tmp = tempdir()?;
|
||||
|
||||
@@ -1636,7 +1636,7 @@ network_access = false # This should be ignored.
|
||||
/*profile_sandbox_mode*/ None,
|
||||
WindowsSandboxLevel::Disabled,
|
||||
/*active_project*/ None,
|
||||
/*sandbox_policy_constraint*/ None,
|
||||
/*permission_profile_constraint*/ None,
|
||||
)
|
||||
.await;
|
||||
assert_eq!(resolution, SandboxPolicy::DangerFullAccess);
|
||||
@@ -1657,7 +1657,7 @@ network_access = true # This should be ignored.
|
||||
/*profile_sandbox_mode*/ None,
|
||||
WindowsSandboxLevel::Disabled,
|
||||
/*active_project*/ None,
|
||||
/*sandbox_policy_constraint*/ None,
|
||||
/*permission_profile_constraint*/ None,
|
||||
)
|
||||
.await;
|
||||
assert_eq!(resolution, SandboxPolicy::new_read_only_policy());
|
||||
@@ -1689,7 +1689,7 @@ trust_level = "trusted"
|
||||
/*profile_sandbox_mode*/ None,
|
||||
WindowsSandboxLevel::Disabled,
|
||||
/*active_project*/ None,
|
||||
/*sandbox_policy_constraint*/ None,
|
||||
/*permission_profile_constraint*/ None,
|
||||
)
|
||||
.await;
|
||||
if cfg!(target_os = "windows") {
|
||||
@@ -1729,7 +1729,7 @@ exclude_slash_tmp = true
|
||||
/*profile_sandbox_mode*/ None,
|
||||
WindowsSandboxLevel::Disabled,
|
||||
/*active_project*/ None,
|
||||
/*sandbox_policy_constraint*/ None,
|
||||
/*permission_profile_constraint*/ None,
|
||||
)
|
||||
.await;
|
||||
if cfg!(target_os = "windows") {
|
||||
@@ -6316,7 +6316,7 @@ trust_level = "untrusted"
|
||||
/*profile_sandbox_mode*/ None,
|
||||
WindowsSandboxLevel::Disabled,
|
||||
Some(&active_project),
|
||||
/*sandbox_policy_constraint*/ None,
|
||||
/*permission_profile_constraint*/ None,
|
||||
)
|
||||
.await;
|
||||
|
||||
@@ -6337,8 +6337,8 @@ trust_level = "untrusted"
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn derive_sandbox_policy_falls_back_to_constraint_value_for_implicit_defaults()
|
||||
-> anyhow::Result<()> {
|
||||
async fn derive_sandbox_policy_falls_back_to_read_only_for_implicit_defaults() -> anyhow::Result<()>
|
||||
{
|
||||
let project_dir = TempDir::new()?;
|
||||
let project_path = project_dir.path().to_path_buf();
|
||||
let project_key = project_path.to_string_lossy().to_string();
|
||||
@@ -6354,14 +6354,14 @@ async fn derive_sandbox_policy_falls_back_to_constraint_value_for_implicit_defau
|
||||
let active_project = ProjectConfig {
|
||||
trust_level: Some(TrustLevel::Trusted),
|
||||
};
|
||||
let constrained = Constrained::new(SandboxPolicy::DangerFullAccess, |candidate| {
|
||||
if matches!(candidate, SandboxPolicy::DangerFullAccess) {
|
||||
let constrained = Constrained::new(PermissionProfile::read_only(), |candidate| {
|
||||
if candidate == &PermissionProfile::read_only() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(ConstraintError::InvalidValue {
|
||||
field_name: "sandbox_mode",
|
||||
candidate: format!("{candidate:?}"),
|
||||
allowed: "[DangerFullAccess]".to_string(),
|
||||
allowed: "[ReadOnly]".to_string(),
|
||||
requirement_source: RequirementSource::Unknown,
|
||||
})
|
||||
}
|
||||
@@ -6377,7 +6377,7 @@ async fn derive_sandbox_policy_falls_back_to_constraint_value_for_implicit_defau
|
||||
)
|
||||
.await;
|
||||
|
||||
assert_eq!(resolution, SandboxPolicy::DangerFullAccess);
|
||||
assert_eq!(resolution, SandboxPolicy::new_read_only_policy());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -6399,18 +6399,29 @@ async fn derive_sandbox_policy_preserves_windows_downgrade_for_unsupported_fallb
|
||||
let active_project = ProjectConfig {
|
||||
trust_level: Some(TrustLevel::Trusted),
|
||||
};
|
||||
let constrained = Constrained::new(SandboxPolicy::new_workspace_write_policy(), |candidate| {
|
||||
if matches!(candidate, SandboxPolicy::WorkspaceWrite { .. }) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(ConstraintError::InvalidValue {
|
||||
field_name: "sandbox_mode",
|
||||
candidate: format!("{candidate:?}"),
|
||||
allowed: "[WorkspaceWrite]".to_string(),
|
||||
requirement_source: RequirementSource::Unknown,
|
||||
})
|
||||
}
|
||||
})?;
|
||||
let constrained = Constrained::new(
|
||||
PermissionProfile::from_legacy_sandbox_policy(&SandboxPolicy::new_workspace_write_policy()),
|
||||
|candidate| {
|
||||
if matches!(
|
||||
candidate,
|
||||
PermissionProfile::Managed {
|
||||
file_system: ManagedFileSystemPermissions::Restricted { entries, .. },
|
||||
..
|
||||
} if entries
|
||||
.iter()
|
||||
.any(|entry| entry.access.can_write())
|
||||
) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(ConstraintError::InvalidValue {
|
||||
field_name: "sandbox_mode",
|
||||
candidate: format!("{candidate:?}"),
|
||||
allowed: "[WorkspaceWrite]".to_string(),
|
||||
requirement_source: RequirementSource::Unknown,
|
||||
})
|
||||
}
|
||||
},
|
||||
)?;
|
||||
|
||||
let resolution = cfg
|
||||
.derive_sandbox_policy(
|
||||
|
||||
@@ -19,6 +19,7 @@ use codex_config::LoaderOverrides;
|
||||
use codex_config::McpServerIdentity;
|
||||
use codex_config::McpServerRequirement;
|
||||
use codex_config::ResidencyRequirement;
|
||||
use codex_config::SandboxModeRequirement;
|
||||
use codex_config::Sourced;
|
||||
use codex_config::ThreadConfigLoader;
|
||||
use codex_config::config_toml::ConfigToml;
|
||||
@@ -30,6 +31,7 @@ use codex_config::config_toml::validate_model_providers;
|
||||
use codex_config::loader::load_config_layers_state;
|
||||
use codex_config::loader::project_trust_key;
|
||||
use codex_config::profile_toml::ConfigProfile;
|
||||
use codex_config::sandbox_mode_requirement_for_permission_profile;
|
||||
use codex_config::types::ApprovalsReviewer;
|
||||
use codex_config::types::AuthCredentialsStoreMode;
|
||||
use codex_config::types::DEFAULT_OTEL_ENVIRONMENT;
|
||||
@@ -295,25 +297,6 @@ impl Permissions {
|
||||
}
|
||||
}
|
||||
|
||||
fn constrained_permission_profile_from_sandbox_projection(
|
||||
initial_value: PermissionProfile,
|
||||
sandbox_constraint: Constrained<SandboxPolicy>,
|
||||
cwd: AbsolutePathBuf,
|
||||
) -> std::io::Result<Constrained<PermissionProfile>> {
|
||||
Constrained::new(initial_value, move |candidate| {
|
||||
let (file_system_sandbox_policy, network_sandbox_policy) =
|
||||
candidate.to_runtime_permissions();
|
||||
let sandbox_policy = compatibility_sandbox_policy_for_permission_profile(
|
||||
candidate,
|
||||
&file_system_sandbox_policy,
|
||||
network_sandbox_policy,
|
||||
cwd.as_path(),
|
||||
);
|
||||
sandbox_constraint.can_set(&sandbox_policy)
|
||||
})
|
||||
.map_err(std::io::Error::from)
|
||||
}
|
||||
|
||||
/// Configured thread persistence backend.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Default)]
|
||||
pub enum ThreadStoreConfig {
|
||||
@@ -1709,7 +1692,7 @@ impl Config {
|
||||
let ConfigRequirements {
|
||||
approval_policy: mut constrained_approval_policy,
|
||||
approvals_reviewer: mut constrained_approvals_reviewer,
|
||||
sandbox_policy: mut constrained_sandbox_policy,
|
||||
permission_profile: mut constrained_permission_profile,
|
||||
web_search_mode: mut constrained_web_search_mode,
|
||||
feature_requirements,
|
||||
managed_hooks: _,
|
||||
@@ -1881,9 +1864,7 @@ impl Config {
|
||||
let (
|
||||
configured_network_proxy_config,
|
||||
permission_profile,
|
||||
sandbox_policy,
|
||||
file_system_sandbox_policy,
|
||||
network_sandbox_policy,
|
||||
) = if let Some(mut permission_profile) = permission_profile {
|
||||
let (mut file_system_sandbox_policy, network_sandbox_policy) =
|
||||
permission_profile.to_runtime_permissions();
|
||||
@@ -1910,7 +1891,7 @@ impl Config {
|
||||
} else {
|
||||
NetworkProxyConfig::default()
|
||||
};
|
||||
let mut sandbox_policy = compatibility_sandbox_policy_for_permission_profile(
|
||||
let sandbox_policy = compatibility_sandbox_policy_for_permission_profile(
|
||||
&permission_profile,
|
||||
&file_system_sandbox_policy,
|
||||
network_sandbox_policy,
|
||||
@@ -1927,19 +1908,11 @@ impl Config {
|
||||
&file_system_sandbox_policy,
|
||||
network_sandbox_policy,
|
||||
);
|
||||
sandbox_policy = compatibility_sandbox_policy_for_permission_profile(
|
||||
&permission_profile,
|
||||
&file_system_sandbox_policy,
|
||||
network_sandbox_policy,
|
||||
resolved_cwd.as_path(),
|
||||
);
|
||||
}
|
||||
(
|
||||
configured_network_proxy_config,
|
||||
permission_profile,
|
||||
sandbox_policy,
|
||||
file_system_sandbox_policy,
|
||||
network_sandbox_policy,
|
||||
)
|
||||
} else if profiles_are_active {
|
||||
let permissions = cfg.permissions.as_ref().ok_or_else(|| {
|
||||
@@ -1968,7 +1941,7 @@ impl Config {
|
||||
&file_system_sandbox_policy,
|
||||
network_sandbox_policy,
|
||||
);
|
||||
let mut sandbox_policy = compatibility_sandbox_policy_for_permission_profile(
|
||||
let sandbox_policy = compatibility_sandbox_policy_for_permission_profile(
|
||||
&permission_profile,
|
||||
&file_system_sandbox_policy,
|
||||
network_sandbox_policy,
|
||||
@@ -1984,19 +1957,11 @@ impl Config {
|
||||
&file_system_sandbox_policy,
|
||||
network_sandbox_policy,
|
||||
);
|
||||
sandbox_policy = compatibility_sandbox_policy_for_permission_profile(
|
||||
&permission_profile,
|
||||
&file_system_sandbox_policy,
|
||||
network_sandbox_policy,
|
||||
resolved_cwd.as_path(),
|
||||
);
|
||||
}
|
||||
(
|
||||
configured_network_proxy_config,
|
||||
permission_profile,
|
||||
sandbox_policy,
|
||||
file_system_sandbox_policy,
|
||||
network_sandbox_policy,
|
||||
)
|
||||
} else {
|
||||
let configured_network_proxy_config = NetworkProxyConfig::default();
|
||||
@@ -2006,7 +1971,7 @@ impl Config {
|
||||
config_profile.sandbox_mode,
|
||||
windows_sandbox_level,
|
||||
Some(&active_project),
|
||||
Some(&constrained_sandbox_policy),
|
||||
Some(&constrained_permission_profile),
|
||||
)
|
||||
.await;
|
||||
if let SandboxPolicy::WorkspaceWrite { writable_roots, .. } = &mut sandbox_policy {
|
||||
@@ -2030,9 +1995,7 @@ impl Config {
|
||||
(
|
||||
configured_network_proxy_config,
|
||||
permission_profile,
|
||||
sandbox_policy,
|
||||
file_system_sandbox_policy,
|
||||
network_sandbox_policy,
|
||||
)
|
||||
};
|
||||
let approval_policy_was_explicit = approval_policy_override.is_some()
|
||||
@@ -2324,8 +2287,7 @@ impl Config {
|
||||
.map(AbsolutePathBuf::to_path_buf)
|
||||
.or_else(|| resolve_sqlite_home_env(&resolved_cwd))
|
||||
.unwrap_or_else(|| codex_home.to_path_buf());
|
||||
let original_sandbox_policy = sandbox_policy.clone();
|
||||
|
||||
let original_permission_profile = permission_profile.clone();
|
||||
apply_requirement_constrained_value(
|
||||
"approval_policy",
|
||||
approval_policy,
|
||||
@@ -2339,17 +2301,22 @@ impl Config {
|
||||
&& !filesystem_requirements.deny_read.is_empty()
|
||||
{
|
||||
let requirement_source = filesystem_requirements_source.clone();
|
||||
constrained_sandbox_policy
|
||||
constrained_permission_profile
|
||||
.value
|
||||
.add_validator(move |policy| match policy {
|
||||
SandboxPolicy::ReadOnly { .. } | SandboxPolicy::WorkspaceWrite { .. } => Ok(()),
|
||||
SandboxPolicy::DangerFullAccess | SandboxPolicy::ExternalSandbox { .. } => {
|
||||
Err(ConstraintError::InvalidValue {
|
||||
field_name: "sandbox_mode",
|
||||
candidate: policy.to_string(),
|
||||
allowed: "[read-only, workspace-write]".to_string(),
|
||||
requirement_source: requirement_source.clone(),
|
||||
})
|
||||
.add_validator(move |permission_profile| {
|
||||
let mode = sandbox_mode_requirement_for_permission_profile(permission_profile);
|
||||
match mode {
|
||||
SandboxModeRequirement::ReadOnly
|
||||
| SandboxModeRequirement::WorkspaceWrite => Ok(()),
|
||||
SandboxModeRequirement::DangerFullAccess
|
||||
| SandboxModeRequirement::ExternalSandbox => {
|
||||
Err(ConstraintError::InvalidValue {
|
||||
field_name: "sandbox_mode",
|
||||
candidate: format!("{mode:?}"),
|
||||
allowed: "[read-only, workspace-write]".to_string(),
|
||||
requirement_source: requirement_source.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
.map_err(std::io::Error::from)?;
|
||||
@@ -2367,9 +2334,9 @@ impl Config {
|
||||
&mut startup_warnings,
|
||||
)?;
|
||||
apply_requirement_constrained_value(
|
||||
"sandbox_mode",
|
||||
sandbox_policy,
|
||||
&mut constrained_sandbox_policy,
|
||||
"permission_profile",
|
||||
permission_profile,
|
||||
&mut constrained_permission_profile,
|
||||
&mut startup_warnings,
|
||||
)?;
|
||||
apply_requirement_constrained_value(
|
||||
@@ -2387,13 +2354,7 @@ impl Config {
|
||||
None => (None, None),
|
||||
};
|
||||
let has_network_requirements = network_requirements.is_some();
|
||||
let network_permission_profile = if *constrained_sandbox_policy.get()
|
||||
== original_sandbox_policy
|
||||
{
|
||||
permission_profile.clone()
|
||||
} else {
|
||||
PermissionProfile::from_legacy_sandbox_policy(constrained_sandbox_policy.get())
|
||||
};
|
||||
let network_permission_profile = constrained_permission_profile.get().clone();
|
||||
let network = NetworkProxySpec::from_config_and_constraints(
|
||||
configured_network_proxy_config,
|
||||
network_requirements,
|
||||
@@ -2419,17 +2380,13 @@ impl Config {
|
||||
zsh_path.as_ref(),
|
||||
main_execve_wrapper_exe.as_ref(),
|
||||
);
|
||||
let effective_sandbox_policy = constrained_sandbox_policy.value.get().clone();
|
||||
let mut effective_file_system_sandbox_policy =
|
||||
if effective_sandbox_policy == original_sandbox_policy {
|
||||
file_system_sandbox_policy
|
||||
} else {
|
||||
FileSystemSandboxPolicy::from_legacy_sandbox_policy_preserving_deny_entries(
|
||||
&effective_sandbox_policy,
|
||||
resolved_cwd.as_path(),
|
||||
&file_system_sandbox_policy,
|
||||
)
|
||||
};
|
||||
let effective_permission_profile = constrained_permission_profile.value.get().clone();
|
||||
let (mut effective_file_system_sandbox_policy, effective_network_sandbox_policy) =
|
||||
effective_permission_profile.to_runtime_permissions();
|
||||
if effective_permission_profile != original_permission_profile {
|
||||
effective_file_system_sandbox_policy
|
||||
.preserve_deny_read_restrictions_from(&file_system_sandbox_policy);
|
||||
}
|
||||
if let Some(Sourced {
|
||||
value: filesystem_requirements,
|
||||
..
|
||||
@@ -2442,28 +2399,15 @@ impl Config {
|
||||
}
|
||||
let effective_file_system_sandbox_policy = effective_file_system_sandbox_policy
|
||||
.with_additional_readable_roots(resolved_cwd.as_path(), &helper_readable_roots);
|
||||
let effective_network_sandbox_policy =
|
||||
if effective_sandbox_policy == original_sandbox_policy {
|
||||
network_sandbox_policy
|
||||
} else {
|
||||
NetworkSandboxPolicy::from(&effective_sandbox_policy)
|
||||
};
|
||||
let effective_enforcement = if effective_sandbox_policy == original_sandbox_policy {
|
||||
permission_profile.enforcement()
|
||||
} else {
|
||||
SandboxEnforcement::from_legacy_sandbox_policy(&effective_sandbox_policy)
|
||||
};
|
||||
let effective_permission_profile = PermissionProfile::from_runtime_permissions_with_enforcement(
|
||||
effective_enforcement,
|
||||
effective_permission_profile.enforcement(),
|
||||
&effective_file_system_sandbox_policy,
|
||||
effective_network_sandbox_policy,
|
||||
);
|
||||
let constrained_permission_profile =
|
||||
constrained_permission_profile_from_sandbox_projection(
|
||||
effective_permission_profile,
|
||||
constrained_sandbox_policy.value.clone(),
|
||||
resolved_cwd.clone(),
|
||||
)?;
|
||||
constrained_permission_profile
|
||||
.value
|
||||
.set(effective_permission_profile)
|
||||
.map_err(std::io::Error::from)?;
|
||||
let config = Self {
|
||||
model,
|
||||
service_tier,
|
||||
@@ -2476,7 +2420,7 @@ impl Config {
|
||||
startup_warnings,
|
||||
permissions: Permissions {
|
||||
approval_policy: constrained_approval_policy.value,
|
||||
permission_profile: constrained_permission_profile,
|
||||
permission_profile: constrained_permission_profile.value,
|
||||
network,
|
||||
allow_login_shell,
|
||||
shell_environment_policy,
|
||||
|
||||
Reference in New Issue
Block a user