diff --git a/src/security/audit.ts b/src/security/audit.ts index c21d349ccb7..a27289879e0 100644 --- a/src/security/audit.ts +++ b/src/security/audit.ts @@ -6,7 +6,7 @@ import { resolveBrowserConfig, resolveProfile } from "../browser/config.js"; import { resolveBrowserControlAuth } from "../browser/control-auth.js"; import { listChannelPlugins } from "../channels/plugins/index.js"; import { formatCliCommand } from "../cli/command-format.js"; -import type { OpenClawConfig } from "../config/config.js"; +import type { ConfigFileSnapshot, OpenClawConfig } from "../config/config.js"; import { resolveConfigPath, resolveStateDir } from "../config/paths.js"; import { resolveGatewayAuth } from "../gateway/auth.js"; import { buildGatewayConnectionDetails } from "../gateway/call.js"; @@ -104,6 +104,10 @@ export type SecurityAuditOptions = { execIcacls?: ExecFn; /** Dependency injection for tests (Docker label checks). */ execDockerRawFn?: typeof execDockerRaw; + /** Optional preloaded config snapshot to skip audit-time config file reads. */ + configSnapshot?: ConfigFileSnapshot | null; + /** Optional cache for code-safety summaries across repeated deep audits. */ + codeSafetySummaryCache?: Map>; }; function countBySeverity(findings: SecurityAuditFinding[]): SecurityAuditSummary { @@ -1033,11 +1037,14 @@ export async function runSecurityAudit(opts: SecurityAuditOptions): Promise null) + ? opts.configSnapshot !== undefined + ? opts.configSnapshot + : await readConfigSnapshotForAudit({ env, configPath }).catch(() => null) : null; if (opts.includeFilesystem !== false) { - const codeSafetySummaryCache = new Map>(); + const codeSafetySummaryCache = + opts.codeSafetySummaryCache ?? new Map>(); findings.push( ...(await collectFilesystemFindings({ stateDir,