diff --git a/src/commands/doctor-security.ts b/src/commands/doctor-security.ts index caeac21f135..2a6f46a8b4a 100644 --- a/src/commands/doctor-security.ts +++ b/src/commands/doctor-security.ts @@ -1,4 +1,4 @@ -import { listChannelPlugins } from "../channels/plugins/index.js"; +import { listReadOnlyChannelPluginsForConfig } from "../channels/plugins/read-only.js"; import type { ChannelId } from "../channels/plugins/types.public.js"; import { formatCliCommand } from "../cli/command-format.js"; import type { OpenClawConfig, GatewayBindMode } from "../config/config.js"; @@ -304,7 +304,10 @@ export async function noteSecurityWarnings(cfg: OpenClawConfig) { } }; - for (const plugin of listChannelPlugins()) { + for (const plugin of listReadOnlyChannelPluginsForConfig(cfg, { + includePersistedAuthState: true, + includeSetupRuntimeFallback: false, + })) { if (!plugin.security) { continue; } diff --git a/src/security/audit-channel.ts b/src/security/audit-channel.ts index ead65992d90..8feb38df275 100644 --- a/src/security/audit-channel.ts +++ b/src/security/audit-channel.ts @@ -3,7 +3,7 @@ import { hasResolvedCredentialValue, } from "../channels/account-snapshot-fields.js"; import { resolveChannelDefaultAccountId } from "../channels/plugins/helpers.js"; -import type { listChannelPlugins } from "../channels/plugins/index.js"; +import type { ChannelPlugin } from "../channels/plugins/types.plugin.js"; import type { ChannelId } from "../channels/plugins/types.public.js"; import { inspectReadOnlyChannelAccount } from "../channels/read-only-account-inspect.js"; import { formatCliCommand } from "../cli/command-format.js"; @@ -80,7 +80,7 @@ function formatChannelAccountNote(params: { export async function collectChannelSecurityFindings(params: { cfg: OpenClawConfig; sourceConfig?: OpenClawConfig; - plugins: ReturnType; + plugins: ChannelPlugin[]; }): Promise { const findings: SecurityAuditFinding[] = []; const sourceConfig = params.sourceConfig ?? params.cfg; diff --git a/src/security/audit.ts b/src/security/audit.ts index 587ddd65db9..7b05818b84b 100644 --- a/src/security/audit.ts +++ b/src/security/audit.ts @@ -1,7 +1,7 @@ import path from "node:path"; import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent-scope.js"; import { resolveSandboxConfigForAgent } from "../agents/sandbox/config.js"; -import type { listChannelPlugins } from "../channels/plugins/index.js"; +import type { ChannelPlugin } from "../channels/plugins/types.plugin.js"; import type { ConfigFileSnapshot, OpenClawConfig } from "../config/config.js"; import { resolveConfigPath, resolveStateDir } from "../config/paths.js"; import { type ExecApprovalsFile, loadExecApprovals } from "../infra/exec-approvals.js"; @@ -57,7 +57,7 @@ export type SecurityAuditOptions = { /** Time limit for deep gateway probe. */ deepTimeoutMs?: number; /** Dependency injection for tests. */ - plugins?: ReturnType; + plugins?: ChannelPlugin[]; /** Dependency injection for tests (Windows ACL checks). */ execIcacls?: ExecFn; /** Dependency injection for tests (Docker label checks). */ @@ -88,21 +88,20 @@ export type AuditExecutionContext = { execIcacls?: ExecFn; execDockerRawFn?: ExecDockerRawFn; probeGatewayFn?: ProbeGatewayFn; - plugins?: ReturnType; + plugins?: ChannelPlugin[]; configSnapshot: ConfigFileSnapshot | null; codeSafetySummaryCache: Map>; deepProbeAuth?: { token?: string; password?: string }; workspaceDir?: string; }; -let channelPluginsModulePromise: Promise | undefined; +let readOnlyChannelPluginsModulePromise: + | Promise + | undefined; let auditNonDeepModulePromise: Promise | undefined; let auditChannelModulePromise: | Promise | undefined; -let pluginRegistryLoaderModulePromise: - | Promise - | undefined; let pluginMetadataRegistryLoaderModulePromise: | Promise | undefined; @@ -122,9 +121,9 @@ let gatewayProbeDepsPromise: }> | undefined; -async function loadChannelPlugins() { - channelPluginsModulePromise ??= import("../channels/plugins/index.js"); - return await channelPluginsModulePromise; +async function loadReadOnlyChannelPlugins() { + readOnlyChannelPluginsModulePromise ??= import("../channels/plugins/read-only.js"); + return await readOnlyChannelPluginsModulePromise; } async function loadAuditNonDeepModule() { @@ -137,11 +136,6 @@ async function loadAuditChannelModule() { return await auditChannelModulePromise; } -async function loadPluginRegistryLoaderModule() { - pluginRegistryLoaderModulePromise ??= import("../plugins/runtime/runtime-registry-loader.js"); - return await pluginRegistryLoaderModulePromise; -} - async function loadPluginMetadataRegistryLoaderModule() { pluginMetadataRegistryLoaderModulePromise ??= import("../plugins/runtime/metadata-registry-loader.js"); @@ -1050,16 +1044,16 @@ export async function runSecurityAudit(opts: SecurityAuditOptions): Promise