Compute Isolation¶
Each sandbox runs in its own isolated environment, fully separated from other sandboxes and from any other tenants' workloads.
You pick an image and (optionally) a command — Tilde launches the sandbox, captures its output, and cleans up when it exits.
Supported Images¶
Sandboxes accept any Docker image reference in the image field. Pass a public image tag like python:3.12 or ubuntu:22.04, or a reference from any registry Tilde can pull from (e.g. ghcr.io/my-org/my-image:latest, my-registry.example.com/team/image:v1).
Creating a Sandbox¶
# Run and stream output (default behavior)
tilde sandbox run -r my-team/my-data \
--image python:3.12 \
-- python -c "import os; print(os.listdir('/sandbox'))"
# Detach and print sandbox ID
tilde sandbox run -r my-team/my-data \
--image python:3.12 -d \
-- python -c "import os; print(os.listdir('/sandbox'))"
Response: 201 Created
Configuration Options¶
| Field | Type | Required | Description |
|---|---|---|---|
image |
string | Yes | Docker image reference (e.g. python:3.12, ubuntu:22.04, ghcr.io/my-org/my-image:latest) |
command |
string[] | No | Command to execute inside the container |
mountpoint |
string | No | Where to mount repo data (default: /sandbox) |
path_prefix |
string | No | Only mount objects under this prefix |
timeout_seconds |
integer | No | Maximum execution time in seconds |
env_vars |
object | No | Environment variables to inject into the container |
run_as |
object | No | Run as an agent or role instead of yourself (see Delegation) |
Checking Status¶
Poll the sandbox to check its progress:
Sandbox Statuses¶
| Status | Meaning |
|---|---|
created |
Sandbox is queued |
starting |
Container is being pulled and started |
running |
Container is executing |
committed |
Completed successfully, changes committed |
awaiting_approval |
Completed, waiting for human review |
failed |
Exited with an error |
cancelled |
Cancelled by user |
When a sandbox reaches committed, the response includes a commit_id pointing to the new commit with the sandbox's changes.
Exit Lifecycle¶
| Exit code | Cancelled? | Outcome |
|---|---|---|
| 0 | No | Session is committed; status becomes committed |
| 0 (approval required) | No | Session needs approval; status becomes awaiting_approval |
| Non-zero | No | Session is rolled back; status becomes failed |
| Any | Yes | Session is rolled back; status becomes cancelled |
Streaming Logs¶
Stream stdout and stderr from a running sandbox:
# Stream stdout
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
https://tilde.run/api/v1/organizations/my-team/repositories/my-data/sandboxes/SANDBOX_ID/stdout
# Stream stderr
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
https://tilde.run/api/v1/organizations/my-team/repositories/my-data/sandboxes/SANDBOX_ID/stderr
Both endpoints use chunked transfer encoding — new output is sent as it becomes available.
Cancelling a Sandbox¶
Cancel a running sandbox:
Response: 202 Accepted — the cancellation is asynchronous. The sandbox transitions to cancelled once the container stops.
Environment Variables and Secrets¶
You can pass environment variables directly when creating a sandbox:
{
"image": "python:3.12",
"command": ["python", "validate.py"],
"env_vars": {
"STRICT_MODE": "1",
"OUTPUT_FORMAT": "json"
}
}
For sensitive values, use secrets instead of passing them in env_vars. Secrets are encrypted at rest and injected automatically. See the Python SDK or the API Reference for details on creating repository and agent secrets.
Precedence (highest to lowest):
env_varspassed in the sandbox request- Agent secrets (if the sandbox runs as an agent)
- Repository secrets
Delegation¶
By default, sandboxes run under your identity. You can delegate execution to an agent or role using the run_as field:
{
"image": "python:3.12",
"command": ["python", "pipeline.py"],
"run_as": {
"type": "agent",
"id": "AGENT_UUID"
}
}
When a sandbox runs as an agent, it inherits the agent's secrets, RBAC permissions, and network policies. This is useful for automated pipelines where the sandbox should have a specific, limited set of permissions rather than your full user access.
Two policy checks run before the sandbox starts:
- Caller permission. Setting
run_as.type = "agent"requiresUseAgenton the target agent;run_as.type = "role"requiresUseRole. Without this grant the request is rejected with403 FORBIDDEN. The built-inOwner,SuperUser, andAgentManagerpolicies include these grants; other principals must be granted them explicitly. See Impersonation. - Target permission. The agent's inline policy must allow
CreateSandbox,CreateSession, andCommitSessionon the target repository — the sandbox lifecycle uses the agent's identity for these actions and they are no longer bypassed. Agents created through the Tilde web UI have these seeded by default; API and CLI callers settinginline_policyexplicitly need to include them. See Running sandboxes as agents.
Examples¶
The examples below wire a sandbox to a trigger so it runs automatically when specific files change.
Document Summarization Agent¶
An agent that automatically summarizes documents when they're added to the repository. When a PDF or text file is uploaded to documents/, the agent reads it, generates a summary using an LLM, and commits the summary as a companion Markdown file.
1. Create the agent and configure its secrets:
import tilde
org = tilde.organizations.get("my-team")
agent = org.agents.create(
"summarizer",
description="Reads new documents and writes summaries",
)
# The agent needs an LLM API key to generate summaries
agent.secrets.create("OPENAI_API_KEY", "sk-...")
2. Create the trigger:
{
"name": "Summarize new documents",
"description": "Generate a Markdown summary for each new document in documents/",
"conditions": [
{ "type": "prefix", "prefix": "documents/" }
],
"sandbox_config": {
"image": "my-org/doc-summarizer:latest",
"command": ["python", "summarize.py"],
"mountpoint": "/repo",
"timeout_seconds": 300
},
"run_as": {
"type": "agent",
"id": "AGENT_UUID"
}
}
When someone uploads documents/quarterly-review.pdf, the agent reads the file, calls the LLM (using OPENAI_API_KEY from its secrets), and commits documents/quarterly-review.summary.md. The commit appears in the timeline attributed to summarizer.
Form Auto-Fill Agent¶
An agent that processes blank or partially filled forms. When a form template is uploaded, the agent reads structured data already in the repository and fills in the form fields, committing the completed version for human review.
{
"name": "Fill uploaded forms",
"conditions": [
{ "type": "prefix", "prefix": "forms/pending/" }
],
"sandbox_config": {
"image": "my-org/form-filler:latest",
"command": ["python", "fill_forms.py"],
"mountpoint": "/repo",
"timeout_seconds": 600
},
"run_as": {
"type": "agent",
"id": "AGENT_UUID"
}
}
The agent reads the form from forms/pending/, pulls reference data from data/ in the same mount, writes the completed form to forms/completed/, and commits. With Require approval for agent commits enabled, a human reviews the filled form before it becomes part of the committed history.
Website Content Generator¶
An agent that turns rough ideas into published content. Writers drop short briefs into drafts/ideas/, and the agent expands each one into a full article, complete with metadata, and places it in the site's content directory.
Agent secrets:
org = tilde.organizations.get("my-team")
agent = org.agents.get("content-writer")
agent.secrets.create("ANTHROPIC_API_KEY", "sk-ant-...")
Trigger:
{
"name": "Draft content from ideas",
"conditions": [
{ "type": "prefix", "prefix": "drafts/ideas/" }
],
"sandbox_config": {
"image": "my-org/content-gen:latest",
"command": ["python", "generate.py"],
"mountpoint": "/site",
"timeout_seconds": 900,
"env_vars": {
"OUTPUT_DIR": "/site/content/blog/"
}
},
"run_as": {
"type": "agent",
"id": "AGENT_UUID"
}
}
A writer uploads drafts/ideas/tilde-launch.md containing a short outline. The agent reads the brief, generates a full blog post with front matter, and commits it to content/blog/tilde-launch.md. The ANTHROPIC_API_KEY is injected from the agent's secrets — it never appears in the trigger config or container environment.
Limits¶
| Resource | Limit |
|---|---|
| Triggers per repository | 50 |
| Conditions per trigger | 10 |
| Trigger name length | 100 characters |
| Environment variables per sandbox | 50 |
| Env var key length | 256 characters |
| Env var value length | 4,096 characters |
| Path/prefix length | 1,024 bytes |