Compare commits

..

5 Commits

Author SHA1 Message Date
Michael Bolin
d2e3e3613b exec-server: use permission profiles in file system handler tests 2026-04-30 02:36:30 -07:00
Michael Bolin
57f895a7c0 memories: configure consolidation permissions directly 2026-04-30 02:36:30 -07:00
Michael Bolin
0cc3264ed4 analytics: distinguish custom managed permission profiles 2026-04-30 02:36:30 -07:00
Michael Bolin
05d341f0d4 tests: use permission profiles in guardian config checks 2026-04-30 02:36:30 -07:00
Michael Bolin
d53c86e0da tests: use permission profiles in unix escalation checks 2026-04-30 02:36:30 -07:00
6 changed files with 33 additions and 57 deletions

View File

@@ -98,7 +98,6 @@ use codex_protocol::protocol::AskForApproval;
use codex_protocol::protocol::HookEventName;
use codex_protocol::protocol::HookRunStatus;
use codex_protocol::protocol::HookSource;
use codex_protocol::protocol::SandboxPolicy;
use codex_protocol::protocol::SessionSource;
use codex_protocol::protocol::SubAgentSource;
use codex_protocol::protocol::TokenUsage;
@@ -313,9 +312,7 @@ fn sample_turn_resolved_config(turn_id: &str) -> TurnResolvedConfigFact {
session_source: SessionSource::Exec,
model: "gpt-5".to_string(),
model_provider: "openai".to_string(),
permission_profile: CorePermissionProfile::from_legacy_sandbox_policy(
&SandboxPolicy::new_read_only_policy(),
),
permission_profile: CorePermissionProfile::read_only(),
permission_profile_cwd: PathBuf::from("/tmp"),
reasoning_effort: None,
reasoning_summary: None,

View File

@@ -979,7 +979,7 @@ fn sandbox_policy_mode(permission_profile: &PermissionProfile, cwd: &Path) -> &'
if permission_profile.network_sandbox_policy().is_enabled() {
"full_access"
} else {
"external_sandbox"
"custom_permissions"
}
} else if file_system_policy
.get_writable_roots_with_cwd(cwd)
@@ -1089,7 +1089,7 @@ mod tests {
use codex_protocol::permissions::NetworkSandboxPolicy;
#[test]
fn managed_full_disk_with_restricted_network_reports_external_sandbox() {
fn managed_full_disk_with_restricted_network_reports_custom_permissions() {
let permission_profile = PermissionProfile::from_runtime_permissions_with_enforcement(
SandboxEnforcement::Managed,
&FileSystemSandboxPolicy::unrestricted(),
@@ -1098,7 +1098,7 @@ mod tests {
assert_eq!(
sandbox_policy_mode(&permission_profile, Path::new("/")),
"external_sandbox"
"custom_permissions"
);
}
}

View File

@@ -38,7 +38,6 @@ use codex_protocol::protocol::GuardianRiskLevel;
use codex_protocol::protocol::GuardianUserAuthorization;
use codex_protocol::protocol::ReviewDecision;
use codex_protocol::protocol::RolloutItem;
use codex_protocol::protocol::SandboxPolicy;
use codex_protocol::protocol::TurnCompleteEvent;
use core_test_support::PathBufExt;
use core_test_support::TempDirExt;
@@ -2168,9 +2167,7 @@ async fn guardian_review_session_config_preserves_parent_network_proxy() {
);
assert_eq!(
guardian_config.permissions.permission_profile,
Constrained::allow_only(PermissionProfile::from_legacy_sandbox_policy(
&SandboxPolicy::new_read_only_policy(),
))
Constrained::allow_only(PermissionProfile::read_only())
);
}
@@ -2232,9 +2229,7 @@ async fn guardian_review_session_config_uses_live_network_proxy_state() {
NetworkProxySpec::from_config_and_constraints(
live_network,
/*requirements*/ None,
&PermissionProfile::from_legacy_sandbox_policy(
&SandboxPolicy::new_read_only_policy(),
),
&PermissionProfile::read_only(),
)
.expect("live network proxy spec")
)

View File

@@ -28,7 +28,6 @@ use codex_protocol::permissions::NetworkSandboxPolicy;
use codex_protocol::protocol::AskForApproval;
use codex_protocol::protocol::GranularApprovalConfig;
use codex_protocol::protocol::GuardianCommandSource;
use codex_protocol::protocol::SandboxPolicy;
use codex_sandboxing::SandboxType;
use codex_shell_escalation::EscalationExecution;
use codex_shell_escalation::EscalationPermissions;
@@ -67,10 +66,6 @@ fn read_only_file_system_sandbox_policy() -> FileSystemSandboxPolicy {
}])
}
fn permission_profile_from_sandbox_policy(sandbox_policy: &SandboxPolicy) -> PermissionProfile {
PermissionProfile::from_legacy_sandbox_policy(sandbox_policy)
}
fn test_sandbox_cwd() -> AbsolutePathBuf {
AbsolutePathBuf::try_from(host_absolute_path(&["workspace"])).unwrap()
}
@@ -406,9 +401,7 @@ async fn execve_permission_request_hook_short_circuits_prompt() -> anyhow::Resul
call_id: "execve-hook-call".to_string(),
tool_name: GuardianCommandSource::Shell,
approval_policy: AskForApproval::OnRequest,
permission_profile: permission_profile_from_sandbox_policy(
&SandboxPolicy::new_read_only_policy(),
),
permission_profile: PermissionProfile::read_only(),
file_system_sandbox_policy: read_only_file_system_sandbox_policy(),
sandbox_policy_cwd: workdir.clone(),
sandbox_permissions: SandboxPermissions::RequireEscalated,
@@ -475,9 +468,7 @@ fn evaluate_intercepted_exec_policy_uses_wrapper_command_when_shell_wrapper_pars
],
InterceptedExecPolicyContext {
approval_policy: AskForApproval::OnRequest,
permission_profile: permission_profile_from_sandbox_policy(
&SandboxPolicy::new_read_only_policy(),
),
permission_profile: PermissionProfile::read_only(),
file_system_sandbox_policy: &read_only_file_system_sandbox_policy(),
sandbox_cwd: sandbox_cwd.as_path(),
sandbox_permissions: SandboxPermissions::UseDefault,
@@ -530,9 +521,7 @@ fn evaluate_intercepted_exec_policy_matches_inner_shell_commands_when_enabled()
],
InterceptedExecPolicyContext {
approval_policy: AskForApproval::OnRequest,
permission_profile: permission_profile_from_sandbox_policy(
&SandboxPolicy::new_read_only_policy(),
),
permission_profile: PermissionProfile::read_only(),
file_system_sandbox_policy: &read_only_file_system_sandbox_policy(),
sandbox_cwd: sandbox_cwd.as_path(),
sandbox_permissions: SandboxPermissions::UseDefault,
@@ -576,9 +565,7 @@ host_executable(name = "git", paths = ["{git_path_literal}"])
&["git".to_string(), "status".to_string()],
InterceptedExecPolicyContext {
approval_policy: AskForApproval::OnRequest,
permission_profile: permission_profile_from_sandbox_policy(
&SandboxPolicy::new_read_only_policy(),
),
permission_profile: PermissionProfile::read_only(),
file_system_sandbox_policy: &read_only_file_system_sandbox_policy(),
sandbox_cwd: sandbox_cwd.as_path(),
sandbox_permissions: SandboxPermissions::UseDefault,
@@ -610,7 +597,7 @@ fn intercepted_exec_policy_treats_preapproved_additional_permissions_as_default(
let program = AbsolutePathBuf::try_from(host_absolute_path(&["usr", "bin", "printf"])).unwrap();
let argv = ["printf".to_string(), "hello".to_string()];
let approval_policy = AskForApproval::OnRequest;
let sandbox_policy = SandboxPolicy::new_workspace_write_policy();
let permission_profile = PermissionProfile::workspace_write();
let file_system_sandbox_policy = read_only_file_system_sandbox_policy();
let sandbox_cwd = test_sandbox_cwd();
@@ -620,7 +607,7 @@ fn intercepted_exec_policy_treats_preapproved_additional_permissions_as_default(
&argv,
InterceptedExecPolicyContext {
approval_policy,
permission_profile: permission_profile_from_sandbox_policy(&sandbox_policy),
permission_profile: permission_profile.clone(),
file_system_sandbox_policy: &file_system_sandbox_policy,
sandbox_cwd: sandbox_cwd.as_path(),
sandbox_permissions: super::approval_sandbox_permissions(
@@ -636,7 +623,7 @@ fn intercepted_exec_policy_treats_preapproved_additional_permissions_as_default(
&argv,
InterceptedExecPolicyContext {
approval_policy,
permission_profile: permission_profile_from_sandbox_policy(&sandbox_policy),
permission_profile,
file_system_sandbox_policy: &file_system_sandbox_policy,
sandbox_cwd: sandbox_cwd.as_path(),
sandbox_permissions: SandboxPermissions::WithAdditionalPermissions,
@@ -671,9 +658,7 @@ host_executable(name = "git", paths = ["{allowed_git_literal}"])
&["git".to_string(), "status".to_string()],
InterceptedExecPolicyContext {
approval_policy: AskForApproval::OnRequest,
permission_profile: permission_profile_from_sandbox_policy(
&SandboxPolicy::new_read_only_policy(),
),
permission_profile: PermissionProfile::read_only(),
file_system_sandbox_policy: &read_only_file_system_sandbox_policy(),
sandbox_cwd: sandbox_cwd.as_path(),
sandbox_permissions: SandboxPermissions::UseDefault,

View File

@@ -173,8 +173,8 @@ fn map_fs_error(err: io::Error) -> JSONRPCErrorError {
#[cfg(test)]
mod tests {
use codex_protocol::protocol::NetworkAccess;
use codex_protocol::protocol::SandboxPolicy;
use codex_protocol::models::PermissionProfile;
use codex_protocol::permissions::NetworkSandboxPolicy;
use codex_utils_absolute_path::AbsolutePathBuf;
use pretty_assertions::assert_eq;
@@ -195,12 +195,12 @@ mod tests {
let sandbox_cwd =
AbsolutePathBuf::from_absolute_path(temp_dir.path()).expect("absolute tempdir");
for (file_name, sandbox_policy) in [
("danger.txt", SandboxPolicy::DangerFullAccess),
for (file_name, permission_profile) in [
("danger.txt", PermissionProfile::Disabled),
(
"external.txt",
SandboxPolicy::ExternalSandbox {
network_access: NetworkAccess::Restricted,
PermissionProfile::External {
network: NetworkSandboxPolicy::Restricted,
},
),
] {
@@ -212,8 +212,8 @@ mod tests {
.write_file(FsWriteFileParams {
path: path.clone(),
data_base64: STANDARD.encode("ok"),
sandbox: Some(FileSystemSandboxContext::from_legacy_sandbox_policy(
sandbox_policy.clone(),
sandbox: Some(FileSystemSandboxContext::from_permission_profile_with_cwd(
permission_profile.clone(),
sandbox_cwd.clone(),
)),
})
@@ -223,8 +223,8 @@ mod tests {
let response = handler
.read_file(FsReadFileParams {
path,
sandbox: Some(FileSystemSandboxContext::from_legacy_sandbox_policy(
sandbox_policy,
sandbox: Some(FileSystemSandboxContext::from_permission_profile_with_cwd(
permission_profile,
sandbox_cwd.clone(),
)),
})

View File

@@ -17,9 +17,10 @@ use codex_config::Constrained;
use codex_core::config::Config;
use codex_features::Feature;
use codex_protocol::ThreadId;
use codex_protocol::models::PermissionProfile;
use codex_protocol::permissions::NetworkSandboxPolicy;
use codex_protocol::protocol::AgentStatus;
use codex_protocol::protocol::AskForApproval;
use codex_protocol::protocol::SandboxPolicy;
use codex_protocol::protocol::TokenUsage;
use codex_protocol::user_input::UserInput;
use codex_state::Stage1Output;
@@ -315,18 +316,16 @@ mod agent {
.features
.disable(Feature::SkillMcpDependencyInstall);
// Sandbox policy
let writable_roots = vec![root];
// The consolidation agent only needs local memory-root write access and no network.
let consolidation_sandbox_policy = SandboxPolicy::WorkspaceWrite {
writable_roots,
network_access: false,
exclude_tmpdir_env_var: true,
exclude_slash_tmp: true,
};
let permission_profile = PermissionProfile::workspace_write_with(
std::slice::from_ref(&root),
NetworkSandboxPolicy::Restricted,
/*exclude_tmpdir_env_var*/ true,
/*exclude_slash_tmp*/ true,
);
agent_config
.permissions
.set_legacy_sandbox_policy(consolidation_sandbox_policy, agent_config.cwd.as_path())
.set_permission_profile(permission_profile)
.ok()?;
agent_config.model = Some(