-
-
Notifications
You must be signed in to change notification settings - Fork 54.3k
Description
Bug: tools.fs.workspaceOnly defaults to restricted even when unset
Observed behavior
When tools.fs.workspaceOnly is not configured (neither globally at tools.fs.workspaceOnly nor per-agent at agents.list[].tools.fs.workspaceOnly), the write and edit tools reject paths outside the agent workspace with:
Path escapes workspace root: /tmp
Expected behavior
Per the type definition in src/config/types.tools.ts, the documented default is false (unrestricted):
export type FsToolsConfig = {
/**
* Restrict filesystem tools (read/write/edit/apply_patch) to the agent workspace directory.
* Default: false (unrestricted, matches legacy behavior).
*/
workspaceOnly?: boolean;
};When not set, agents should be able to write outside their workspace (matching legacy behavior).
Root cause
There is a mismatch between the policy resolution layer and the implementation layer:
Policy layer (src/agents/tool-fs-policy.ts:10) correctly resolves undefined to false:
export function createToolFsPolicy(params: { workspaceOnly?: boolean }): ToolFsPolicy {
return {
workspaceOnly: params.workspaceOnly === true, // undefined === true → false ✓
};
}Implementation layer (src/agents/pi-tools.read.ts:761) treats undefined as true:
function createHostWriteOperations(root: string, options?: { workspaceOnly?: boolean }) {
const workspaceOnly = options?.workspaceOnly !== false; // undefined !== false → true ✗
// ...The !== false guard means only an explicit false unlocks writes. If undefined arrives at this function (through any code path that doesn't go through the policy layer), it silently defaults to restricted.
The same pattern exists in createHostEditOperations and createHostReadOperations.
#28822 partially addressed this for the explicit workspaceOnly: false case, but the default/unset case still behaves as restricted.
Reproduction
# No tools.fs.workspaceOnly set in config
openclaw agent --agent main -m "Write a file at /tmp/test.txt with content 'ok'"
# → "Path escapes workspace root: /tmp"Agent config:
{
"id": "main",
"tools": { "allow": ["*"] }
// No sandbox, no tools.fs config
}Global config: no tools.fs section set.
Suggested fix
Either:
A) Change the implementation guard to match the documented default:
const workspaceOnly = options?.workspaceOnly ?? false;B) Or, if restricted-by-default is the intended secure posture, update the type documentation and ensure the policy layer matches:
// types.tools.ts
workspaceOnly?: boolean; // Default: true (restricted to workspace)Environment
- OpenClaw version:
2026.2.27 - Platform: Ubuntu 24.04 (Linux)
- Agent sandbox mode:
off(default)