feat(macos): replace rootless Docker spike with rootless podman
test / stage-firecracker-inputs (pull_request) Successful in 2s
test / integration-docker (pull_request) Successful in 32s
test / unit (pull_request) Successful in 36s
lint / lint (push) Failing after 52s
test / build-infra (pull_request) Successful in 4m5s
tracker-policy-pr / check-pr (pull_request) Successful in 8s
test / integration-firecracker (pull_request) Successful in 2m2s
test / coverage (pull_request) Successful in 2m7s
test / publish-infra (pull_request) Has been skipped
test / stage-firecracker-inputs (pull_request) Successful in 2s
test / integration-docker (pull_request) Successful in 32s
test / unit (pull_request) Successful in 36s
lint / lint (push) Failing after 52s
test / build-infra (pull_request) Successful in 4m5s
tracker-policy-pr / check-pr (pull_request) Successful in 8s
test / integration-firecracker (pull_request) Successful in 2m2s
test / coverage (pull_request) Successful in 2m7s
test / publish-infra (pull_request) Has been skipped
Podman avoids the CAP_SYS_ADMIN requirement that makes rootless Docker impossible here: with no subordinate UID range configured it falls back to a single-UID self-mapping, which an unprivileged process may write itself, so newuidmap is never invoked. The image build therefore strips /etc/subuid and /etc/subgid entries rather than adding them. The agent-facing surface is unchanged — docker and docker compose talk to podman's Docker-compatible API socket. Two device nodes need relaxing as root inside the bottle (0666 on /dev/fuse and /dev/net/tun); both already exist and neither needs a capability the bottle lacks, unlike CAP_SYS_ADMIN. Verified live on macOS 26 / Apple Container 1.0.0: service starts with zero added capabilities, compose pulls and serves from the workspace on a published port, and a nested container cannot reach the network outside the egress path. Known limitation, not yet addressed: the agent base image is Debian bookworm, whose podman 4.3.1 swallows container exit codes through the compat API (docker run returns 0 regardless). podman 5.4.2 on trixie fixes it; the base bump is a separate PR. The acceptance test asserts on an in-band marker rather than an exit code so it cannot false-pass in the meantime. Nested containers give no isolation from the agent itself — root inside one is the agent user outside it. They are a build/test convenience; the bottle remains the security boundary. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GnMp8SUGH57hZX7192Rv2F
This commit is contained in:
@@ -75,13 +75,21 @@ On compatible macOS hosts, the default backend requires Apple's `container` CLI
|
||||
|
||||
Use `BOT_BOTTLE_BACKEND=docker ./cli.py start <agent>` on hosts where neither Apple Container nor KVM is available and Docker is the desired backend.
|
||||
|
||||
> **Experimental Docker-in-bottle spike (#392):** a bottle may set
|
||||
> **Experimental containers-in-bottle spike (#392):** a bottle may set
|
||||
> `docker_access: true`. On the macOS backend this starts a guest-local,
|
||||
> rootless Docker daemon after the bottle is registered. It does not mount
|
||||
> Docker Desktop's socket or add outer VM capabilities. The spike currently
|
||||
> requires live-macOS validation before it is considered supported; startup
|
||||
> fails closed when the Apple guest kernel cannot satisfy rootless Docker's
|
||||
> user-namespace requirements.
|
||||
> rootless **podman** service after the bottle is registered, exposing its
|
||||
> Docker-compatible API socket — the agent still uses `docker` and `docker
|
||||
> compose`. It does not mount Docker Desktop's socket or add outer VM
|
||||
> capabilities. Rootless Docker was tried first and does not work here at
|
||||
> all: Apple Container's capability bounding set omits `CAP_SYS_ADMIN`,
|
||||
> which the kernel requires to write a multi-range `uid_map`. See
|
||||
> [`docs/research/rootless-docker-in-apple-container-spike.md`](docs/research/rootless-docker-in-apple-container-spike.md).
|
||||
>
|
||||
> The tradeoff to understand before enabling it: podman avoids that
|
||||
> requirement by falling back to a single-UID mapping, so nested containers
|
||||
> provide **no isolation from the agent itself** — `root` inside a nested
|
||||
> container is the agent user outside it. Nested containers are a build/test
|
||||
> convenience, not a security boundary. The bottle remains the boundary.
|
||||
|
||||
### Firecracker on Linux
|
||||
|
||||
|
||||
Reference in New Issue
Block a user