fix(exec): exempt venv python interpreter from .goclaw/ path deny (#1140)

The ExecTool path-deny rule blocks any token containing `.goclaw/` unless
it matches one of the AllowPathExemptions prefixes (skills-store, tenants).
This silently rejected legitimate commands invoking the goclaw-managed
Python interpreter via its absolute path:

    /home/user/.goclaw/venv/bin/python3 .../script.py

The first token `/home/user/.goclaw/venv/bin/python3` matched the deny
pattern but no exemption, so the entire command was denied.

Naive exemption (".goclaw/venv/bin/") does not work: matchesAnyPathExemption
resolves both tokens and exemption candidates via EvalSymlinks, and the
venv's python3 is a symlink into the host's python cellar (e.g. linuxbrew).
The token canonicalizes to /home/linuxbrew/.../python3.14 while a literal
".goclaw/venv/bin/" prefix never gets touched.

Fix: resolve venv/bin/python3 once at startup and exempt the dirname of
the resolved target. Failure to resolve (no venv present) silently falls
through.

Without this, ACP-driven agents either fail outright or work only via
fragile heuristics (cwd-local symlinks generated on the fly by the LLM).

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
codebit0andClaude Opus 4.7 authored and GitHub committed 2026-06-21 07:03:48 +07:00
1 parent 05d790662a
commit d5033b4aaf
1 file changed
+8
+8
View File
@@ -222,6 +222,14 @@ func setupToolRegistry(
filepath.Join(dataDir, "skills-store")+"/",
filepath.Join(dataDir, "tenants")+"/",
)
// Allow the goclaw-managed Python venv interpreter to be invoked with its
// absolute path. venv/bin/python3 is a symlink to the real interpreter
// (e.g. linuxbrew cellar), and matchesAnyPathExemption resolves symlinks
// before comparing — so we must exempt the *resolved* target dir.
// Resolved at startup; falls back silently if venv not present.
if real, err := filepath.EvalSymlinks(filepath.Join(filepath.Dir(dataDir), "venv", "bin", "python3")); err == nil {
et.AllowPathExemptions(filepath.Dir(real) + "/")
}
// Harden: block access to internal workspace files via shell commands.
// Prevents `cat ../config.json`, `cat memory.db` etc. from user workspaces.
et.DenyPaths(