The sandbox
Agents run only inside a sandbox.
What every run getsβ
- Its own worktree and branch under
~/.orion, never your checkout. - An OS-level sandbox: Seatbelt on macOS, bubblewrap on Linux.
- A network allowlist of GitHub, the package registries, Anthropic and your tracker's host.
- No credentials:
~/.ssh, cloud keys,.envfiles and API-key variables are denied at both the tool level and the OS level. - The
gate,shieldandbreakerhooks on every tool call (Safety and limits lists what each stops).
Orion generates the settings per workspace from the running build's rules, so a workspace created by an older release does not keep an older allowlist. The fix agent in the integration loop runs under the same sandbox.
When the OS sandbox is missingβ
The generated settings set failIfUnavailable: true and
allowUnsandboxedCommands: false. If the OS sandbox cannot initialise, the
run does not start, and no command may run outside it.
orion doctor reports whether this machine can provide the sandbox. It
grades a missing one as WARN, but workspaces still refuse to start.
Network allowlistβ
Agents can reach only these hosts:
| Host | For |
|---|---|
api.anthropic.com | the model |
github.com, api.github.com, raw.githubusercontent.com, objects.githubusercontent.com, codeload.github.com | git, pull requests, downloads |
registry.npmjs.org | npm |
pypi.org, files.pythonhosted.org | Python packages |
proxy.golang.org, sum.golang.org | Go modules |
crates.io, static.crates.io | Rust crates |
| your tracker's host | only when a tracker URL is configured |
The list is the minimum a build needs, because each addition widens what a
compromised dependency could reach. The tracker host is added only when
ORION_JIRA_URL is set.
Binding a loopback port is allowed, so tests can start a local HTTP server;
a socket on 127.0.0.1 reaches only the process that opened it.
Credentials deniedβ
At the OS level, the sandbox denies:
- the files
~/.ssh,~/.aws/credentialsand~/.config/gcloud; - the environment variables
AWS_SECRET_ACCESS_KEYandANTHROPIC_API_KEY.
At the tool level, the agent's permissions deny reading .env*,
./secrets/**, **/id_rsa*, **/.aws/credentials and **/.npmrc, plus
WebFetch, curl and wget, and editing orion.json or
.github/workflows/**.
The supervisor also strips cloud credentials from the agent's environment before it starts, in case the sandbox is misconfigured. The binary reads Orion's own Jira and Slack tokens and never passes them to the agent.
Which Claude configuration a run seesβ
On Linux, a supervised run gets a configuration directory Orion builds at
$ORION_HOME/agent-config, pointed at with CLAUDE_CONFIG_DIR. It holds the
toolkit's skills and agents and nothing else. --strict-mcp-config is passed
with no MCP configuration beside it, so the run has no MCP servers at all,
including account-level connectors.
On macOS, runs inherit your own Claude Code configuration: your plugins, MCP servers and subagents. A curated directory cannot sign in there, because the CLI's login lives in the Keychain and is not reached for a non-default configuration directory. Every run reports this as a warning. The agent can reach anything your own Claude Code can, and a run on another machine may behave differently because its tools differ.
If your own Claude Code has MCP servers with write access to real accounts, an agent running under Orion on macOS has them too. Disconnect what an unattended agent should not touch, or run Orion on Linux.
delegation.inherit_operator_config in orion.json lists stages or actors
that should get your own configuration on purpose, on any platform. It is
empty by default, and the event log names the opt-in on any run that uses it
(ADR 0014).
What the sandbox does not stopβ
The OS sandbox stops credential reads and network egress, but it is not a VM and does not defend against a determined exploit. For code you do not trust, run Orion itself inside a VM or container.
Workspace layoutβ
Each project's workspace, which orion plan creates:
$ORION_HOME/projects/<slug>-<id>/
βββ repo/ the project, git initialized
βββ worktrees/ one per ticket being worked
βββ .orion/
βββ task.json idea, stage, status, run history
βββ settings.json generated: permission denies + OS sandbox
βββ cache/ compiler cache, shared by every job in this sandbox
βββ state/ breaker counters
βββ logs/ full transcript per run
βββ events.jsonl the run's own record
ORION_HOME defaults to ~/.orion. To look at where agents worked:
orion sandbox # clones and worktrees
orion sandbox KEY # one ticket's worktree: branch, commits, dirt
orion sandbox KEY --shell # a shell in it (--code opens VS Code, --path prints it)
orion sandbox prune # remove worktrees whose branch is merged and clean
Not documented yetβ
- A ready-made VM or container recipe for running Orion.
- Whether the network allowlist can be extended per project.