mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-27 16:22:20 +01:00
fix(agent): give file tools the agent workspace as root when no workspace is set (#6722)
* fix(agent): give file tools the agent workspace as root when no workspace is set (#6679) With no workspace bound, bash/python run in data/agent_workspace, but RequestAuthority sealed no filesystem root, so every native file tool failed with "requires a sealed resource root", and an approved write_file failed with "no sealed resource identity". Seal the agent workspace instead, and resolve relative paths in _resolve_tool_path against it rather than the server's cwd. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: re-seal resource roots when a test swaps the authority owner (#6679) A no-workspace authority now seals the agent workspace for its owner, so replace(authority, owner="bob") copied alice's root and was rejected before the approval-binding check the tests are about. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(agent): only seal a vetted agent workspace as the file-tool root (#6679) Apply the agent_cwd() check before sealing data/agent_workspace: it must be a real directory in the readable data subdirs, otherwise no root is sealed. A symlinked workspace no longer redirects the file tools or the bash/python launch scope. Tighten the dispatch test assertions to the exact 'outside the sealed roots' message. * refactor(agent): vet the no-workspace file root with default_agent_workspace (#6679) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
9d0d3720f4
commit
1000b6582c
@@ -255,7 +255,8 @@ async def test_read_file_dispatch_blocks_etc_shadow(monkeypatch):
|
||||
security_context=NO_TOOL_SECURITY_CONTEXT,
|
||||
)
|
||||
assert result.get("failure_kind") == "resource_identity_denied"
|
||||
assert "sealed resource root" in (result.get("error") or "")
|
||||
assert "outside the sealed roots" in (result.get("error") or "")
|
||||
assert result.get("blocked") is True
|
||||
assert result.get("exit_code") == 1
|
||||
|
||||
|
||||
@@ -285,7 +286,8 @@ async def test_write_file_dispatch_blocks_authorized_keys(monkeypatch):
|
||||
security_context=NO_TOOL_SECURITY_CONTEXT,
|
||||
)
|
||||
assert result.get("failure_kind") == "resource_identity_denied"
|
||||
assert "sealed resource root" in (result.get("error") or "")
|
||||
assert "outside the sealed roots" in (result.get("error") or "")
|
||||
assert result.get("blocked") is True
|
||||
assert result.get("exit_code") == 1
|
||||
|
||||
|
||||
@@ -349,7 +351,8 @@ async def test_write_file_dispatch_blocks_cron(monkeypatch):
|
||||
security_context=NO_TOOL_SECURITY_CONTEXT,
|
||||
)
|
||||
assert result.get("failure_kind") == "resource_identity_denied"
|
||||
assert "sealed resource root" in (result.get("error") or "")
|
||||
assert "outside the sealed roots" in (result.get("error") or "")
|
||||
assert result.get("blocked") is True
|
||||
assert result.get("exit_code") == 1
|
||||
@pytest.mark.parametrize("filename", ["auth.json", "app.db", "settings.json"])
|
||||
def test_application_secrets_are_sensitive_paths(filename):
|
||||
|
||||
Reference in New Issue
Block a user