Sandbox Images¶
Every bot runs its commands inside a Docker sandbox created by LocalDockerEnvironment. The sandbox runs an unmodified image from the Microsoft Container Registry, and you choose it by passing image. Two images have constants in microbots.environment.local_docker.images:
| Constant | Image | Use it for |
|---|---|---|
DEBIAN_IMAGE (default) |
mcr.microsoft.com/devcontainers/python:3.11 |
General work. Debian with Python and a full developer toolset. |
AZURELINUX_IMAGE |
mcr.microsoft.com/azurelinux/base/core:3.0 |
Azure Linux and RPM work. Its tdnf repos package mock, rpm-build, and golang. |
How a stock image becomes a sandbox¶
There is no custom image to build. When an environment starts, Microbots:
- Starts the image idle.
- Copies its shell server (
local_docker/shell_server) into/opt/microbots, owned by root. - Runs
shell_server/prepare.shas root. It installs anything missing (Python,useradd,mount,git) withapt-get,tdnf,dnf, oryum. It also creates the unprivilegedagentaccount, removes the devcontainer's passwordless-sudovscodeuser, and installs the server's dependencies (FastAPI, uvicorn, pydantic) into a root-owned venv. - Starts the shell server, which drops to the
agentaccount before running any bot command.
Preparation needs network access for package and PyPI downloads. It takes about 10 seconds on DEBIAN_IMAGE and about 40 seconds on AZURELINUX_IMAGE, which also installs Python and the user tools.
Choose an image¶
Pass image to any bot or to LocalDockerEnvironment:
from microbots import WritingBot
from microbots.environment.local_docker.images import AZURELINUX_IMAGE
bot = WritingBot(
model="azure-openai/your-deployment",
folder_to_mount="/path/to/repo",
image=AZURELINUX_IMAGE,
)
from microbots.environment.local_docker.LocalDockerEnvironment import LocalDockerEnvironment
env = LocalDockerEnvironment(port=8080, image="mcr.microsoft.com/devcontainers/base:debian")
- Any image works if it has
shandbash, plus eitherpython3or one of the supported package managers. Images that already include the prerequisites start faster. - A bot's
imageonly applies to the environment the bot creates. If you pass your ownenvironment, choose the image when you create it; passing both raisesValueError.
Tools and distros¶
You never declare the sandbox's distribution. Tools read it from the running container's /etc/os-release and pick their distro-specific commands from it. A tool that only defines debian commands, such as cscope or browser-use, fails to install on the Azure Linux image with UnsupportedDistroError.
Azure Linux build tools¶
Microbots ships tool definitions for Azure Linux and RPM work:
| Tool | Provides | Distros |
|---|---|---|
rpm.yaml |
rpm, rpmbuild, rpmspec, rpm2cpio, createrepo_c |
Azure Linux, Debian |
mock.yaml |
mock with the rpmautospec plugin. Needs sudo_access=True. |
Azure Linux |
azldev.yaml |
Azure Linux Dev Tools. Uses mock for render and build. |
Azure Linux, Debian |
from microbots import WritingBot
from microbots.environment.local_docker.images import AZURELINUX_IMAGE
from microbots.tools.tool_yaml_parser import parse_tool_definition
bot = WritingBot(
model="azure-openai/your-deployment",
folder_to_mount="/path/to/azurelinux",
image=AZURELINUX_IMAGE,
sudo_access=True,
additional_tools=[parse_tool_definition(n) for n in ("rpm.yaml", "mock.yaml", "azldev.yaml")],
)
mock.yamladds the agent to themockgroup, so the agent runsmock(andazldev, which drives it) as itself.mock's setuid launcher does the privileged work, which is why it needssudo_access=True. Files thatazldevandmockwrite into the repository stay owned by the host user.azldev.yamlinstalls theazldevversion pinned in the mounted repository's.azldev-versionfile, or the latest release if there is no pin.
Sudo access¶
By default the sandbox shell drops to an unprivileged agent account that has your host user's uid, and the container blocks privilege escalation (no-new-privileges). Some tools, such as mock, need root for part of their work. Pass sudo_access=True to any bot or to LocalDockerEnvironment to give the agent passwordless sudo:
bot = WritingBot(
model="azure-openai/your-deployment",
folder_to_mount="/path/to/repo",
image=AZURELINUX_IMAGE,
sudo_access=True,
)
- The agent's commands still run as your uid unless it explicitly uses
sudo, so files it writes in aREAD_WRITEmount stay owned by you. Files it writes throughsudoare owned by root and are left that way. sudo_accessapplies to the environment the bot creates. If you pass your ownenvironment, create it withLocalDockerEnvironment(..., sudo_access=True).- The container is started without
no-new-privileges, sosudoand setuid helpers (such asmock's launcher) work. Ifsudodoesn't work in the image, the environment fails to start with aRuntimeError.
Warning
Sudo access turns the sandbox into a guardrail rather than an isolation boundary. Through sudo the agent has root with the container's SYS_ADMIN capability and AppArmor unconfined, so it can mount filesystems and reach host-wide kernel interfaces (for example core_pattern or a cgroup release_agent). A misbehaving or prompt-injected agent could therefore remount a READ_ONLY mount as writable, or gain root on the host. A READ_ONLY mount still works for a cooperative agent, and its changes are discarded with the sandbox. Enable sudo access only for trusted tasks and trusted repositories, skills, and instructions.