Skip to Content
DocsRecipesSandboxed coding assistant

Sandboxed coding assistant

The agent can read and write files only inside a workspace directory. Symlink-based escapes are blocked; an HMAC-signed audit log records every file access.

import asyncio from pathlib import Path from loomflow import Agent, Mode, StandardPermissions, tool from loomflow.security import FileAuditLog, FilesystemSandbox from loomflow.tools import InProcessToolHost WORKSPACE = Path("./workspace").resolve() @tool def read_file(path: str) -> str: """Read a file from the workspace.""" return Path(path).read_text() @tool(destructive=True) def write_file(path: str, content: str) -> str: """Write content to a file (destructive — requires approval).""" Path(path).write_text(content) return f"wrote {len(content)} bytes to {path}" async def main(): inner = InProcessToolHost([read_file, write_file]) sandbox = FilesystemSandbox(inner, roots=[WORKSPACE]) agent = Agent( "You are a coding assistant. Only touch files inside the workspace.", model="claude-opus-4-7", tools=sandbox, permissions=StandardPermissions(mode=Mode.ACCEPT_EDITS), audit_log=FileAuditLog("./audit.jsonl", secret="prod-secret"), ) @agent.before_tool async def confirm_destructive(call): if call.tool == "write_file": answer = input(f"Allow write to {call.args.get('path')}? [y/N] ") if answer.strip().lower() != "y": from loomflow.core.types import PermissionDecision return PermissionDecision.deny_("user declined") return None await agent.run("Refactor utils.py to use type hints.") asyncio.run(main())

The sandbox auto-detects path-typed arguments by name (path, file, directory, etc.) and by value (containing / or \). Any path that resolves outside the workspace. Including via symlink, is rejected before the tool runs.

Last updated on