# How AstrBot's Agent Sandbox Isolates Code Execution for Security

> Learn how AstrBot's agent sandbox isolates code execution using pluggable booters, process isolation, filesystem isolation, and capability gating for enhanced security.

- Repository: [AstrBot AI/AstrBot](https://github.com/AstrBotDevs/AstrBot)
- Tags: internals
- Published: 2026-03-12

---

**AstrBot isolates agent code execution by running it inside sandboxed containers managed through pluggable booters like Shipyard Neo or Boxlite, enforcing process isolation, filesystem isolation, capability gating, and automatic TTL expiration.**

AstrBot is an open-source LLM agent framework that enables AI agents to execute code, interact with shells, and manipulate files. To prevent malicious or buggy agent code from compromising the host system, AstrBot implements a robust **Agent Sandbox** architecture that delegates all execution to isolated runtime environments. This article examines how the sandbox system works, from configuration to lifecycle management, based on the implementation in the `AstrBotDevs/AstrBot` repository.

## Configuration and Sandbox Selection

The sandbox system is controlled through the `provider_settings` configuration in [`astrbot/core/config/default.py`](https://github.com/AstrBotDevs/AstrBot/blob/main/astrbot/core/config/default.py). By default, the `computer_use_runtime` is set to `"none"`, but enabling agent capabilities requires setting it to `"sandbox"` and configuring a booter implementation.

```json
{
  "computer_use_runtime": "sandbox",
  "sandbox": {
    "booter": "shipyard_neo",
    "shipyard_neo_endpoint": "",
    "shipyard_neo_access_token": "",
    "shipyard_neo_profile": "python-default",
    "shipyard_neo_ttl": 3600
  }
}

```

The `booter` field determines which isolation backend to use. **Shipyard Neo** connects to an external Bay service or spins up local Docker containers, while **Boxlite** provides a lightweight mock container for local testing. This pluggable architecture allows operators to choose between full container isolation or lightweight sandboxing based on deployment constraints.

## Shipyard Neo Booter: Container-Based Isolation

The `ShipyardNeoBooter` class in [`astrbot/core/computer/booters/shipyard_neo.py`](https://github.com/AstrBotDevs/AstrBot/blob/main/astrbot/core/computer/booters/shipyard_neo.py) implements the core isolation logic by managing Docker-based Bay containers. It creates fresh sandbox instances for each session, ensuring complete separation between agent executions.

### Auto-Start Mode and Docker Containers

When the `shipyard_neo_endpoint` is set to `"__auto__"` or left empty, the booter automatically launches a local Docker container using `BayContainerManager`. This spawns an isolated process space separate from the AstrBot host process.

```python

# From shipyard_neo.py lines 10-27

if endpoint in ("__auto__", ""):
    self.container_manager = BayContainerManager()
    await self.container_manager.start()
    credentials = self.container_manager.get_credentials()
    endpoint = credentials["endpoint"]
    access_token = credentials["access_token"]

```

The container runs its own Python interpreter and shell, with filesystem mounts strictly limited to the container's own directories.

### Sandbox Creation and TTL

After authentication, the booter creates a fresh sandbox with a defined time-to-live (TTL). The default TTL of 3600 seconds ensures that even if cleanup fails, the sandbox will automatically expire, limiting the window for any malicious activity.

```python

# From shipyard_neo.py lines 48-55

self._sandbox = await self._client.create_sandbox(
    profile=self.config.get("shipyard_neo_profile", "python-default"),
    ttl=self.config.get("shipyard_neo_ttl", 3600)
)

```

### Capability Restriction

The sandbox advertises only specific capabilities through `self._sandbox.capabilities`. The booter selectively exposes tools based on these capabilities, preventing agents from accessing functionality not explicitly granted (such as browsers, network access, or GPUs).

```python

# From shipyard_neo.py lines 90-100

if "browser" in self._sandbox.capabilities:
    self._browser = NeoBrowserComponent(self._sandbox)
else:
    self._browser = None

```

## Isolated Execution Components

The `ShipyardNeoBooter` exposes four isolated execution components, each wrapping sandbox-specific functionality while keeping the host process insulated:

| Component | Implementation | Isolation Mechanism |
|-----------|---------------|---------------------|
| **NeoPythonComponent** | [`astrbot/core/computer/booters/shipyard_neo.py`](https://github.com/AstrBotDevs/AstrBot/blob/main/astrbot/core/computer/booters/shipyard_neo.py) lines 32-41 | Executes Python via `self._sandbox.python.exec`, running in the sandbox's isolated interpreter with limited memory and CPU. |
| **NeoShellComponent** | [`astrbot/core/computer/booters/shipyard_neo.py`](https://github.com/AstrBotDevs/AstrBot/blob/main/astrbot/core/computer/booters/shipyard_neo.py) lines 73-84 | Executes shell commands via `self._sandbox.shell.exec`, confined to the container's namespace. |
| **NeoFileSystemComponent** | [`astrbot/core/computer/booters/shipyard_neo.py`](https://github.com/AstrBotDevs/AstrBot/blob/main/astrbot/core/computer/booters/shipyard_neo.py) lines 38-71 | File operations via `self._sandbox.filesystem`, with paths resolved relative to the sandbox root. |
| **NeoBrowserComponent** | [`astrbot/core/computer/booters/shipyard_neo.py`](https://github.com/AstrBotDevs/AstrBot/blob/main/astrbot/core/computer/booters/shipyard_neo.py) lines 60-62 | Only instantiated if the sandbox profile includes the `browser` capability. |

Each component returns a structured dictionary containing `success`, `stdout`, `stderr`, and execution metadata, ensuring the host process never directly handles agent-generated data streams.

## Local Mock Sandbox with Boxlite

For development environments or deployments without Docker access, `BoxliteBooter` in [`astrbot/core/computer/booters/boxlite.py`](https://github.com/AstrBotDevs/AstrBot/blob/main/astrbot/core/computer/booters/boxlite.py) provides a lightweight mock sandbox. It spins up a `SimpleBox` container and wraps it with `MockShipyardSandboxClient`, implementing the same RPC interface as the real Shipyard client.

```python

# From boxlite.py lines 31-38 and 50-68

self.box = SimpleBox()
await self.box.start()
self.mock_client = MockShipyardSandboxClient(self.box)
self._sandbox = await self.mock_client.create_sandbox(profile=profile, ttl=ttl)

```

Even in this mock mode, agent code never touches the host filesystem directly. All reads and writes flow through the mocked sandbox client, preserving the isolation contract while enabling local testing.

## Lifecycle Management and Health Checks

The sandbox lifecycle is strictly managed to prevent stale or compromised instances from processing agent requests.

**Health Monitoring**: The `available()` method probes sandbox health via `self._sandbox.refresh()`. If the status is "failed" or "expired", the booter reports the sandbox as unavailable, triggering creation of a fresh instance.

```python

# From shipyard_neo.py lines 97-110

async def available(self) -> bool:
    if not self._sandbox:
        return False
    try:
        await self._sandbox.refresh()
        return self._sandbox.status not in ("failed", "expired")
    except Exception:
        return False

```

**Graceful Shutdown**: The `shutdown()` method destroys the sandbox via `self._client.__aexit__()`, but intentionally preserves the underlying Bay container for reuse across sessions. This balances security (sandbox state is wiped) with performance (container startup overhead is avoided).

**Skill Synchronization**: Before execution, `computer_client._sync_skills_to_sandbox` uploads the current skill bundle to the sandbox filesystem and rescans metadata inside the isolated environment. This ensures the agent operates on a consistent, isolated copy of the skill code.

## How the Sandbox Protects the Host

AstrBot's Agent Sandbox implements defense in depth through multiple isolation mechanisms:

- **Process Isolation**: Each sandbox runs in its own Docker container (Bay) or lightweight namespace (Boxlite), ensuring agent processes cannot access the AstrBot host process memory or PID namespace.
- **Filesystem Isolation**: Agents interact only with the sandbox's `/workspace/` tree. The container's mount namespace prevents path traversal attacks that might escape to the host filesystem.
- **Capability Gating**: Only capabilities explicitly declared in the sandbox profile (e.g., `browser`, `filesystem`) are exposed to the agent. Missing capabilities (network, GPU, raw sockets) are unavailable by default.
- **Time-to-Live (TTL)**: Sandboxes automatically expire after the configured TTL (default 3600 seconds), limiting the window for any persistent compromise or resource exhaustion attack.

Together, these layers ensure that even if an LLM agent generates malicious code, the execution is confined to a temporary, restricted environment that cannot affect the host system or other sessions.

## Summary

- AstrBot isolates agent code execution using **sandboxed containers** managed by pluggable booters like `ShipyardNeoBooter` and `BoxliteBooter`.
- The **Shipyard Neo** integration creates fresh Docker-based sandboxes with configurable TTL, process isolation, and capability-based access controls.
- **Isolated components** (`NeoPythonComponent`, `NeoShellComponent`, `NeoFileSystemComponent`, `NeoBrowserComponent`) ensure agent code never runs directly on the host.
- **Boxlite** provides a lightweight mock sandbox for local development while maintaining the same isolation contract.
- **Health checks and lifecycle management** prevent use of expired or failed sandboxes, with automatic cleanup and skill synchronization keeping environments fresh.

## Frequently Asked Questions

### How does AstrBot prevent sandbox escape vulnerabilities?

AstrBot relies on container-level isolation through Docker (for production) or lightweight namespaces (for testing). The sandbox runs in its own mount namespace, preventing filesystem escape, and has no access to the host's PID or network namespaces unless explicitly granted through capabilities. Additionally, the TTL expiration ensures that even if a sandbox is compromised, it has a limited lifetime.

### What is the difference between Shipyard Neo and Boxlite booters?

**Shipyard Neo** is the production booter that connects to an external Bay service or launches local Docker containers to provide full isolation. **Boxlite** is a lightweight mock implementation intended for development and testing environments where Docker is unavailable. While Boxlite simulates the sandbox interface, it may not provide the same level of kernel-level isolation as Docker-based sandboxes.

### Can I restrict which capabilities an agent has access to?

Yes. Capabilities are controlled through the `shipyard_neo_profile` configuration option. Each profile defines available capabilities such as `browser`, `filesystem`, `shell`, or `python`. The `ShipyardNeoBooter` only instantiates components for capabilities advertised by the sandbox (e.g., `NeoBrowserComponent` is only created if the `browser` capability exists). This prevents agents from accessing unapproved system resources.

### How does the sandbox handle skill code synchronization?

Before executing agent tools, [`computer_client.py`](https://github.com/AstrBotDevs/AstrBot/blob/main/computer_client.py) calls `_sync_skills_to_sandbox` to upload the current skill bundle to the sandbox's isolated filesystem via `upload_file`. It then rescans skill metadata inside the sandbox to update the UI-visible cache. This ensures the agent operates on a fresh, isolated copy of skills rather than accessing the host's skill directory directly.