Skip to content

Bug: restrict_to_workspace=false ignored by write_file/read_file/edit #994

Description

@astralwaveorg

Setting restrict_to_workspace = false on an agent
(verified in PostgreSQL agents table and
config.json) should allow that agent's filesystem
tools to access paths outside its workspace.
However, write_file, read_file, and edit tools all
still reject access with:

access denied: path outside workspace

The exec tool correctly allows access to paths
outside the workspace when restrict_to_workspace =
false.

Reproduction

  1. Set restrict_to_workspace = false for agent
    lunexi in both PostgreSQL and config.json
  2. Attempt to use write_file tool to write to
    /tmp/test.txt
  3. Error: access denied: path outside workspace
  4. Same operation with exec tool succeeds — it can
    write to /tmp/

Expected behavior

When restrict_to_workspace = false,
write_file/read_file/edit tools should allow access to paths outside the agent's workspace, not just
exec.

Root cause (code investigation)

In internal/tools/context_keys.go, the
effectiveRestrict() function is hardcoded to always return true:

func effectiveRestrict(ctx context.Context,
toolDefault bool) bool {
// Multi-tenant security: always restrict
agents to their workspace.
// Agents must not access files outside their
tenant-scoped workspace.
return true
}

This function is called by
write_file/read_file/edit tools (via resolvePath()
in filesystem.go). The toolDefault parameter —
which should reflect the agent's
restrict_to_workspace setting — is completely
ignored. The WithRestrictToWorkspace() context
helper exists (line 269-271) and RestrictFromCtx()
correctly retrieves the override value from
context, but effectiveRestrict() never calls
RestrictFromCtx().

The restrict_to_workspace field in agents table and config.json is never read by filesystem tools
because the check in effectiveRestrict()
short-circuits before any lookup occurs.

Environment

  • GoClaw version: (latest from main)
  • PostgreSQL 18.3
  • macOS

Verification

PostgreSQL query confirms the setting is correctly
stored:
SELECT agent_key, restrict_to_workspace, workspace
FROM agents WHERE agent_key = 'lunexi';
-- lunexi | f |
~/.goclaw/workspace/lunexi

config.json also has restrict_to_workspace: false
for lunexi.

Suggested fix

Modify effectiveRestrict() to actually read the
context override before falling back to
toolDefault:

func effectiveRestrict(ctx context.Context,
toolDefault bool) bool {
if override, ok := RestrictFromCtx(ctx); ok {
return override
}
return toolDefault
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions