How to Sandbox Hermes with Apple’s container CLI?

The native option on macOS Tahoe — one lightweight VM per container, signed by Apple, no third-party daemon. The shortest-possible-path sandbox for Hermes on Apple Silicon.

Setup time ~20 minutes
Disk budget ~12 GB (cap at 20 GB)
One-time cost Free
Going cost Free (Apache-2)

Ingredients

Apple’s container takes an unusual approach: every container is its own lightweight VM. There is no shared kernel and no shared daemon — each workload starts its own micro-VM in well under a second on Apple Silicon. The image format is OCI-compatible, so you can pull anything from Docker Hub or build a Dockerfile unchanged.

On macOS Tahoe (26) this is the lightest option on the page. The kernel-level VirtioFS path is first-class, idle resource use is measured in tens of megabytes, and the whole stack ships from Apple, signed and notarised. If you are on Tahoe and on Apple Silicon, this is the recipe to try first.

Older macOS? The container tool needs macOS Sequoia (15) at minimum — some features only became first-class in Tahoe. On Sonoma (14) it will not start; on Sequoia most things work but VirtioFS performance is noticeably lower than on Tahoe. If you are stuck on an older release, see the OrbStack recipe instead.

1 Install the tool

Download the signed installer from the releases page and run the .pkg. Or via Homebrew:

brew install --cask container

Start the system service (it idles when nothing is running) and confirm:

container system start
container --version

2 Create the one shared folder

mkdir -p ~/hermes-workspace

This is the only path Hermes will see from the Mac. Anything outside it is not in its filesystem namespace at all — not because it has been politely asked to stay away, but because the bind mount does not exist.

3 Write the Hermes image

The Dockerfile is the same OCI format that Docker and Colima use. In ~/hermes-image/Dockerfile:

FROM python:3.12-slim-bookworm

ENV PATH=/root/.local/share/fnm:/root/.local/bin:$PATH \
    HERMES_WORKSPACE=/workspace

RUN apt-get update && \
    apt-get install -y --no-install-recommends curl git build-essential ca-certificates && \
    rm -rf /var/lib/apt/lists/*

RUN curl -fsSL https://fnm.vercel.app/install | bash -s -- --skip-shell && \
    /root/.local/share/fnm/fnm install 22 && \
    /root/.local/share/fnm/fnm default 22

RUN git clone https://github.com/NousResearch/hermes-agent.git /opt/hermes && \
    pip install --no-cache-dir -e /opt/hermes

WORKDIR /workspace
CMD ["hermes", "run", "--workspace", "/workspace"]

Build with Apple’s native builder — it produces a linux/arm64 image natively on Apple Silicon, no emulation:

cd ~/hermes-image
container build -t hermes-sandbox:latest .

4 Run with one volume and hard limits

container run -it --rm \
    --name hermes \
    --memory 4g \
    --cpus 4 \
    --volume ~/hermes-workspace:/workspace \
    hermes-sandbox:latest

Each container run spins up its own micro-VM with its own kernel and the resource ceiling you gave it. The --volume flag is the one bridge to the Mac. On Tahoe the underlying transport is VirtioFS at the kernel level, so the read/write traffic an agent produces stays fast even when it touches thousands of small files.

Disk cap: unlike Docker Desktop and OrbStack, container does not give every micro-VM a giant pre-sized disk. Each VM’s root is a thin overlay on the image, with a small writable layer on top — typical footprint per run is hundreds of megabytes. The 20 GB budget in this recipe is for image storage; you will rarely come close.

5 Verify the seam

From the host:

echo "from the mac" > ~/hermes-workspace/in.txt

From the container (in the Hermes prompt or a second shell via container exec -it hermes bash):

cat /workspace/in.txt
echo "from the vm" > /workspace/out.txt

Back on the host:

cat ~/hermes-workspace/out.txt

That single folder is the entire surface area of the sandbox.

Day-to-day commands

# list running containers (= running micro-VMs)
container list

# stop a running one
container stop hermes

# delete the image when you no longer need it
container rmi hermes-sandbox:latest

# stop the background service entirely
container system stop

Because the service idles when nothing is running, there is no penalty to leaving it installed and starting Hermes only when you need it.

What you end up with

A Hermes image that runs as its own lightweight VM on Apple Silicon, started by an Apple-signed system service on macOS Tahoe, with one host folder bind-mounted at /workspace. Each run is independent — nothing carries over between them except whatever was written into the shared folder. The closest thing to a sandboxed Linux process that macOS offers natively.

Back to the main recipe

← How to Run Hermes in a macOS Sandbox?

Further reading