From 0340e12f5dc468f35ff922065ac1800459939b08 Mon Sep 17 00:00:00 2001 From: Krish Chainani Date: Wed, 26 Aug 2026 22:49:01 +0000 Subject: [PATCH] Allow bundled browser plugins to run executor cleanup hooks (#40993) ## Why Executor plugin manifests are unsigned, so cleanup hooks must remain limited to explicitly trusted plugin identities and MCP targets. ## What changed - Allow the bundled Browser, Chrome, Chrome Dev, and Chrome Internal plugins to run the existing `Stop` hook for `node_repl.turn_ended`. - Continue allowing the bundled Computer Use plugin and rejecting unlisted or lookalike marketplace identities. ## Testing - Extend manifest-filtering coverage for unlisted bundled plugins and marketplace name variants. GitOrigin-RevId: 1ad5d679a1530994df5a9628c2117ce509fec9ad --- codex-rs/core-plugins/src/executor_hooks.rs | 36 ++++++++++++++++--- .../core-plugins/src/executor_hooks_tests.rs | 17 ++++++++- 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/codex-rs/core-plugins/src/executor_hooks.rs b/codex-rs/core-plugins/src/executor_hooks.rs index 58d1ea6266..3bbd36cfb9 100644 --- a/codex-rs/core-plugins/src/executor_hooks.rs +++ b/codex-rs/core-plugins/src/executor_hooks.rs @@ -18,21 +18,47 @@ struct AllowlistedExecutorPluginHook { } // Executor plugin manifests are unsigned, so temporarily hardcode the expected -// bundled cleanup hook identity and MCP target until plugin signing lands. -const ALLOWLISTED_EXECUTOR_PLUGIN_HOOKS: &[AllowlistedExecutorPluginHook] = - &[AllowlistedExecutorPluginHook { +// bundled plugin identities and cleanup MCP target until plugin signing lands. +const ALLOWLISTED_EXECUTOR_PLUGIN_HOOKS: &[AllowlistedExecutorPluginHook] = &[ + AllowlistedExecutorPluginHook { + plugin_id: "browser@openai-bundled", + event: HookEventName::Stop, + server: "node_repl", + tool: "turn_ended", + }, + AllowlistedExecutorPluginHook { + plugin_id: "chrome@openai-bundled", + event: HookEventName::Stop, + server: "node_repl", + tool: "turn_ended", + }, + AllowlistedExecutorPluginHook { + plugin_id: "chrome-dev@openai-bundled", + event: HookEventName::Stop, + server: "node_repl", + tool: "turn_ended", + }, + AllowlistedExecutorPluginHook { + plugin_id: "chrome-internal@openai-bundled", + event: HookEventName::Stop, + server: "node_repl", + tool: "turn_ended", + }, + AllowlistedExecutorPluginHook { plugin_id: "computer-use@openai-bundled", event: HookEventName::Stop, server: "node_repl", tool: "turn_ended", - }]; + }, +]; /// Returns accepted inline hook sources from executor-discovered plugin manifests. /// /// Executor scoped hooks are best-effort because executor capabilities can become available /// after earlier lifecycle events have passed. /// -/// Note: Executor manifests are not signed yet, so temporarily we only admit the known Computer Use cleanup hook. +/// Note: Executor manifests are not signed yet, so temporarily we only admit the known cleanup +/// hook from the bundled Browser, Chrome, Chrome Dev, Chrome Internal, and Computer Use plugins. pub fn executor_plugin_hook_sources( snapshot: &ExecutorCapabilityDiscoverySnapshot, ) -> Vec { diff --git a/codex-rs/core-plugins/src/executor_hooks_tests.rs b/codex-rs/core-plugins/src/executor_hooks_tests.rs index 79682fac01..60fe716f45 100644 --- a/codex-rs/core-plugins/src/executor_hooks_tests.rs +++ b/codex-rs/core-plugins/src/executor_hooks_tests.rs @@ -186,10 +186,25 @@ fn ignores_unallowlisted_executor_plugin_hooks() { wrong_matcher["hooks"]["hooks"]["Stop"][0]["matcher"] = json!("unexpected"); for (name, plugin_id, manifest) in [ ( - "wrong plugin id", + "unallowlisted bundled plugin", + "another-plugin@openai-bundled", + cleanup_hook_manifest(), + ), + ( + "wrong marketplace", "computer-use@other", cleanup_hook_manifest(), ), + ( + "bundled alpha marketplace", + "computer-use@openai-bundled-alpha", + cleanup_hook_manifest(), + ), + ( + "bundled marketplace suffix", + "computer-use@fake-openai-bundled", + cleanup_hook_manifest(), + ), ("wrong event", "computer-use@openai-bundled", wrong_event), ( "wrong handler",