mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
chore: migrate additional permissions to PermissionProfile (#12731)
This PR replaces the old `additional_permissions.fs_read/fs_write` shape with a shared `PermissionProfile` model and wires it through the command approval, sandboxing, protocol, and TUI layers. The schema is adopted from the `SkillManifestPermissions`, which is also refactored to use this unified struct. This helps us easily expose permission profiles in app server/core as a follow-up.
This commit is contained in:
@@ -24,7 +24,7 @@ use crate::function_tool::FunctionCallError;
|
||||
use crate::sandboxing::SandboxPermissions;
|
||||
use crate::sandboxing::normalize_additional_permissions;
|
||||
pub use apply_patch::ApplyPatchHandler;
|
||||
use codex_protocol::models::AdditionalPermissions;
|
||||
use codex_protocol::models::PermissionProfile;
|
||||
use codex_protocol::protocol::AskForApproval;
|
||||
pub use dynamic::DynamicToolHandler;
|
||||
pub use grep_files::GrepFilesHandler;
|
||||
@@ -62,9 +62,9 @@ pub(super) fn normalize_and_validate_additional_permissions(
|
||||
request_permission_enabled: bool,
|
||||
approval_policy: AskForApproval,
|
||||
sandbox_permissions: SandboxPermissions,
|
||||
additional_permissions: Option<AdditionalPermissions>,
|
||||
additional_permissions: Option<PermissionProfile>,
|
||||
cwd: &Path,
|
||||
) -> Result<Option<AdditionalPermissions>, String> {
|
||||
) -> Result<Option<PermissionProfile>, String> {
|
||||
let uses_additional_permissions = matches!(
|
||||
sandbox_permissions,
|
||||
SandboxPermissions::WithAdditionalPermissions
|
||||
@@ -87,14 +87,14 @@ pub(super) fn normalize_and_validate_additional_permissions(
|
||||
}
|
||||
let Some(additional_permissions) = additional_permissions else {
|
||||
return Err(
|
||||
"missing `additional_permissions`; provide `fs_read` and/or `fs_write` when using `with_additional_permissions`"
|
||||
"missing `additional_permissions`; provide `file_system.read` and/or `file_system.write` when using `with_additional_permissions`"
|
||||
.to_string(),
|
||||
);
|
||||
};
|
||||
let normalized = normalize_additional_permissions(additional_permissions, cwd)?;
|
||||
if normalized.is_empty() {
|
||||
return Err(
|
||||
"`additional_permissions` must include at least one path in `fs_read` or `fs_write`"
|
||||
"`additional_permissions` must include at least one path in `file_system.read` or `file_system.write`"
|
||||
.to_string(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ use crate::tools::runtimes::shell::ShellRuntime;
|
||||
use crate::tools::runtimes::shell::ShellRuntimeBackend;
|
||||
use crate::tools::sandboxing::ToolCtx;
|
||||
use crate::tools::spec::ShellCommandBackendConfig;
|
||||
use codex_protocol::models::AdditionalPermissions;
|
||||
use codex_protocol::models::PermissionProfile;
|
||||
|
||||
pub struct ShellHandler;
|
||||
|
||||
@@ -50,7 +50,7 @@ pub struct ShellCommandHandler {
|
||||
struct RunExecLikeArgs {
|
||||
tool_name: String,
|
||||
exec_params: ExecParams,
|
||||
additional_permissions: Option<AdditionalPermissions>,
|
||||
additional_permissions: Option<PermissionProfile>,
|
||||
prefix_rule: Option<Vec<String>>,
|
||||
session: Arc<crate::codex::Session>,
|
||||
turn: Arc<TurnContext>,
|
||||
|
||||
@@ -21,8 +21,8 @@ use crate::unified_exec::UnifiedExecProcessManager;
|
||||
use crate::unified_exec::UnifiedExecResponse;
|
||||
use crate::unified_exec::WriteStdinRequest;
|
||||
use async_trait::async_trait;
|
||||
use codex_protocol::models::AdditionalPermissions;
|
||||
use codex_protocol::models::FunctionCallOutputBody;
|
||||
use codex_protocol::models::PermissionProfile;
|
||||
use serde::Deserialize;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
@@ -47,7 +47,7 @@ pub(crate) struct ExecCommandArgs {
|
||||
#[serde(default)]
|
||||
sandbox_permissions: SandboxPermissions,
|
||||
#[serde(default)]
|
||||
additional_permissions: Option<AdditionalPermissions>,
|
||||
additional_permissions: Option<PermissionProfile>,
|
||||
#[serde(default)]
|
||||
justification: Option<String>,
|
||||
#[serde(default)]
|
||||
|
||||
@@ -10,7 +10,7 @@ use crate::sandboxing::CommandSpec;
|
||||
use crate::sandboxing::SandboxPermissions;
|
||||
use crate::shell::Shell;
|
||||
use crate::tools::sandboxing::ToolError;
|
||||
use codex_protocol::models::AdditionalPermissions;
|
||||
use codex_protocol::models::PermissionProfile;
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
|
||||
@@ -26,7 +26,7 @@ pub(crate) fn build_command_spec(
|
||||
env: &HashMap<String, String>,
|
||||
expiration: ExecExpiration,
|
||||
sandbox_permissions: SandboxPermissions,
|
||||
additional_permissions: Option<AdditionalPermissions>,
|
||||
additional_permissions: Option<PermissionProfile>,
|
||||
justification: Option<String>,
|
||||
) -> Result<CommandSpec, ToolError> {
|
||||
let (program, args) = command
|
||||
|
||||
@@ -31,7 +31,7 @@ use crate::tools::sandboxing::ToolRuntime;
|
||||
use crate::tools::sandboxing::sandbox_override_for_first_attempt;
|
||||
use crate::tools::sandboxing::with_cached_approval;
|
||||
use codex_network_proxy::NetworkProxy;
|
||||
use codex_protocol::models::AdditionalPermissions;
|
||||
use codex_protocol::models::PermissionProfile;
|
||||
use codex_protocol::protocol::ReviewDecision;
|
||||
use futures::future::BoxFuture;
|
||||
use std::collections::HashMap;
|
||||
@@ -46,7 +46,7 @@ pub struct ShellRequest {
|
||||
pub explicit_env_overrides: HashMap<String, String>,
|
||||
pub network: Option<NetworkProxy>,
|
||||
pub sandbox_permissions: SandboxPermissions,
|
||||
pub additional_permissions: Option<AdditionalPermissions>,
|
||||
pub additional_permissions: Option<PermissionProfile>,
|
||||
pub justification: Option<String>,
|
||||
pub exec_approval_requirement: ExecApprovalRequirement,
|
||||
}
|
||||
@@ -89,7 +89,7 @@ pub(crate) struct ApprovalKey {
|
||||
command: Vec<String>,
|
||||
cwd: PathBuf,
|
||||
sandbox_permissions: SandboxPermissions,
|
||||
additional_permissions: Option<AdditionalPermissions>,
|
||||
additional_permissions: Option<PermissionProfile>,
|
||||
}
|
||||
|
||||
impl ShellRuntime {
|
||||
|
||||
@@ -32,7 +32,7 @@ use crate::unified_exec::UnifiedExecError;
|
||||
use crate::unified_exec::UnifiedExecProcess;
|
||||
use crate::unified_exec::UnifiedExecProcessManager;
|
||||
use codex_network_proxy::NetworkProxy;
|
||||
use codex_protocol::models::AdditionalPermissions;
|
||||
use codex_protocol::models::PermissionProfile;
|
||||
use codex_protocol::protocol::ReviewDecision;
|
||||
use futures::future::BoxFuture;
|
||||
use std::collections::HashMap;
|
||||
@@ -47,7 +47,7 @@ pub struct UnifiedExecRequest {
|
||||
pub network: Option<NetworkProxy>,
|
||||
pub tty: bool,
|
||||
pub sandbox_permissions: SandboxPermissions,
|
||||
pub additional_permissions: Option<AdditionalPermissions>,
|
||||
pub additional_permissions: Option<PermissionProfile>,
|
||||
pub justification: Option<String>,
|
||||
pub exec_approval_requirement: ExecApprovalRequirement,
|
||||
}
|
||||
@@ -58,7 +58,7 @@ pub struct UnifiedExecApprovalKey {
|
||||
pub cwd: PathBuf,
|
||||
pub tty: bool,
|
||||
pub sandbox_permissions: SandboxPermissions,
|
||||
pub additional_permissions: Option<AdditionalPermissions>,
|
||||
pub additional_permissions: Option<PermissionProfile>,
|
||||
}
|
||||
|
||||
pub struct UnifiedExecRuntime<'a> {
|
||||
|
||||
@@ -256,29 +256,36 @@ fn create_approval_parameters(request_permission_enabled: bool) -> BTreeMap<Stri
|
||||
properties.insert(
|
||||
"additional_permissions".to_string(),
|
||||
JsonSchema::Object {
|
||||
properties: BTreeMap::from([
|
||||
(
|
||||
"fs_read".to_string(),
|
||||
JsonSchema::Array {
|
||||
items: Box::new(JsonSchema::String { description: None }),
|
||||
description: Some(
|
||||
"Additional filesystem paths to grant read access for this command."
|
||||
.to_string(),
|
||||
properties: BTreeMap::from([(
|
||||
"file_system".to_string(),
|
||||
JsonSchema::Object {
|
||||
properties: BTreeMap::from([
|
||||
(
|
||||
"read".to_string(),
|
||||
JsonSchema::Array {
|
||||
items: Box::new(JsonSchema::String { description: None }),
|
||||
description: Some(
|
||||
"Additional filesystem paths to grant read access for this command."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
(
|
||||
"fs_write".to_string(),
|
||||
JsonSchema::Array {
|
||||
items: Box::new(JsonSchema::String { description: None }),
|
||||
description: Some(
|
||||
"Additional filesystem paths to grant write access for this command."
|
||||
.to_string(),
|
||||
(
|
||||
"write".to_string(),
|
||||
JsonSchema::Array {
|
||||
items: Box::new(JsonSchema::String { description: None }),
|
||||
description: Some(
|
||||
"Additional filesystem paths to grant write access for this command."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
]),
|
||||
required: None,
|
||||
]),
|
||||
required: None,
|
||||
additional_properties: Some(false.into()),
|
||||
},
|
||||
)]),
|
||||
required: Some(vec!["file_system".to_string()]),
|
||||
additional_properties: Some(false.into()),
|
||||
},
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user