Bastion is a self-hosted orchestrator for background coding agents. Instead of giving several agents processes or containers on a developer laptop, it creates a separate Cloud Hypervisor virtual machine for each environment. Templates define CPU, memory, disk, agents, tunnels and lifecycle actions as schema-validated JSON; prepared layers are reused, while each task receives a fresh writable overlay.
This is infrastructure, not a coding model. Bastion currently integrates OpenCode directly and exposes SSH for other tools. It can reduce conflicts and improve containment, but a VM is only one security boundary. The privileged host daemon, local API, template supply chain, network egress, secrets, repositories and merge path still require explicit policy.
How Bastion is assembled
| Component | Responsibility | Trust implication |
|---|---|---|
| Host API | Stores metadata in SQLite and serves HTTP on localhost:3148 by default | Unprivileged process, but any caller can create, enter and remove environments |
| bastiond | Performs privileged VM lifecycle and networking operations through a Unix socket | Runs as root; compromise can affect every guest and host networking |
| Cloud Hypervisor VM | Provides guest kernel, root filesystem, processes and network for one environment | Stronger separation than a shared process, but not an absolute boundary |
| Base image | Shared Ubuntu kernel/initramfs/root filesystem and guest components | A vulnerable or poisoned base propagates to every template |
| Template overlay | Immutable prepared project dependencies and init actions | Improves reproducibility; secrets must not be baked into the layer |
| Environment overlay | Writable copy-on-write disk for one task | Disposable by design; required outputs must be exported before removal |
Isolation benefits—and what they do not prove
Each VM has its own guest kernel, processes, filesystem and network. That reduces accidental conflicts between agents installing different dependencies, binding the same port or editing a common worktree. It also creates a clearer destruction unit: remove the environment instead of trying to clean an unknown process tree from a laptop.
Isolation does not grant safe autonomy by itself. A VM with a broad GitHub token can still delete branches; unrestricted egress can still exfiltrate code; a tunnel can expose a vulnerable development server; and a malicious template action runs as root inside the guest. Bastion’s current documentation also says template actions run as guest root and the host daemon runs as root. Treat both facts as design inputs, not footnotes.
| Threat | VM helps with | Additional control required |
|---|---|---|
| Two agents alter the same dependency | Separate writable disks and processes | Separate branches/worktrees and merge review |
| Agent runs destructive shell command | Damage may stay inside disposable guest | No host mounts, scoped credentials and egress limits |
| Malicious package install | Process isolation from other guests | Registry policy, lockfiles, scanning and rebuild |
| Credential misuse | None if the credential grants external authority | Short-lived per-task tokens and provider-side restrictions |
| Hypervisor or daemon exploit | VM boundary may slow lateral movement | Host patching, minimal services and dedicated worker nodes |
| Bad code reaches production | None | Protected branches, CI, review and deployment approvals |
Host requirements and installation
The current runtime requires Linux on x86_64, read/write access to /dev/kvm and /dev/vhost-vsock, and nested virtualization when the Bastion host itself is a VM. macOS Apple silicon is client-only. Required host utilities include SSH/SCP, qemu-img, mkfs.vfat, mcopy, iptables and IP tooling. Bastion can automatically install missing utilities through several package managers when explicitly requested.
The homepage offers a curl-to-shell installer, while GitHub Releases provides archives. For production, inspect the script, verify release provenance and checksum, pin a version, and record installed Cloud Hypervisor, guest kernel and base-image versions. Run bastion system check after install and after host upgrades. Do not expose the default API directly to an untrusted network.
Templates are infrastructure code
A template is immutable JSON defining resources, named tunnels, agents and lifecycle actions. During creation, Bastion boots a temporary VM, runs init actions and stores a prepared qcow2 layer. New environments add fresh writable overlays and run optional start actions. This makes dependency installation reusable and agent environments repeatable.
Version template JSON alongside the repository, but separate organization policy from project convenience. Pin package versions and Git commits. Avoid curl | bash inside init actions, floating package tags and unchecked binary downloads. Never place API keys in JSON, shell history, base images or template snapshots. A snapshot can preserve deleted files and environment state.
| Template field | Review question | Safe default |
|---|---|---|
| resources | Can one job exhaust host CPU, memory or disk? | Small quotas plus host capacity reserve |
| agents | Which server is installed and what permission mode applies? | One approved agent/version with interactive safeguards |
| actions.init | What executes as root and becomes part of the immutable layer? | Pinned, reviewed, non-secret dependency setup |
| actions.start | What changes on every boot? | Idempotent checkout and service launch with clear logs |
| tunnels | Which guest ports become reachable through the API? | No tunnel unless a task requires a reviewed preview |
| auth/secrets | Can credentials escape through logs, disks or child processes? | Short-lived task token injected only at runtime |
Repositories, branches and artifact flow
Give each environment a unique issue, branch and task key. Clone with a token that can read the repository and push only the designated branch. Do not give agents permission to bypass protected branches, approve their own pull requests or manage organization settings. Outputs should exit through a controlled path: commit/diff, test report, build artifact and machine-readable task summary.
- Create an issue with allowed paths, forbidden changes and acceptance tests.
- Mint a short-lived credential scoped to one repository and task branch.
- Create the environment from a pinned template revision.
- Run the agent with egress and runtime limits.
- Collect logs, diff, test results, dependency changes and artifact hashes.
- Revoke the credential before human review.
- Merge through normal protected-branch and CI controls.
- Remove the environment and verify data-retention expectations.
Network design and tunnels
The API binds to localhost by default, and the project warns that anyone who can reach it can create, remove and enter environments. If remote access is necessary, put it behind an authenticated TLS boundary such as a carefully configured private network. Do not change the bind address to 0.0.0.0 and assume a cloud firewall is enough.
Control guest egress by destination and purpose. Package registries, model providers and source hosts may be allowed; metadata endpoints, internal admin systems and production databases should be blocked unless a particular task is approved. Named service tunnels are useful for preview servers, but preview applications often lack authentication and run development middleware. Give tunnels short lifetimes and avoid public exposure.
Secrets and agent permissions
The example configuration references stored secrets rather than embedding key values. That is the right direction, yet injection into an agent VM still makes the secret available to a process with guest-root control. Prefer narrowly scoped installation tokens, workload identities or brokered credentials that expire automatically. Separate source access, model access, package publishing and cloud deployment into different identities.
The homepage example shows an OpenCode permission value of “allow.” Do not copy a permissive example into production without mapping its exact semantics. VM isolation reduces host impact but does not make every external action reversible. Keep high-consequence operations behind a human or policy service outside the guest.
Single host versus cluster
A single KVM host is the simplest evaluation target. The optional cluster adds shared Postgres state, S3-compatible storage for base/template archives, node registration, scheduling and proxied connections. This increases capacity and availability options, but also expands the security and backup surface.
| Design | Advantage | New responsibility |
|---|---|---|
| Single host | Smallest control plane and easiest debugging | Capacity, local failure and maintenance window |
| Multiple standalone hosts | Manual separation by team or trust level | Duplicated images, policies and scheduling |
| Bastion cluster | Shared scheduling and template distribution | Postgres, object storage, node authentication and recovery |
| Cloud KVM instances | Elastic infrastructure | Nested virtualization support, instance cost and cloud IAM |
| Dedicated bare metal | Predictable performance and clearer tenant boundary | Hardware operations and slower capacity changes |
Capacity and cost planning
VM isolation has real overhead. Budget host memory for the operating system, bastiond, the API, page cache and peak simultaneous guests. Disk consumption includes the shared base, template overlays, every writable environment, logs and cluster archives. Copy-on-write saves space initially but write-heavy builds can grow quickly.
Track environment startup latency, queue time, CPU and memory saturation, disk growth, network egress, agent/provider spend, failed-task cleanup and cost per accepted change. Set TTLs and idle termination. “Disposable” environments become permanent expense when no process owns deletion.
Alternatives
| Option | Best fit | Tradeoff versus Bastion |
|---|---|---|
| Bastion | Self-hosted per-agent VMs on Linux/KVM with declarative layers | Pre-1.0 and requires privileged infrastructure operations |
| E2B | Managed, API-first cloud sandboxes | Less self-host control and external data processor |
| Daytona | Development-environment orchestration across providers | Broader workspace focus and different isolation model |
| GitHub Actions runners | Auditable non-interactive repository automation | Less suitable for persistent conversational agents |
| Firecracker platform | Teams building a custom microVM control plane | Much more engineering, maximum architectural control |
| Rootless containers | Lower-overhead trusted workloads | Shared host kernel and weaker isolation boundary |
Frequently asked questions
Can Bastion run on a Mac?
The VM host currently requires Linux x86_64 with KVM. Apple silicon macOS can act as a client, not the virtualization host.
Which coding agents are supported?
OpenCode is the built-in integration today. SSH provides a path for other tools, but those workflows require your own setup and validation.
Is every agent in a separate VM?
Each Bastion environment receives a Cloud Hypervisor VM with its own guest kernel, filesystem, processes and network.
Is it production-ready?
The project describes itself as pre-1.0 and warns that interfaces may change. Run a limited pilot and pin exact versions.
Does VM isolation make auto-approval safe?
No. External credentials and network authority remain consequential even if host files are isolated.
Is Bastion open source?
Yes. The current repository is published under the MIT License.
Primary sources
- Official product overview and workflow
- Official repository, architecture and limitations
- Official host and runtime setup guide
- Official template guide
- Official cluster architecture guide
- Official private remote-access example
- Official MIT license
- Cloud Hypervisor documentation
Last reviewed July 25, 2026. Bastion is pre-1.0; verify the current schema, release, security notes and infrastructure requirements before rollout.



