diff --git a/src/agents/pi-tools.policy.ts b/src/agents/pi-tools.policy.ts index b9d5a8e885..caed3ca302 100644 --- a/src/agents/pi-tools.policy.ts +++ b/src/agents/pi-tools.policy.ts @@ -7,6 +7,7 @@ import { resolveThreadParentSessionKey } from "../sessions/session-key-utils.js" import { normalizeMessageChannel } from "../utils/message-channel.js"; import { resolveAgentConfig, resolveAgentIdFromSessionKey } from "./agent-scope.js"; import { compileGlobPatterns, matchesAnyGlobPattern } from "./glob-pattern.js"; +import { pickSandboxToolPolicy } from "./sandbox-tool-policy.js"; import { expandToolGroups, normalizeToolName } from "./tool-policy.js"; function makeToolPolicyMatcher(policy: SandboxToolPolicy) { @@ -112,34 +113,6 @@ type ToolPolicyConfig = { profile?: string; }; -function unionAllow(base?: string[], extra?: string[]) { - if (!Array.isArray(extra) || extra.length === 0) { - return base; - } - // If the user is using alsoAllow without an allowlist, treat it as additive on top of - // an implicit allow-all policy. - if (!Array.isArray(base) || base.length === 0) { - return Array.from(new Set(["*", ...extra])); - } - return Array.from(new Set([...base, ...extra])); -} - -function pickToolPolicy(config?: ToolPolicyConfig): SandboxToolPolicy | undefined { - if (!config) { - return undefined; - } - const allow = Array.isArray(config.allow) - ? unionAllow(config.allow, config.alsoAllow) - : Array.isArray(config.alsoAllow) && config.alsoAllow.length > 0 - ? unionAllow(undefined, config.alsoAllow) - : undefined; - const deny = Array.isArray(config.deny) ? config.deny : undefined; - if (!allow && !deny) { - return undefined; - } - return { allow, deny }; -} - function normalizeProviderKey(value: string): string { return value.trim().toLowerCase(); } @@ -237,10 +210,10 @@ export function resolveEffectiveToolPolicy(params: { }); return { agentId, - globalPolicy: pickToolPolicy(globalTools), - globalProviderPolicy: pickToolPolicy(providerPolicy), - agentPolicy: pickToolPolicy(agentTools), - agentProviderPolicy: pickToolPolicy(agentProviderPolicy), + globalPolicy: pickSandboxToolPolicy(globalTools), + globalProviderPolicy: pickSandboxToolPolicy(providerPolicy), + agentPolicy: pickSandboxToolPolicy(agentTools), + agentProviderPolicy: pickSandboxToolPolicy(agentProviderPolicy), profile, providerProfile: agentProviderPolicy?.profile ?? providerPolicy?.profile, // alsoAllow is applied at the profile stage (to avoid being filtered out early). @@ -313,7 +286,7 @@ export function resolveGroupToolPolicy(params: { senderUsername: params.senderUsername, senderE164: params.senderE164, }); - return pickToolPolicy(toolsConfig); + return pickSandboxToolPolicy(toolsConfig); } export function isToolAllowedByPolicies( diff --git a/src/agents/sandbox-tool-policy.ts b/src/agents/sandbox-tool-policy.ts new file mode 100644 index 0000000000..c4a4b2dc81 --- /dev/null +++ b/src/agents/sandbox-tool-policy.ts @@ -0,0 +1,37 @@ +import type { SandboxToolPolicy } from "./sandbox/types.js"; + +type SandboxToolPolicyConfig = { + allow?: string[]; + alsoAllow?: string[]; + deny?: string[]; +}; + +function unionAllow(base?: string[], extra?: string[]): string[] | undefined { + if (!Array.isArray(extra) || extra.length === 0) { + return base; + } + // If the user is using alsoAllow without an allowlist, treat it as additive on top of + // an implicit allow-all policy. + if (!Array.isArray(base) || base.length === 0) { + return Array.from(new Set(["*", ...extra])); + } + return Array.from(new Set([...base, ...extra])); +} + +export function pickSandboxToolPolicy( + config?: SandboxToolPolicyConfig, +): SandboxToolPolicy | undefined { + if (!config) { + return undefined; + } + const allow = Array.isArray(config.allow) + ? unionAllow(config.allow, config.alsoAllow) + : Array.isArray(config.alsoAllow) && config.alsoAllow.length > 0 + ? unionAllow(undefined, config.alsoAllow) + : undefined; + const deny = Array.isArray(config.deny) ? config.deny : undefined; + if (!allow && !deny) { + return undefined; + } + return { allow, deny }; +} diff --git a/src/pairing/setup-code.ts b/src/pairing/setup-code.ts index 8d47ec441a..3542a9509d 100644 --- a/src/pairing/setup-code.ts +++ b/src/pairing/setup-code.ts @@ -152,8 +152,9 @@ function isTailnetIPv4(address: string): boolean { return a === 100 && b >= 64 && b <= 127; } -function pickLanIPv4( +function pickIPv4Matching( networkInterfaces: () => ReturnType, + matches: (address: string) => boolean, ): string | null { const nets = networkInterfaces(); for (const entries of Object.values(nets)) { @@ -170,7 +171,7 @@ function pickLanIPv4( if (!address) { continue; } - if (isPrivateIPv4(address)) { + if (matches(address)) { return address; } } @@ -178,30 +179,16 @@ function pickLanIPv4( return null; } +function pickLanIPv4( + networkInterfaces: () => ReturnType, +): string | null { + return pickIPv4Matching(networkInterfaces, isPrivateIPv4); +} + function pickTailnetIPv4( networkInterfaces: () => ReturnType, ): string | null { - const nets = networkInterfaces(); - for (const entries of Object.values(nets)) { - if (!entries) { - continue; - } - for (const entry of entries) { - const family = entry?.family; - const isIpv4 = family === "IPv4"; - if (!entry || entry.internal || !isIpv4) { - continue; - } - const address = entry.address?.trim() ?? ""; - if (!address) { - continue; - } - if (isTailnetIPv4(address)) { - return address; - } - } - } - return null; + return pickIPv4Matching(networkInterfaces, isTailnetIPv4); } function parsePossiblyNoisyJsonObject(raw: string): Record { diff --git a/src/security/audit-tool-policy.ts b/src/security/audit-tool-policy.ts index 478ac30c0d..2726f99cc8 100644 --- a/src/security/audit-tool-policy.ts +++ b/src/security/audit-tool-policy.ts @@ -1,31 +1 @@ -import type { SandboxToolPolicy } from "../agents/sandbox/types.js"; - -function unionAllow(base?: string[], extra?: string[]): string[] | undefined { - if (!Array.isArray(extra) || extra.length === 0) { - return base; - } - if (!Array.isArray(base) || base.length === 0) { - return Array.from(new Set(["*", ...extra])); - } - return Array.from(new Set([...base, ...extra])); -} - -export function pickSandboxToolPolicy(config?: { - allow?: string[]; - alsoAllow?: string[]; - deny?: string[]; -}): SandboxToolPolicy | undefined { - if (!config) { - return undefined; - } - const allow = Array.isArray(config.allow) - ? unionAllow(config.allow, config.alsoAllow) - : Array.isArray(config.alsoAllow) && config.alsoAllow.length > 0 - ? unionAllow(undefined, config.alsoAllow) - : undefined; - const deny = Array.isArray(config.deny) ? config.deny : undefined; - if (!allow && !deny) { - return undefined; - } - return { allow, deny }; -} +export { pickSandboxToolPolicy } from "../agents/sandbox-tool-policy.js";