From b9deb57689bef15a9bf77b4aec419e6f7c9a3824 Mon Sep 17 00:00:00 2001 From: gt-oai Date: Fri, 23 Jan 2026 21:52:27 +0000 Subject: [PATCH] Load untrusted rules (#9791) --- codex-rs/core/src/exec_policy.rs | 45 +++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/codex-rs/core/src/exec_policy.rs b/codex-rs/core/src/exec_policy.rs index dea11c860..61c007023 100644 --- a/codex-rs/core/src/exec_policy.rs +++ b/codex-rs/core/src/exec_policy.rs @@ -227,7 +227,9 @@ pub async fn load_exec_policy(config_stack: &ConfigLayerStack) -> Result anyhow::Result<()> { + let project_dir = tempdir()?; + let policy_dir = project_dir.path().join(RULES_DIR_NAME); + fs::create_dir_all(&policy_dir)?; + fs::write( + policy_dir.join("disabled.rules"), + r#"prefix_rule(pattern=["ls"], decision="forbidden")"#, + )?; + + let project_dot_codex_folder = AbsolutePathBuf::from_absolute_path(project_dir.path())?; + let layers = vec![ConfigLayerEntry::new_disabled( + ConfigLayerSource::Project { + dot_codex_folder: project_dot_codex_folder, + }, + TomlValue::Table(Default::default()), + "trust disabled", + )]; + let config_stack = ConfigLayerStack::new( + layers, + ConfigRequirements::default(), + ConfigRequirementsToml::default(), + )?; + + let policy = load_exec_policy(&config_stack).await?; + + assert_eq!( + Evaluation { + decision: Decision::Forbidden, + matched_rules: vec![RuleMatch::PrefixRuleMatch { + matched_prefix: vec!["ls".to_string()], + decision: Decision::Forbidden, + justification: None, + }], + }, + policy.check_multiple([vec!["ls".to_string()]].iter(), &|_| Decision::Allow) + ); + + Ok(()) + } + #[tokio::test] async fn loads_policies_from_multiple_config_layers() -> anyhow::Result<()> { let user_dir = tempdir()?;