mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Use ApiPathString in app-server filesystem permission paths (#28367)
## Why Clients running an app-server on one OS and an exec-server on another OS need to be able to pass sandbox config to app-server that refers to resources on the executor's foreign OS. ## What `AbsolutePathBuf` can't represent these paths and we don't want users to be exposed to `PathUri` yet, so this moves the public app-server API to be expressed in terms of `ApiPathString`. Stacked on #28165. - change app-server v2 filesystem permission paths, including legacy read/write roots, to `ApiPathString` - localize API paths through `PathUri` when converting into the current native core permission types - make path-bearing permission conversions fallible and surface localization failures instead of silently treating malformed grants as ordinary denials - propagate conversion failures through app-server and TUI approval handling - regenerate the app-server JSON and TypeScript schemas - leave migration TODOs on native-path conversions so they can be removed once core permission paths use `PathUri`
This commit is contained in:
committed by
GitHub
Unverified
parent
d959664420
commit
ecfe174d5f
@@ -30,7 +30,16 @@ impl ChatWidget {
|
||||
self.on_elicitation_request(request_id, params);
|
||||
}
|
||||
ServerRequest::PermissionsRequestApproval { params, .. } => {
|
||||
self.on_request_permissions(request_permissions_from_params(params));
|
||||
// TODO(anp): Remove this native-path localization error path once core permission
|
||||
// paths remain PathUri after crossing the app-server boundary.
|
||||
match request_permissions_from_params(params) {
|
||||
Ok(event) => self.on_request_permissions(event),
|
||||
Err(err) => {
|
||||
self.add_error_message(format!(
|
||||
"failed to localize requested filesystem paths: {err}"
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
ServerRequest::ToolRequestUserInput { params, .. } => {
|
||||
self.on_request_user_input(params);
|
||||
@@ -62,6 +71,17 @@ impl ChatWidget {
|
||||
completion: Option<(i64, codex_app_server_protocol::AutoReviewDecisionSource)>,
|
||||
action: GuardianApprovalReviewAction,
|
||||
) {
|
||||
// TODO(anp): Remove this native-path localization error path once core permission paths
|
||||
// remain PathUri after crossing the app-server boundary.
|
||||
let action = match action.try_into() {
|
||||
Ok(action) => action,
|
||||
Err(err) => {
|
||||
self.add_error_message(format!(
|
||||
"failed to localize guardian filesystem paths: {err}"
|
||||
));
|
||||
return;
|
||||
}
|
||||
};
|
||||
let (completed_at_ms, decision_source) = match completion {
|
||||
Some((completed_at_ms, decision_source)) => {
|
||||
(Some(completed_at_ms), Some(decision_source))
|
||||
@@ -128,7 +148,7 @@ impl ChatWidget {
|
||||
GuardianAssessmentDecisionSource::Agent
|
||||
}
|
||||
}),
|
||||
action: action.into(),
|
||||
action,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -164,6 +164,7 @@ pub(super) use codex_terminal_detection::TerminalInfo;
|
||||
pub(super) use codex_terminal_detection::TerminalName;
|
||||
pub(super) use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
pub(super) use codex_utils_approval_presets::builtin_approval_presets;
|
||||
pub(super) use codex_utils_path_uri::ApiPathString;
|
||||
pub(super) use crossterm::event::KeyCode;
|
||||
pub(super) use crossterm::event::KeyEvent;
|
||||
pub(super) use crossterm::event::KeyModifiers;
|
||||
|
||||
@@ -89,6 +89,8 @@ fn app_server_exec_approval_request_preserves_permissions_context() {
|
||||
.expect("absolute read path");
|
||||
let write_path = AbsolutePathBuf::try_from(PathBuf::from(test_path_display("/tmp/write")))
|
||||
.expect("absolute write path");
|
||||
let read_api_path = ApiPathString::from_abs_path(&read_path);
|
||||
let write_api_path = ApiPathString::from_abs_path(&write_path);
|
||||
let request = exec_approval_request_from_params(
|
||||
AppServerCommandExecutionRequestApprovalParams {
|
||||
thread_id: "thread-1".to_string(),
|
||||
@@ -109,8 +111,8 @@ fn app_server_exec_approval_request_preserves_permissions_context() {
|
||||
enabled: Some(true),
|
||||
}),
|
||||
file_system: Some(AppServerAdditionalFileSystemPermissions {
|
||||
read: Some(vec![read_path.clone()]),
|
||||
write: Some(vec![write_path.clone()]),
|
||||
read: Some(vec![read_api_path.clone()]),
|
||||
write: Some(vec![write_api_path.clone()]),
|
||||
glob_scan_max_depth: None,
|
||||
entries: None,
|
||||
}),
|
||||
@@ -136,8 +138,8 @@ fn app_server_exec_approval_request_preserves_permissions_context() {
|
||||
enabled: Some(true),
|
||||
}),
|
||||
file_system: Some(AppServerAdditionalFileSystemPermissions {
|
||||
read: Some(vec![read_path]),
|
||||
write: Some(vec![write_path]),
|
||||
read: Some(vec![read_api_path]),
|
||||
write: Some(vec![write_api_path]),
|
||||
glob_scan_max_depth: None,
|
||||
entries: None,
|
||||
}),
|
||||
@@ -274,6 +276,8 @@ fn app_server_request_permissions_preserves_file_system_permissions() {
|
||||
.expect("absolute read path");
|
||||
let write_path = AbsolutePathBuf::try_from(PathBuf::from(test_path_display("/tmp/write")))
|
||||
.expect("absolute write path");
|
||||
let read_api_path = ApiPathString::from_abs_path(&read_path);
|
||||
let write_api_path = ApiPathString::from_abs_path(&write_path);
|
||||
let cwd =
|
||||
AbsolutePathBuf::try_from(PathBuf::from(test_path_display("/tmp"))).expect("absolute cwd");
|
||||
|
||||
@@ -290,13 +294,14 @@ fn app_server_request_permissions_preserves_file_system_permissions() {
|
||||
enabled: Some(true),
|
||||
}),
|
||||
file_system: Some(AppServerAdditionalFileSystemPermissions {
|
||||
read: Some(vec![read_path.clone()]),
|
||||
write: Some(vec![write_path.clone()]),
|
||||
read: Some(vec![read_api_path]),
|
||||
write: Some(vec![write_api_path]),
|
||||
glob_scan_max_depth: None,
|
||||
entries: None,
|
||||
}),
|
||||
},
|
||||
});
|
||||
})
|
||||
.expect("API paths should convert to native paths");
|
||||
|
||||
assert_eq!(
|
||||
request.permissions,
|
||||
|
||||
Reference in New Issue
Block a user