mirror of
https://github.com/openai/codex.git
synced 2026-10-27 18:48:37 +00:00
core: merge built-in permission profiles as TOML
This commit is contained in:
@@ -2356,7 +2356,13 @@ async fn default_permissions_profile_can_extend_builtin_workspace() -> std::io::
|
||||
description: None,
|
||||
extends: Some(BUILT_IN_PERMISSION_PROFILE_WORKSPACE.to_string()),
|
||||
workspace_roots: None,
|
||||
filesystem: None,
|
||||
filesystem: Some(FilesystemPermissionsToml {
|
||||
glob_scan_max_depth: None,
|
||||
entries: BTreeMap::from([(
|
||||
":tmpdir".to_string(),
|
||||
FilesystemPermissionToml::Access(FileSystemAccessMode::Read),
|
||||
)]),
|
||||
}),
|
||||
network: Some(NetworkToml {
|
||||
enabled: Some(true),
|
||||
..Default::default()
|
||||
@@ -2383,6 +2389,30 @@ async fn default_permissions_profile_can_extend_builtin_workspace() -> std::io::
|
||||
!policy.can_write_path_with_cwd(&cwd.path().join(".git"), cwd.path()),
|
||||
"expected profile extending :workspace to keep metadata carveouts, policy: {policy:?}"
|
||||
);
|
||||
assert!(
|
||||
policy.entries.iter().any(|entry| matches!(
|
||||
entry,
|
||||
FileSystemSandboxEntry {
|
||||
path: FileSystemPath::Special {
|
||||
value: FileSystemSpecialPath::Tmpdir,
|
||||
},
|
||||
access: FileSystemAccessMode::Read,
|
||||
}
|
||||
)),
|
||||
"expected child :tmpdir read entry to replace the inherited write entry, policy: {policy:?}"
|
||||
);
|
||||
assert!(
|
||||
!policy.entries.iter().any(|entry| matches!(
|
||||
entry,
|
||||
FileSystemSandboxEntry {
|
||||
path: FileSystemPath::Special {
|
||||
value: FileSystemSpecialPath::Tmpdir,
|
||||
},
|
||||
access: FileSystemAccessMode::Write,
|
||||
}
|
||||
)),
|
||||
"expected inherited :tmpdir write entry to be removed, policy: {policy:?}"
|
||||
);
|
||||
assert_eq!(
|
||||
config.permissions.network_sandbox_policy(),
|
||||
NetworkSandboxPolicy::Enabled
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use std::borrow::Cow;
|
||||
use std::collections::BTreeMap;
|
||||
use std::io;
|
||||
use std::path::Component;
|
||||
use std::path::Path;
|
||||
@@ -196,25 +197,59 @@ pub(crate) fn resolve_permission_profile(
|
||||
profile_name: &str,
|
||||
) -> io::Result<ResolvedPermissionProfileToml> {
|
||||
permissions
|
||||
.resolve_profile(profile_name, extensible_builtin_parent_profile_marker)
|
||||
.resolve_profile(profile_name, extensible_builtin_parent_profile)
|
||||
.map_err(|err| io::Error::new(io::ErrorKind::InvalidInput, err.to_string()))
|
||||
}
|
||||
|
||||
/// Built-in parents provide their runtime permissions below. Resolution only
|
||||
/// needs an empty profile marker so inheritance can terminate while preserving
|
||||
/// the built-in parent id in `inherited_profile_names`.
|
||||
fn extensible_builtin_parent_profile_marker(profile_name: &str) -> Option<PermissionProfileToml> {
|
||||
matches!(
|
||||
profile_name,
|
||||
BUILT_IN_READ_ONLY_PROFILE | BUILT_IN_WORKSPACE_PROFILE
|
||||
)
|
||||
.then_some(PermissionProfileToml {
|
||||
description: None,
|
||||
extends: None,
|
||||
workspace_roots: None,
|
||||
filesystem: None,
|
||||
network: None,
|
||||
})
|
||||
fn extensible_builtin_parent_profile(profile_name: &str) -> Option<PermissionProfileToml> {
|
||||
match profile_name {
|
||||
BUILT_IN_READ_ONLY_PROFILE => Some(PermissionProfileToml {
|
||||
description: None,
|
||||
extends: None,
|
||||
workspace_roots: None,
|
||||
filesystem: Some(FilesystemPermissionsToml {
|
||||
glob_scan_max_depth: None,
|
||||
entries: BTreeMap::from([(
|
||||
":root".to_string(),
|
||||
FilesystemPermissionToml::Access(FileSystemAccessMode::Read),
|
||||
)]),
|
||||
}),
|
||||
network: None,
|
||||
}),
|
||||
BUILT_IN_WORKSPACE_PROFILE => Some(PermissionProfileToml {
|
||||
description: None,
|
||||
extends: None,
|
||||
workspace_roots: None,
|
||||
filesystem: Some(FilesystemPermissionsToml {
|
||||
glob_scan_max_depth: None,
|
||||
entries: BTreeMap::from([
|
||||
(
|
||||
":root".to_string(),
|
||||
FilesystemPermissionToml::Access(FileSystemAccessMode::Read),
|
||||
),
|
||||
(
|
||||
":workspace_roots".to_string(),
|
||||
FilesystemPermissionToml::Scoped(BTreeMap::from([
|
||||
(".".to_string(), FileSystemAccessMode::Write),
|
||||
(".git".to_string(), FileSystemAccessMode::Read),
|
||||
(".agents".to_string(), FileSystemAccessMode::Read),
|
||||
(".codex".to_string(), FileSystemAccessMode::Read),
|
||||
])),
|
||||
),
|
||||
(
|
||||
":slash_tmp".to_string(),
|
||||
FilesystemPermissionToml::Access(FileSystemAccessMode::Write),
|
||||
),
|
||||
(
|
||||
":tmpdir".to_string(),
|
||||
FilesystemPermissionToml::Access(FileSystemAccessMode::Write),
|
||||
),
|
||||
]),
|
||||
}),
|
||||
network: None,
|
||||
}),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn network_proxy_config_for_profile_selection(
|
||||
@@ -244,25 +279,10 @@ pub(crate) fn compile_permission_profile(
|
||||
policy_cwd: &Path,
|
||||
startup_warnings: &mut Vec<String>,
|
||||
) -> io::Result<(FileSystemSandboxPolicy, NetworkSandboxPolicy)> {
|
||||
let ResolvedPermissionProfileToml {
|
||||
profile,
|
||||
inherited_profile_names,
|
||||
} = resolve_permission_profile(permissions, profile_name)?;
|
||||
let base_permissions = inherited_profile_names.iter().find_map(|name| {
|
||||
match name.as_str() {
|
||||
BUILT_IN_READ_ONLY_PROFILE => Some(PermissionProfile::read_only()),
|
||||
BUILT_IN_WORKSPACE_PROFILE => Some(PermissionProfile::workspace_write()),
|
||||
_ => None,
|
||||
}
|
||||
.map(|profile| profile.to_runtime_permissions())
|
||||
});
|
||||
let (mut file_system_sandbox_policy, base_network_sandbox_policy) = base_permissions
|
||||
.unwrap_or_else(|| {
|
||||
(
|
||||
FileSystemSandboxPolicy::restricted(Vec::new()),
|
||||
NetworkSandboxPolicy::Restricted,
|
||||
)
|
||||
});
|
||||
let ResolvedPermissionProfileToml { profile, .. } =
|
||||
resolve_permission_profile(permissions, profile_name)?;
|
||||
let mut file_system_sandbox_policy = FileSystemSandboxPolicy::restricted(Vec::new());
|
||||
let base_network_sandbox_policy = NetworkSandboxPolicy::Restricted;
|
||||
if let Some(filesystem) = profile.filesystem.as_ref() {
|
||||
if filesystem.is_empty() && file_system_sandbox_policy.entries.is_empty() {
|
||||
push_warning(
|
||||
@@ -693,6 +713,7 @@ fn parse_special_path(path: &str) -> Option<FileSystemSpecialPath> {
|
||||
":minimal" => Some(FileSystemSpecialPath::Minimal),
|
||||
":workspace_roots" => Some(FileSystemSpecialPath::project_roots(/*subpath*/ None)),
|
||||
":tmpdir" => Some(FileSystemSpecialPath::Tmpdir),
|
||||
":slash_tmp" => Some(FileSystemSpecialPath::SlashTmp),
|
||||
_ if path.starts_with(':') => {
|
||||
Some(FileSystemSpecialPath::unknown(path, /*subpath*/ None))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user