Environments
Reusable container templates that define what a session's sandbox is built from in Orca Agent Engine.
An Environment is a reusable template for a session's sandbox. It says where the sandbox runs and what network it can reach, and every session must reference one: environment_id is required at create time and there is no default.
Environments describe the sandbox. What the sandbox guarantees once it is running - the filesystem layout, the one writable path, the per-session caps - is on Sandboxes.
Get your registry endpoint
Registry endpoint
Examples on this page target your registry endpoint - the deployment host root, with no path
suffix. For CLI, set ORCA_REGISTRY_URL and exactly one of ORCA_ACCESS_TOKEN (Bearer) or
ORCA_API_KEY (x-api-key). For TypeScript SDK, set ORCA_BASE_URL / ORCA_API_KEY (Bearer).
To find the endpoint, see Connect to the registry.
Create an environment
name is the only required field. Omitting config gives you a cloud environment with unrestricted networking.
environment=$(ork agent environments create \
--name "data-science" \
--description "Python environment for analysis sessions" \
--config-json '{"type":"cloud","networking":{"type":"limited","allowed_hosts":["api.example.com"]}}' \
-o json)
ENVIRONMENT_ID=$(jq -r '.id' <<< "$environment")A successful create returns 200 OK. The response normalizes config: every package manager is present, and networking is filled in even when you did not send it.
{
"id": "env_01H8...",
"type": "environment",
"name": "data-science",
"description": "Python environment for analysis sessions",
"config": {
"type": "cloud",
"networking": { "type": "limited", "allowed_hosts": ["api.example.com"] },
"packages": {
"type": "packages",
"apt": [],
"cargo": [],
"gem": [],
"go": [],
"npm": [],
"pip": []
}
},
"metadata": { "team": "data" },
"archived_at": null,
"created_at": "2026-05-11T17:24:08Z",
"updated_at": "2026-05-11T17:24:08Z"
}$ENVIRONMENT_ID, or environmentId in the TypeScript examples below, is what you pass to a session as environment_id.
Configure the sandbox
config is a discriminated union on type:
type | Accepts | Meaning |
|---|---|---|
cloud | packages, networking | The platform provisions the sandbox. The default. |
self_hosted | nothing else | The sandbox runs in infrastructure you operate. Sending packages or networking alongside it returns 400. |
Packages
config.packages declares packages by manager. The registry accepts and stores the field - it
recognizes apt, cargo, gem, go, npm, and pip, each taking an array of package names -
but no managed sandbox acts on it.
Declaring a package makes the session fail to start. Sandbox setup rejects a non-empty
packages list in every managed sandbox mode, before any install could run, and the session ends
in setup_failed rather than starting without the packages. An environment that names even one
package cannot run a session at all.
Install hooks would execute before resource and Skill roots are sealed, so they are held back until the runtime can seal the filesystem first. Until then, build what a session needs into the environment's image.
Any other key is rejected: the schema is strict, so a typo like "python" fails rather than being ignored - though since a populated list stops the session from starting at all, a rejected typo is the better outcome. See Installing packages.
Networking
config.networking applies only to cloud configs and takes one of two shapes:
{
"config": {
"type": "cloud",
"networking": {
"type": "limited",
"allowed_hosts": ["api.internal.example.com"],
"allow_package_managers": true,
"allow_mcp_servers": true
}
}
}| Field | Type | Default | Description |
|---|---|---|---|
type | unrestricted / limited | unrestricted | Whether egress is filtered at all. |
allowed_hosts | string array | [] | Hosts reachable under limited. |
allow_package_managers | boolean | false | Whether package-manager registries stay reachable under limited. |
allow_mcp_servers | boolean | false | Whether declared MCP servers stay reachable under limited. |
On update, a limited block merges field by field against the stored one: omitted fields keep their current value, and a field set to null resets it to the default. An unrestricted block replaces whatever was there.
Networking is stored but not enforced in this build. The sandbox layer receives the value and no runtime reads it, so limited restricts nothing and allowed_hosts blocks nothing. Do not use it as a security boundary. Keep secrets out of the sandbox with vaults, which resolve credentials at the gateway, and control reach by choosing which MCP servers an agent declares.
Flat legacy fields
The registry also accepts four flat legacy fields alongside config: packages (a bare string array, treated as apt), networking, image, and target. The flat packages reaches the same place as config.packages, so a non-empty value stops sessions from starting in exactly the same way.
target and config.type write the same stored value, so send whichever your client supports - config.type is the current spelling. Either way the value is read at run time: an environment whose target is self_hosted enables client-executed built-in tools for sessions that also use the claude_agent_sdk harness in separate mode.
image never takes effect. Under the default separate mode it is not read at all. Under an
in-sandbox harness it is read, but sandbox setup
rejects a user-supplied image before that point, so every session on the environment fails to
start - the same check that rejects config.packages. The image that runs is the operator-owned
catalog image. Prefer config for everything else: the flat fields exist for compatibility with
older clients.
Manage environments
List environments
environments=$(ork agent environments list --limit 20 -o json)
jq -r '.data[] | "\(.id) \(.name)"' <<< "$environments"List takes only limit (1 to 100, default 100), page, and include_archived. There is no name or metadata filter; select client-side with jq. Paging works the same way as session pagination.
Retrieve an environment
environment=$(ork agent environments get "$ENVIRONMENT_ID" -o json)
jq -r '.config.networking.allowed_hosts[]' <<< "$environment"Update an environment
Update is a POST to the environment path, not a PATCH.
environment=$(ork agent environments update "$ENVIRONMENT_ID" \
--config-json '{"type":"cloud","networking":{"type":"limited","allowed_hosts":["api.example.com","cdn.example.com"]}}' \
-o json)
jq -r '.updated_at' <<< "$environment"Sending config does not replace every stored child field wholesale. On a cloud environment, omitting config.networking preserves the existing networking block; a supplied limited block merges its fields as described above. Omitting config.packages also preserves the stored package lists, while supplying it replaces those lists. metadata patches instead: omitted keys survive and a key set to null is removed.
Archive an environment
ork agent environments archive "$ENVIRONMENT_ID"Archiving hides the environment from list results unless you pass include_archived=true. Sessions already using it keep running.
Delete an environment
ork agent environments delete "$ENVIRONMENT_ID"Delete refuses if any session references the environment, returning 409 environment is referenced by one or more sessions. That check does not exclude archived or terminated sessions, so an environment used even once is effectively permanent until those sessions are deleted. Archive is the operation you want for retiring an environment.
What a change affects
A session does not snapshot its environment. The registry re-reads the environment row on every turn, and the result is part of the runtime configuration key the harness compares before dispatching; when the key changes, the runner is stopped and respawned against the new configuration. An environment edit therefore reaches an existing session on its next turn, not only new sessions. Edit an environment that live sessions depend on with that in mind.
That makes environments safe to edit but easy to misread: if a session is missing a package you just added, check when the session was created before checking the environment.
Permissions
Treat every Workspace API key as full access to its Workspace's resources, and separate access with Workspaces. See Control registry access.
What's next
Multiagent
Let one agent delegate to others inside a single session in Orca Agent Engine, and read each delegate's work on its own thread.
Sandboxes
What a session sandbox in Orca Agent Engine guarantees - the filesystem layout, where an agent may write, what gets mounted where, and the per-session limits.