refactor(sandbox): centralize dangerous docker override key handling

This commit is contained in:
Peter Steinberger
2026-02-25 02:12:10 +00:00
parent 885452f5c1
commit 91ae82ae19
2 changed files with 43 additions and 62 deletions

View File

@@ -24,6 +24,26 @@ import type {
SandboxScope,
} from "./types.js";
export const DANGEROUS_SANDBOX_DOCKER_BOOLEAN_KEYS = [
"dangerouslyAllowReservedContainerTargets",
"dangerouslyAllowExternalBindSources",
"dangerouslyAllowContainerNamespaceJoin",
] as const;
type DangerousSandboxDockerBooleanKey = (typeof DANGEROUS_SANDBOX_DOCKER_BOOLEAN_KEYS)[number];
type DangerousSandboxDockerBooleans = Pick<SandboxDockerConfig, DangerousSandboxDockerBooleanKey>;
function resolveDangerousSandboxDockerBooleans(
agentDocker?: Partial<SandboxDockerConfig>,
globalDocker?: Partial<SandboxDockerConfig>,
): DangerousSandboxDockerBooleans {
const resolved = {} as DangerousSandboxDockerBooleans;
for (const key of DANGEROUS_SANDBOX_DOCKER_BOOLEAN_KEYS) {
resolved[key] = agentDocker?.[key] ?? globalDocker?.[key];
}
return resolved;
}
export function resolveSandboxBrowserDockerCreateConfig(params: {
docker: SandboxDockerConfig;
browser: SandboxBrowserConfig;
@@ -95,15 +115,7 @@ export function resolveSandboxDockerConfig(params: {
dns: agentDocker?.dns ?? globalDocker?.dns,
extraHosts: agentDocker?.extraHosts ?? globalDocker?.extraHosts,
binds: binds.length ? binds : undefined,
dangerouslyAllowReservedContainerTargets:
agentDocker?.dangerouslyAllowReservedContainerTargets ??
globalDocker?.dangerouslyAllowReservedContainerTargets,
dangerouslyAllowExternalBindSources:
agentDocker?.dangerouslyAllowExternalBindSources ??
globalDocker?.dangerouslyAllowExternalBindSources,
dangerouslyAllowContainerNamespaceJoin:
agentDocker?.dangerouslyAllowContainerNamespaceJoin ??
globalDocker?.dangerouslyAllowContainerNamespaceJoin,
...resolveDangerousSandboxDockerBooleans(agentDocker, globalDocker),
};
}

View File

@@ -1,5 +1,6 @@
import { describe, expect, it } from "vitest";
import {
DANGEROUS_SANDBOX_DOCKER_BOOLEAN_KEYS,
resolveSandboxBrowserConfig,
resolveSandboxDockerConfig,
} from "../agents/sandbox/config.js";
@@ -87,61 +88,29 @@ describe("sandbox docker config", () => {
expect(res.ok).toBe(true);
});
it("uses agent override precedence for dangerouslyAllowContainerNamespaceJoin", () => {
const inherited = resolveSandboxDockerConfig({
scope: "agent",
globalDocker: { dangerouslyAllowContainerNamespaceJoin: true },
agentDocker: {},
});
expect(inherited.dangerouslyAllowContainerNamespaceJoin).toBe(true);
it("uses agent override precedence for dangerous sandbox docker booleans", () => {
for (const key of DANGEROUS_SANDBOX_DOCKER_BOOLEAN_KEYS) {
const inherited = resolveSandboxDockerConfig({
scope: "agent",
globalDocker: { [key]: true },
agentDocker: {},
});
expect(inherited[key]).toBe(true);
const overridden = resolveSandboxDockerConfig({
scope: "agent",
globalDocker: { dangerouslyAllowContainerNamespaceJoin: true },
agentDocker: { dangerouslyAllowContainerNamespaceJoin: false },
});
expect(overridden.dangerouslyAllowContainerNamespaceJoin).toBe(false);
});
const overridden = resolveSandboxDockerConfig({
scope: "agent",
globalDocker: { [key]: true },
agentDocker: { [key]: false },
});
expect(overridden[key]).toBe(false);
it("uses agent override precedence for bind-mount dangerous overrides", () => {
const inherited = resolveSandboxDockerConfig({
scope: "agent",
globalDocker: {
dangerouslyAllowReservedContainerTargets: true,
dangerouslyAllowExternalBindSources: true,
},
agentDocker: {},
});
expect(inherited.dangerouslyAllowReservedContainerTargets).toBe(true);
expect(inherited.dangerouslyAllowExternalBindSources).toBe(true);
const overridden = resolveSandboxDockerConfig({
scope: "agent",
globalDocker: {
dangerouslyAllowReservedContainerTargets: true,
dangerouslyAllowExternalBindSources: true,
},
agentDocker: {
dangerouslyAllowReservedContainerTargets: false,
dangerouslyAllowExternalBindSources: false,
},
});
expect(overridden.dangerouslyAllowReservedContainerTargets).toBe(false);
expect(overridden.dangerouslyAllowExternalBindSources).toBe(false);
const sharedScope = resolveSandboxDockerConfig({
scope: "shared",
globalDocker: {
dangerouslyAllowReservedContainerTargets: true,
dangerouslyAllowExternalBindSources: true,
},
agentDocker: {
dangerouslyAllowReservedContainerTargets: false,
dangerouslyAllowExternalBindSources: false,
},
});
expect(sharedScope.dangerouslyAllowReservedContainerTargets).toBe(true);
expect(sharedScope.dangerouslyAllowExternalBindSources).toBe(true);
const sharedScope = resolveSandboxDockerConfig({
scope: "shared",
globalDocker: { [key]: true },
agentDocker: { [key]: false },
});
expect(sharedScope[key]).toBe(true);
}
});
it("rejects seccomp unconfined via Zod schema validation", () => {