Files
openclaw/src/agents/tool-fs-policy.ts
Jacob Tomlinson 824e16f9dd fix(media): require fs access for dynamic local roots (#55946)
* fix(media): require fs access for dynamic local roots

* fix(media): tighten fs root expansion policy

* fix(media): align fs root expansion with effective policy
2026-03-27 19:06:02 +00:00

66 lines
2.2 KiB
TypeScript

import type { OpenClawConfig } from "../config/config.js";
import { resolveAgentConfig } from "./agent-scope.js";
import { pickSandboxToolPolicy } from "./sandbox-tool-policy.js";
import { isToolAllowedByPolicies } from "./tool-policy-match.js";
import { mergeAlsoAllowPolicy, resolveToolProfilePolicy } from "./tool-policy.js";
export type ToolFsPolicy = {
workspaceOnly: boolean;
};
export function createToolFsPolicy(params: { workspaceOnly?: boolean }): ToolFsPolicy {
return {
workspaceOnly: params.workspaceOnly === true,
};
}
export function resolveToolFsConfig(params: { cfg?: OpenClawConfig; agentId?: string }): {
workspaceOnly?: boolean;
} {
const cfg = params.cfg;
const globalFs = cfg?.tools?.fs;
const agentFs =
cfg && params.agentId ? resolveAgentConfig(cfg, params.agentId)?.tools?.fs : undefined;
return {
workspaceOnly: agentFs?.workspaceOnly ?? globalFs?.workspaceOnly,
};
}
export function resolveEffectiveToolFsWorkspaceOnly(params: {
cfg?: OpenClawConfig;
agentId?: string;
}): boolean {
return resolveToolFsConfig(params).workspaceOnly === true;
}
export function resolveEffectiveToolFsRootExpansionAllowed(params: {
cfg?: OpenClawConfig;
agentId?: string;
}): boolean {
const cfg = params.cfg;
if (!cfg) {
return true;
}
const agentTools = params.agentId ? resolveAgentConfig(cfg, params.agentId)?.tools : undefined;
const globalTools = cfg.tools;
const profile = agentTools?.profile ?? globalTools?.profile;
const profileAlsoAllow = new Set(agentTools?.alsoAllow ?? globalTools?.alsoAllow ?? []);
const fsConfig = resolveToolFsConfig(params);
const hasExplicitFsConfig = agentTools?.fs !== undefined || globalTools?.fs !== undefined;
if (fsConfig.workspaceOnly === true) {
return false;
}
if (hasExplicitFsConfig) {
profileAlsoAllow.add("read");
profileAlsoAllow.add("write");
profileAlsoAllow.add("edit");
}
const profilePolicy = mergeAlsoAllowPolicy(
resolveToolProfilePolicy(profile),
profileAlsoAllow.size > 0 ? Array.from(profileAlsoAllow) : undefined,
);
const globalPolicy = pickSandboxToolPolicy(globalTools);
const agentPolicy = pickSandboxToolPolicy(agentTools);
return isToolAllowedByPolicies("read", [profilePolicy, globalPolicy, agentPolicy]);
}