


























@@ -4,8 +4,11 @@ import {
44materializeWindowsSpawnProgram,
55resolveWindowsSpawnProgram,
66} from "../../plugin-sdk/windows-spawn.js";
7-import { sanitizeEnvVars } from "./sanitize-env-vars.js";
8-import type { EnvSanitizationOptions } from "./sanitize-env-vars.js";
7+import {
8+sanitizeEnvVars,
9+sanitizeExplicitSandboxEnvVars,
10+type EnvSanitizationOptions,
11+} from "./sanitize-env-vars.js";
9121013type ExecDockerRawOptions = {
1114allowFailure?: boolean;
@@ -165,7 +168,10 @@ export function execDockerRaw(
165168import { formatCliCommand } from "../../cli/command-format.js";
166169import { markOpenClawExecEnv } from "../../infra/openclaw-exec-env.js";
167170import { defaultRuntime } from "../../runtime.js";
168-import { computeSandboxConfigHash } from "./config-hash.js";
171+import {
172+computeSandboxConfigHash,
173+SANDBOX_DOCKER_EXPLICIT_ENV_POLICY_EPOCH,
174+} from "./config-hash.js";
169175import { DEFAULT_SANDBOX_IMAGE } from "./constants.js";
170176import { readRegistryEntry, updateRegistry } from "./registry.js";
171177import { resolveSandboxAgentId, resolveSandboxScopeKey, slugifySessionKey } from "./shared.js";
@@ -179,6 +185,31 @@ const HOT_CONTAINER_WINDOW_MS = 5 * 60 * 1000;
179185180186export type ExecDockerOptions = ExecDockerRawOptions;
181187188+function envRecordsEqual(left: Record<string, string>, right: Record<string, string>): boolean {
189+const leftEntries = Object.entries(left).toSorted(([leftKey], [rightKey]) =>
190+leftKey.localeCompare(rightKey),
191+);
192+const rightEntries = Object.entries(right).toSorted(([leftKey], [rightKey]) =>
193+leftKey.localeCompare(rightKey),
194+);
195+if (leftEntries.length !== rightEntries.length) {
196+return false;
197+}
198+return leftEntries.every(([key, value], index) => {
199+const rightEntry = rightEntries[index];
200+return rightEntry?.[0] === key && rightEntry[1] === value;
201+});
202+}
203+204+export function resolveDockerEnvPolicyEpoch(env: Record<string, string | undefined> | undefined) {
205+const explicitEnv = env ?? {};
206+const previousAllowed = sanitizeEnvVars(explicitEnv).allowed;
207+const currentAllowed = sanitizeExplicitSandboxEnvVars(explicitEnv).allowed;
208+return envRecordsEqual(previousAllowed, currentAllowed)
209+ ? undefined
210+ : SANDBOX_DOCKER_EXPLICIT_ENV_POLICY_EPOCH;
211+}
212+182213export async function execDocker(args: string[], opts?: ExecDockerOptions) {
183214const result = await execDockerRaw(args, opts);
184215return {
@@ -382,6 +413,11 @@ export function buildSandboxCreateArgs(params: {
382413allowSourcesOutsideAllowedRoots?: boolean;
383414allowReservedContainerTargets?: boolean;
384415allowContainerNamespaceJoin?: boolean;
416+/**
417+ * @deprecated Docker container creation now treats cfg.env as explicit sandbox
418+ * configuration and ignores host-env name filters. This field is kept so SDK
419+ * callers with existing object literals do not hit excess-property failures.
420+ */
385421envSanitizationOptions?: EnvSanitizationOptions;
386422}) {
387423// Runtime security validation: blocks dangerous bind mounts, network modes, and profiles.
@@ -425,12 +461,16 @@ export function buildSandboxCreateArgs(params: {
425461if (params.cfg.user) {
426462args.push("--user", params.cfg.user);
427463}
428-const envSanitization = sanitizeEnvVars(params.cfg.env ?? {}, params.envSanitizationOptions);
464+const envSanitization = sanitizeExplicitSandboxEnvVars(params.cfg.env ?? {});
429465if (envSanitization.blocked.length > 0) {
430-log.warn(`Blocked sensitive environment variables: ${envSanitization.blocked.join(", ")}`);
466+log.warn(
467+`Blocked invalid configured sandbox environment variables: ${envSanitization.blocked.join(", ")}`,
468+);
431469}
432470if (envSanitization.warnings.length > 0) {
433-log.warn(`Suspicious environment variables: ${envSanitization.warnings.join(", ")}`);
471+log.warn(
472+`Suspicious configured sandbox environment variables: ${envSanitization.warnings.join(", ")}`,
473+);
434474}
435475for (const [key, value] of Object.entries(markOpenClawExecEnv(envSanitization.allowed))) {
436476args.push("--env", `${key}=${value}`);
@@ -562,6 +602,7 @@ export async function ensureSandboxContainer(params: {
562602const containerName = name.slice(0, 63);
563603const expectedHash = computeSandboxConfigHash({
564604docker: params.cfg.docker,
605+dockerEnvPolicyEpoch: resolveDockerEnvPolicyEpoch(params.cfg.docker.env),
565606workspaceAccess: params.cfg.workspaceAccess,
566607workspaceDir: params.workspaceDir,
567608agentWorkspaceDir: params.agentWorkspaceDir,
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。