mirror of
https://github.com/openai/codex.git
synced 2026-10-17 17:08:55 +00:00
Expose uncompiled permission profile selection (#39752)
## What changed - Add `resolve_permission_profile_selection` to select the effective profile using configured defaults, managed requirements, and allowlists. - Return the merged configured and managed profile catalog without compiling platform-specific paths, leaving path interpretation to the executor. ## Testing - Verify that a managed default overrides a configured default while preserving Windows-style paths. - Verify that an allowlisted but undefined profile is rejected. GitOrigin-RevId: 0172193d48f0346522f931d3b806054895d199c0
This commit is contained in:
@@ -159,6 +159,7 @@ mod managed_features;
|
||||
mod network_proxy_spec;
|
||||
mod otel;
|
||||
mod permission_profile_catalog;
|
||||
mod permission_profile_selection;
|
||||
mod permissions;
|
||||
mod requirements;
|
||||
mod resolved_permission_profile;
|
||||
@@ -182,6 +183,8 @@ pub use permission_profile_catalog::permission_profile_catalog;
|
||||
use permission_profile_catalog::permission_profile_catalog_from_permissions;
|
||||
use permission_profile_catalog::permission_profile_is_allowed;
|
||||
use permission_profile_catalog::validate_permission_profile_for_deny_read;
|
||||
pub use permission_profile_selection::ResolvedPermissionProfileSelection;
|
||||
pub use permission_profile_selection::resolve_permission_profile_selection;
|
||||
pub(crate) use permissions::is_builtin_permission_profile_name;
|
||||
pub(crate) use resolved_permission_profile::PermissionProfileState;
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
use codex_config::ConfigRequirementsToml;
|
||||
use codex_config::permissions_toml::PermissionsToml;
|
||||
|
||||
/// A selected permission profile and its uncompiled configured and managed catalog.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct ResolvedPermissionProfileSelection<'a> {
|
||||
/// The effective profile selected by configuration and managed requirements.
|
||||
pub profile_id: Option<&'a str>,
|
||||
/// Configured and managed named profiles, without platform-specific compilation.
|
||||
pub profiles: Option<PermissionsToml>,
|
||||
}
|
||||
|
||||
/// Resolves the effective permission profile without interpreting profile paths.
|
||||
///
|
||||
/// Managed profiles and allowlists are applied using Core's normal selection rules,
|
||||
/// while the merged profile catalog remains uncompiled for the executor to interpret.
|
||||
pub fn resolve_permission_profile_selection<'a>(
|
||||
configured_profiles: Option<&PermissionsToml>,
|
||||
configured_default_profile_id: Option<&'a str>,
|
||||
requirements: &'a ConfigRequirementsToml,
|
||||
) -> std::io::Result<ResolvedPermissionProfileSelection<'a>> {
|
||||
let selection = super::resolve_effective_permission_selection(
|
||||
configured_profiles,
|
||||
/*default_permissions_override*/ None,
|
||||
/*persisted_profile_id*/ None,
|
||||
configured_default_profile_id,
|
||||
requirements,
|
||||
&mut Vec::new(),
|
||||
)?;
|
||||
|
||||
Ok(ResolvedPermissionProfileSelection {
|
||||
profile_id: selection.selected_profile_id,
|
||||
profiles: selection.profiles,
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "permission_profile_selection_tests.rs"]
|
||||
mod tests;
|
||||
@@ -0,0 +1,96 @@
|
||||
use crate::config::ResolvedPermissionProfileSelection;
|
||||
use crate::config::resolve_permission_profile_selection;
|
||||
use codex_config::ConfigRequirementsToml;
|
||||
use codex_config::permissions_toml::PermissionsToml;
|
||||
use pretty_assertions::assert_eq;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
#[test]
|
||||
fn resolves_managed_profile_without_compiling_executor_paths() -> anyhow::Result<()> {
|
||||
let configured_profiles = toml::from_str::<PermissionsToml>(
|
||||
r#"
|
||||
[configured-windows]
|
||||
extends = ":workspace"
|
||||
|
||||
[configured-windows.workspace_roots]
|
||||
'C:\Users\agent\workspace' = true
|
||||
|
||||
[configured-windows.filesystem]
|
||||
'C:\Users\agent\workspace' = "write"
|
||||
"#,
|
||||
)?;
|
||||
let requirements = toml::from_str::<ConfigRequirementsToml>(
|
||||
r#"
|
||||
default_permissions = "managed-windows"
|
||||
|
||||
[allowed_permission_profiles]
|
||||
configured-windows = false
|
||||
managed-windows = true
|
||||
|
||||
[permissions.managed-windows.workspace_roots]
|
||||
'D:\Managed\workspace' = true
|
||||
|
||||
[permissions.managed-windows.filesystem]
|
||||
'D:\Managed\workspace' = "read"
|
||||
"#,
|
||||
)?;
|
||||
let expected_profiles = PermissionsToml {
|
||||
entries: BTreeMap::from([
|
||||
(
|
||||
"configured-windows".to_string(),
|
||||
configured_profiles.entries["configured-windows"].clone(),
|
||||
),
|
||||
(
|
||||
"managed-windows".to_string(),
|
||||
requirements
|
||||
.permissions
|
||||
.as_ref()
|
||||
.expect("managed profiles should deserialize")
|
||||
.profiles["managed-windows"]
|
||||
.clone(),
|
||||
),
|
||||
]),
|
||||
};
|
||||
|
||||
let resolved = resolve_permission_profile_selection(
|
||||
Some(&configured_profiles),
|
||||
Some("configured-windows"),
|
||||
&requirements,
|
||||
)?;
|
||||
|
||||
assert_eq!(
|
||||
resolved,
|
||||
ResolvedPermissionProfileSelection {
|
||||
profile_id: Some("managed-windows"),
|
||||
profiles: Some(expected_profiles),
|
||||
}
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_undefined_allowlisted_permission_profile() -> anyhow::Result<()> {
|
||||
let requirements = toml::from_str::<ConfigRequirementsToml>(
|
||||
r#"
|
||||
default_permissions = "missing-profile"
|
||||
|
||||
[allowed_permission_profiles]
|
||||
missing-profile = true
|
||||
"#,
|
||||
)?;
|
||||
|
||||
let error = resolve_permission_profile_selection(
|
||||
/*configured_profiles*/ None,
|
||||
/*configured_default_profile_id*/ None,
|
||||
&requirements,
|
||||
)
|
||||
.expect_err("undefined allowlisted profiles should be rejected");
|
||||
|
||||
assert_eq!(
|
||||
error.to_string(),
|
||||
"requirements.toml allowed_permission_profiles refers to undefined profile `missing-profile`"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user