Runners & isolation
Where phases actually execute, and the boundary around agent code that cannot be switched off.
Peractor orchestrates runs; runners execute them. Wherever a phase runs, one rule holds: agent code never executes on the control plane directly, and there is no way to turn isolation off.
The Peractor runner
Unless a phase says otherwise, it runs on the Peractor runner. This is where every phase of most workflows runs.
Every phase there runs in a fresh, one-shot container: non-root, all capabilities dropped, no privilege escalation, CPU, memory, and process caps, torn down when the phase ends. Multi-tenant deployments, including Peractor Cloud, run that container under gVisor for a kernel-level boundary.
The container sees only what the run needs: the workspace, the secrets the workflow declares, the agent credential, and a repository-scoped git token. Never the host's own environment.
Because Peractor owns the boundary, agents inside it run with their own permission prompts disabled. The human control point is the gate, not a terminal prompt nobody is watching.
Your own machines
Need a phase on hardware you own — a macOS builder with Xcode and simulators, a GPU box, a machine inside your VPN? Pair it in Settings → Runners and run the one-line command it gives you.
The machine dials out to Peractor over one WebSocket, so it needs no inbound ports, no public IP address, and no tunnel. A laptop behind home NAT works as-is. Full walkthrough: Run on your own machine.
A paired machine carries labels, and work reaches it only when a workflow phase asks for one:
phases:
- id: build
title: Build the app
runner: { labels: [macos] }
steps: […]
Three rules keep pairing safe:
- A machine receives only your own organization's runs.
- It receives only phases that name its labels. An unlabelled phase always uses the Peractor runner, so pairing a laptop can never quietly capture work that expected isolation.
- Every registration is authenticated. An anonymous connection is refused.
On your machine the agent runs directly — that is the point, since GUI work, simulators, and your toolchain are why you paired it. So the machine itself is the boundary there. Pair only machines you trust with your organization's work.
Running directly also means the machine brings its own tools. Nothing is containerized there and Peractor installs nothing, so git and the agent CLI your workflows use have to be on the machine. The runner prints a check of exactly that when it starts, and a phase that cannot find one fails saying so, naming the machine.
If a phase targets labels and no matching machine is connected, it parks at its gate with the reason rather than silently falling back to a Linux container. Start the runner, then approve to retry.
The warm workspace cache
By default each phase clones fresh. For install-heavy repositories, a workflow can reuse one workspace across its phases:
defaults:
cacheWorkspace: true
Phases then share one volume — but every phase still resets it hard to
the remote branch on entry, so git stays the only source of truth. Only
git-ignored files like node_modules survive between phases.
The volume is dropped when the run ends, and anything that cannot use it
falls back to a fresh clone.
Each lane of a fan-out gets a volume of its own, so lanes running at the same time on different branches do not reset the tree under each other.
If a machine disappears
A runner that drops its connection fails the phase it was holding, and the phase parks at its gate where Approve retries it.
The runner agent reconnects automatically — a slept laptop re-registers on wake — and a server restart re-dispatches whatever was in flight, from the branch. Losing hardware never loses work: the branch has everything that completed.