From 3997dcbdcc7d91a7183f0ea99bd31f87f0607fbc Mon Sep 17 00:00:00 2001 From: "Brian J. Fox" Date: Sat, 31 Oct 2026 17:31:58 +0000 Subject: [PATCH 1/2] fix(deploy): let the hub's sandboxes create user namespaces The coder and designer run every command under bubblewrap, which makes a user namespace for each one. Docker's default seccomp profile refuses that without CAP_SYS_ADMIN, so inside the Compose hub every designer tool call failed with "bwrap: No permissions to create a new namespace" and the coordinator reported the workspaces as broken. Run the hub service with seccomp=unconfined and keep its capabilities dropped. Document the Ubuntu 24.04 sysctl that strips capabilities from unprivileged user namespaces, which also blocks bubblewrap on such hosts, including the VM that Colima runs. --- deploy/compose.yml | 7 +++++++ docs/SELF_HOST.md | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/deploy/compose.yml b/deploy/compose.yml index 4f60a477..7a57f4ac 100644 --- a/deploy/compose.yml +++ b/deploy/compose.yml @@ -45,6 +45,13 @@ services: # No image name: Compose tags it after the project, so two checkouts never # share one image. <<: *hub + # The coder and designer run their commands under bubblewrap, which makes + # a user namespace for each one. Docker's default seccomp profile refuses + # that without CAP_SYS_ADMIN, so the hub runs without the profile and keeps + # its capabilities dropped. On Ubuntu 24.04 hosts the kernel must also + # allow it; see "Sandboxes" in docs/SELF_HOST.md. + security_opt: + - seccomp=unconfined ports: - "127.0.0.1:${PORT:-8000}:${PORT:-8000}" - "127.0.0.1:1455:1455" diff --git a/docs/SELF_HOST.md b/docs/SELF_HOST.md index de1c2f77..92e94ba8 100644 --- a/docs/SELF_HOST.md +++ b/docs/SELF_HOST.md @@ -76,6 +76,24 @@ To create a machine account and workspace without the UI, set the docker compose --env-file .env.hub --project-directory . -f deploy/compose.yml --profile setup run --rm setup ``` +## Sandboxes + +The coder and designer run every command under bubblewrap, which needs a user +namespace with its capabilities intact. The hub service runs with +`seccomp=unconfined` for that; its capabilities stay dropped. Ubuntu 24.04 and +later strip the capabilities from unprivileged user namespaces, so on such a +host (including the Ubuntu VM that Colima runs) also turn that restriction +off, and make it persist across reboots: + +```sh +sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 +echo kernel.apparmor_restrict_unprivileged_userns=0 | sudo tee /etc/sysctl.d/60-builder-userns.conf +``` + +Without it every designer and coder tool call fails with +`sandbox_tool_process_failed: bwrap: No permissions to create a new namespace` +or `bwrap: setting up uid map: Permission denied`. + ## Sidecars in Docker Agents run in sidecars. By default the hub starts them as processes beside From 5d23af6ef822a06af732f9fc20d0dc82156d725d Mon Sep 17 00:00:00 2001 From: "Brian J. Fox" Date: Sat, 31 Oct 2026 17:36:55 +0000 Subject: [PATCH 2/2] fix(deploy): lift AppArmor and the masked /proc for the sandbox too With only seccomp relaxed, bubblewrap gets past namespace creation and then fails twice more inside the Compose hub: Docker's AppArmor profile refuses the mount propagation change ("Failed to make / slave"), and the masked /proc paths make the fresh /proc mount impossible from a user namespace ("Can't mount proc on /proc"). The sandbox runtime's own srt command runs only once all three are lifted, so run the hub without them; its capabilities stay dropped. Closes #30 --- deploy/compose.yml | 14 +++++++++----- docs/SELF_HOST.md | 9 +++++---- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/deploy/compose.yml b/deploy/compose.yml index 7a57f4ac..cc216126 100644 --- a/deploy/compose.yml +++ b/deploy/compose.yml @@ -45,13 +45,17 @@ services: # No image name: Compose tags it after the project, so two checkouts never # share one image. <<: *hub - # The coder and designer run their commands under bubblewrap, which makes - # a user namespace for each one. Docker's default seccomp profile refuses - # that without CAP_SYS_ADMIN, so the hub runs without the profile and keeps - # its capabilities dropped. On Ubuntu 24.04 hosts the kernel must also - # allow it; see "Sandboxes" in docs/SELF_HOST.md. + # The coder and designer run their commands under bubblewrap, which gives + # each one its own user, pid and mount namespaces with a fresh /proc. + # Docker's default seccomp profile refuses the namespaces without + # CAP_SYS_ADMIN, its AppArmor profile refuses the mount propagation, and + # its masked /proc paths refuse the fresh /proc, so the hub runs without + # those three and keeps its capabilities dropped. On Ubuntu 24.04 hosts + # the kernel must also allow it; see "Sandboxes" in docs/SELF_HOST.md. security_opt: - seccomp=unconfined + - apparmor=unconfined + - systempaths=unconfined ports: - "127.0.0.1:${PORT:-8000}:${PORT:-8000}" - "127.0.0.1:1455:1455" diff --git a/docs/SELF_HOST.md b/docs/SELF_HOST.md index 92e94ba8..6d8814be 100644 --- a/docs/SELF_HOST.md +++ b/docs/SELF_HOST.md @@ -79,10 +79,11 @@ docker compose --env-file .env.hub --project-directory . -f deploy/compose.yml - ## Sandboxes The coder and designer run every command under bubblewrap, which needs a user -namespace with its capabilities intact. The hub service runs with -`seccomp=unconfined` for that; its capabilities stay dropped. Ubuntu 24.04 and -later strip the capabilities from unprivileged user namespaces, so on such a -host (including the Ubuntu VM that Colima runs) also turn that restriction +namespace with its capabilities intact, mount propagation and a fresh `/proc`. +The hub service runs with `seccomp=unconfined`, `apparmor=unconfined` and +`systempaths=unconfined` for that; its capabilities stay dropped. Ubuntu 24.04 +and later strip the capabilities from unprivileged user namespaces, so on such +a host (including the Ubuntu VM that Colima runs) also turn that restriction off, and make it persist across reboots: ```sh