Environments
An environment is the machine a session runs in, defined once as YAML and referenced by name from sessions, automations, and the organization's defaults.
An environment is the sandbox a session runs in: which repositories are cloned, what is installed, how much compute it gets, which secrets and MCP servers it sees. Define it once, in one file, and reference it by name.
The file
ellipsis:
kind: environment
name: cloud_agent_environment
description: The team toolchain, defined once and referenced by name.
repositories:
- name: web-repo
- name: api-repo
variables:
- name: DOPPLER_TOKEN
- name: LOG_LEVEL
value: info
mcp_servers:
- slack
image:
setup: |
(cd web-repo && pnpm install)
(cd api-repo && poetry install)
compute:
memory: 8GBkind: environment is what makes a file in an agents directory an
environment rather than an automation. It syncs the same way: the version on
your default branch is live, and the name is what everything else references.
Using it
agent -e cloud_agent_environment "Fix the flaky test in ci/"environment: cloud_agent_environmentA session names it with -e (or "environment": "cloud_agent_environment"
over the API); an automation names it in its environment field. Set it as
the organization's default environment and
every session that names nothing runs in it. A session may also carry an
inline environment object for one run, and an automation may carry an inline
block instead of a name; a dangling name fails the session loudly at start.
Environments can also be managed through the API with no file
(POST /v1/environments, agent environment create -f), and moved into a
repository later, exactly like automations.
What is in the sandbox
the sandbox, created per session
┌─────────────────────────────────────────────────────────┐
│ │
│ /sandbox your repositories, cloned and │
│ checked out before the agent runs │
│ │
│ base tooling Python 3.13, Node.js 22, git, gh, │
│ curl, a C/C++ toolchain │
│ │
│ your additions image.dockerfile_append, │
│ image.setup, hooks, skills │
│ │
│ scoped credentials a 1-hour GitHub token minted for │
│ this sandbox alone, plus the │
│ variables the environment names │
│ │
└─────────────────────────────────────────────────────────┘
destroyed when the session ends; credentials die with itRepositories are cloned before the agent starts, and gh is already
authenticated against them. Model calls route through Ellipsis with a
per-session key; a real provider key never enters the sandbox. Everything is
revoked or expires at teardown, and nothing an agent installs at run time
carries into the next session. ELLIPSIS_SANDBOX_ID is set in every sandbox
and nowhere else.
Fields
| Field | What it does |
|---|---|
repositories | Cloned into the sandbox before the agent starts. name, an optional owner (defaults to your account), an optional ref. |
variables | Environment variables. A value: hardcodes a non-secret setting; a bare name: injects a stored secret. |
mcp_servers | MCP servers the agent can call: a built-in integration by name (slack, linear), or your own server, stdio (name, command, args, env) or remote (name, url, headers), with ${NAME} references to stored secrets. Fields: agent.yaml › environment.mcp_servers. |
image.dockerfile_append | RUN lines appended to the managed base image, before any repository exists. Toolchain installs go here. Only RUN is accepted. |
image.setup | A shell script run once after checkout and captured in the cached image, so dependency installs cost nothing on repeat sessions. Capped at 10 minutes. Files are captured, environment is not; never write a secret to disk here. |
hooks.post_start, hooks.post_clone | Shell scripts run on every session, never cached: before repository work and after checkout. Authenticate a CLI here. Capped at 5 minutes each. |
compute.cpu, compute.memory, compute.timeout | 1 vCPU, 4096 MiB, and 1 hour by default. Ranges: 0.125 to 16 vCPU, 512MB to 64GB, 60s to 1h. Out of range fails validation; nothing is clamped. The timeout only shortens: a sandbox never outlives its 1-hour GitHub token. |
A hook or setup script that exits non-zero fails the session with
lifecycle_hook_failed, so broken setup is a clear failure rather than an
agent working in a half-prepared sandbox.
Secrets
Store a value once, then name it:
agent variable set DOPPLER_TOKEN=dp.st.xxxvariables:
- name: DOPPLER_TOKENOnly sandboxes whose environment names a secret receive it. Stored values are
write-only: injected into sandboxes, never readable back through the
dashboard, API, or CLI, which list names and timestamps only. Session logs
record what your scripts print, so keep setup and hooks from echoing a
value.
Caching
The cached image is the one thing that carries over between sessions: the
repositories plus everything dockerfile_append and setup produced, cached
per repository set, commit, and image definition.
- A session at a commit that already has an image starts with everything in place.
- A session at a new commit starts from the most recent image for the same
repositories, checks out the new commit, and re-runs
setupon top, so package managers install only what changed. - Changing
dockerfile_appendorsetuprebuilds on the next session.
Test an environment end to end with --rebuild, which skips the cache and
streams every provisioning line:
$ agent -e cloud_agent_environment --rebuild "Run gh auth status, confirm both repositories are cloned, and print doppler --version."
✻ Starting sandbox…
⎿ Cloning your-org/web-repo @ 4c19e7d · Cloning your-org/api-repo @ 91b2aa0
⎿ Running setup… · Successfully installed fastapi-0.115.6 sqlalchemy-2.0.36
✓ Sandbox ready · your-org/web-repo, your-org/api-repo · full buildThe full walkthrough, from storing a credential to authenticating a CLI with it: Give agents the tools and credentials your build needs.