Use the Sandbox¶
The virtual sandbox gives agents controlled access to a workspace.
Read Files¶
Read access is enabled by default.
Write Files¶
agent = await init(allow_write=True)
session = await agent.session()
await session.write_file("report.txt", "Repository summary")
Without allow_write=True, writes raise PermissionError.
Run Shell Commands¶
agent = await init(allow_shell=True)
session = await agent.session()
result = await session.shell("python --version")
Without allow_shell=True, shell commands raise PermissionError.
Enable Both¶
Keep Commands Narrow¶
For production use, prefer command allowlists:
Compound shell syntax is blocked by default. This protects untrusted workflows from pipes, redirects, command substitution, and chained shell commands. Enable compound commands only for trusted workflows:
Grant Secrets Per Call¶
Secrets passed through env are not added to prompts and are not mounted into
the sandbox by default.
agent = await init(
env={"GITHUB_TOKEN": "..."},
allow_shell=True,
allowed_commands=["python"],
)
session = await agent.session("issue-123")
await session.shell(
"python -c 'import os; print(os.getenv(\"GITHUB_TOKEN\"))'",
secrets=["GITHUB_TOKEN"],
)
Use a Remote Sandbox¶
Install the provider extra:
Then select the provider:
agent = await init(
model="openai:gpt-5.5",
sandbox="daytona",
env={"DAYTONA_API_KEY": "..."},
allow_write=True,
allow_shell=True,
)
Supported provider names:
| Provider | API key |
|---|---|
daytona |
DAYTONA_API_KEY |
e2b |
E2B_API_KEY |
modal |
Modal CLI or environment authentication |
runloop |
RUNLOOP_API_KEY |
Remote provider adapters keep the same session API:
session = await agent.session("code")
await session.shell("git clone https://github.com/org/repo workspace/repo")
await session.write_file("workspace/repo/report.md", "# Report\n")
content = await session.read_file("workspace/repo/report.md")
The provider sandbox is responsible for isolation. PyFlue is responsible for the common read, write, edit, grep, glob, and shell interface.