From f76f6212b229d06537a9141e6da8033e23f7d0c3 Mon Sep 17 00:00:00 2001 From: Gustavo Madeira Santana Date: Tue, 21 Apr 2026 20:30:17 -0400 Subject: [PATCH] fix: resolve explicit channel owner ids --- src/plugins/channel-plugin-ids.test.ts | 19 +++++++++++++++++++ src/plugins/channel-presence-policy.ts | 10 ++++++++++ src/plugins/manifest-owner-policy.ts | 2 ++ 3 files changed, 31 insertions(+) diff --git a/src/plugins/channel-plugin-ids.test.ts b/src/plugins/channel-plugin-ids.test.ts index 3c4c71a5b02..8234153f1ca 100644 --- a/src/plugins/channel-plugin-ids.test.ts +++ b/src/plugins/channel-plugin-ids.test.ts @@ -643,6 +643,25 @@ describe("resolveConfiguredChannelPluginIds", () => { ).toEqual([]); }); + it("keeps explicitly configured bundled channel owners under restrictive allowlists", () => { + expect( + resolveConfiguredChannelPluginIds({ + config: { + channels: { + "demo-channel": { + token: "configured", + }, + }, + plugins: { + allow: ["browser"], + }, + } as OpenClawConfig, + workspaceDir: "/tmp", + env: {}, + }), + ).toEqual(["demo-channel"]); + }); + it("blocks bundled activation owners when explicitly denied", () => { expect( resolveConfiguredChannelPluginIds({ diff --git a/src/plugins/channel-presence-policy.ts b/src/plugins/channel-presence-policy.ts index 99df814364b..94f4f61f09e 100644 --- a/src/plugins/channel-presence-policy.ts +++ b/src/plugins/channel-presence-policy.ts @@ -196,11 +196,20 @@ function isChannelPluginEligibleForScopedOwnership(params: { plugin: PluginManifestRecord; normalizedConfig: ReturnType; rootConfig: OpenClawConfig; + channelId?: string; }): boolean { + const allowRestrictiveAllowlistBypass = + params.channelId !== undefined && + isBundledManifestOwner(params.plugin) && + hasExplicitChannelConfig({ + config: params.rootConfig, + channelId: params.channelId, + }); if ( !passesManifestOwnerBasePolicy({ plugin: params.plugin, normalizedConfig: params.normalizedConfig, + allowRestrictiveAllowlistBypass, }) ) { return false; @@ -495,6 +504,7 @@ function resolveScopedChannelOwnerPluginIds(params: { plugin, normalizedConfig, rootConfig: trustConfig, + channelId: channelIds.find((channelId) => recordDeclaresChannel(plugin, channelId)), }); }) .map((plugin) => plugin.id) diff --git a/src/plugins/manifest-owner-policy.ts b/src/plugins/manifest-owner-policy.ts index a668b127df0..44d7b5d6322 100644 --- a/src/plugins/manifest-owner-policy.ts +++ b/src/plugins/manifest-owner-policy.ts @@ -24,6 +24,7 @@ export function passesManifestOwnerBasePolicy(params: { plugin: Pick; normalizedConfig: NormalizedPluginsConfig; allowExplicitlyDisabled?: boolean; + allowRestrictiveAllowlistBypass?: boolean; }): boolean { if (!params.normalizedConfig.enabled) { return false; @@ -38,6 +39,7 @@ export function passesManifestOwnerBasePolicy(params: { return false; } if ( + params.allowRestrictiveAllowlistBypass !== true && params.normalizedConfig.allow.length > 0 && !params.normalizedConfig.allow.includes(params.plugin.id) ) {