mirror of
https://github.com/openai/codex.git
synced 2026-05-01 03:42:05 +03:00
Surface skill permission profiles in zsh-fork exec approvals (#12753)
## Summary
- Preserve each skill’s raw permissions block as a permission_profile on
SkillMetadata during skill loading.
- Keep compiling that same metadata into the existing runtime
Permissions object, so current enforcement
behavior stays intact.
- When zsh-fork intercepts execution of a script that belongs to a
skill, include the skill’s
permission_profile in the exec approval request.
- This lets approval UIs show the extra filesystem access the skill
declared when prompting for approval.
This commit is contained in:
@@ -2,6 +2,10 @@
|
||||
|
||||
use anyhow::Result;
|
||||
use codex_core::features::Feature;
|
||||
#[cfg(unix)]
|
||||
use codex_protocol::models::FileSystemPermissions;
|
||||
#[cfg(unix)]
|
||||
use codex_protocol::models::PermissionProfile;
|
||||
use codex_protocol::protocol::AskForApproval;
|
||||
use codex_protocol::protocol::EventMsg;
|
||||
use codex_protocol::protocol::Op;
|
||||
@@ -45,6 +49,14 @@ description: {name} skill
|
||||
Ok(script_path)
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn write_skill_metadata(home: &Path, name: &str, contents: &str) -> Result<()> {
|
||||
let metadata_dir = home.join("skills").join(name).join("agents");
|
||||
fs::create_dir_all(&metadata_dir)?;
|
||||
fs::write(metadata_dir.join("openai.yaml"), contents)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn shell_command_arguments(command: &str) -> Result<String> {
|
||||
Ok(serde_json::to_string(&json!({
|
||||
"command": command,
|
||||
@@ -441,6 +453,19 @@ async fn shell_zsh_fork_prompts_for_skill_script_execution() -> Result<()> {
|
||||
let mut builder = test_codex()
|
||||
.with_pre_build_hook(|home| {
|
||||
write_skill_with_shell_script(home, "mbolin-test-skill", "hello-mbolin.sh").unwrap();
|
||||
write_skill_metadata(
|
||||
home,
|
||||
"mbolin-test-skill",
|
||||
r#"
|
||||
permissions:
|
||||
file_system:
|
||||
read:
|
||||
- "./data"
|
||||
write:
|
||||
- "./output"
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
})
|
||||
.with_config(move |config| {
|
||||
config.features.enable(Feature::ShellTool);
|
||||
@@ -493,6 +518,16 @@ async fn shell_zsh_fork_prompts_for_skill_script_execution() -> Result<()> {
|
||||
};
|
||||
assert_eq!(approval.call_id, tool_call_id);
|
||||
assert_eq!(approval.command, vec![script_path_str.clone()]);
|
||||
assert_eq!(
|
||||
approval.additional_permissions,
|
||||
Some(PermissionProfile {
|
||||
file_system: Some(FileSystemPermissions {
|
||||
read: Some(vec![PathBuf::from("./data")]),
|
||||
write: Some(vec![PathBuf::from("./output")]),
|
||||
}),
|
||||
..Default::default()
|
||||
})
|
||||
);
|
||||
|
||||
test.codex
|
||||
.submit(Op::ExecApproval {
|
||||
|
||||
Reference in New Issue
Block a user