| name | modal-agent-sandboxing |
| description | Configure agent command execution through Modal Sandboxes. Use when deploying or reviewing an agent that runs terminal/tool commands in Modal instead of the app host, including Modal token setup, sandbox resource limits, filesystem sync, environment passthrough, and smoke tests. |
Modal Agent Sandboxing
Core Pattern
Use Modal as the execution boundary for agent-generated terminal work:
- Run the agent gateway/web service on its normal host.
- Configure the terminal backend to
modal.
- Keep the gateway host persistent only for app state, config, sessions, and API serving.
- Run untrusted or user-directed commands inside Modal Sandboxes rather than on the gateway machine.
For Hermes-style configs, the important shape is:
terminal:
backend: modal
cwd: /opt/data/workspace
env_passthrough: []
modal_image: "python-node image with required runtimes"
container_cpu: 1
container_memory: 5120
container_disk: 51200
container_persistent: true
file_sync_enabled: true
file_sync_max_mb: 100
Secrets
- Inject Modal credentials only into the gateway app process, usually as
MODAL_TOKEN_ID and MODAL_TOKEN_SECRET.
- Do not add provider keys, app secrets, or Modal credentials to
terminal.env_passthrough unless there is a reviewed, concrete need.
- Treat every variable in
env_passthrough as visible to sandboxed commands.
- Support legacy/local aliases only at deployment tooling boundaries, then normalize to the runtime names the app expects.
Resource Choices
Choose conservative sandbox resources first:
- CPU: start with
1 for chat/agent tasks.
- Memory: use enough for package installs and moderate scripts;
5120 MB is a practical starting point for Python/Node mixed sandboxes.
- Disk: use enough for synced workspace state and dependency caches; keep it explicit.
- Persistence: enable only when the agent workflow needs continuity across turns.
- File sync: enable when the agent must exchange workspace files with the sandbox, and cap sync size.
Deployment Checks
Validate Modal auth from inside the deployed gateway, not just locally:
fly ssh console --app <agent-app> -C 'sh -lc "cd /opt/hermes && . .venv/bin/activate && python -c \"import modal; modal.App.lookup(\\\"hermes-agent\\\", create_if_missing=True); print(\\\"modal auth ok\\\")\""'
Also check:
- Local Modal CLI is optional when deployed Fly secrets are present.
- Missing or stale Modal tokens usually show up as auth errors only after the gateway tries to create/look up a Modal app.
- The agent config persists in the app volume; entrypoints should patch runtime-derived defaults without overwriting operator edits.
Security Review
Before production:
- Confirm command execution never falls back to the gateway host.
- Confirm the sandbox working directory is a data/workspace path, not
/root.
- Confirm
env_passthrough is empty or explicitly justified.
- Confirm Modal tokens are set as host secrets and not committed in
.env.example, docs, Dockerfiles, or fly.toml.
- Confirm smoke tests exercise the deployed app's Modal auth path.