The sandbox container's control-plane service (the Bun process started by packages/sandbox-container/src/main.ts) and the user shells it spawns currently run under the same uid. Whatever USER the Dockerfile selects applies to both.
When a downstream image adds USER to run as a less-privileged user (e.g. so Claude Code's --permission-mode bypassPermissions works, since it refuses to run as root), the control plane also drops privileges. That breaks legitimate root-only setup as the container fails to setup HTTPS interception:
{"level":"error","message":"Failed to append runtime certificate, refusing to start without HTTPS interception enabled","error":{"message":"EACCES: permission denied, open"}}
packages/sandbox-container/src/cert.ts appends the CF-injected CA cert to /etc/ssl/certs/ca-certificates.crt on startup when interceptHttps is enabled. That file is root-owned, so the appendFileSync EACCESes.
The current workaround would be to chown the CA bundle to the unprivileged user in the Dockerfile. That works but is fragile — every system file the control plane touches becomes a chown target (FUSE mounts, FIFOs in /tmp, future setup steps, …).
Alternative
Use an "init as root, work as user" pattern. The control plane stays root. User-code spawn points (bash sessions, ptys, desktop worker, code interpreter process pool) drop to a configurable unprivileged user.
The sandbox container's control-plane service (the Bun process started by
packages/sandbox-container/src/main.ts) and the user shells it spawns currently run under the same uid. WhateverUSERthe Dockerfile selects applies to both.When a downstream image adds
USERto run as a less-privileged user (e.g. so Claude Code's--permission-mode bypassPermissionsworks, since it refuses to run as root), the control plane also drops privileges. That breaks legitimate root-only setup as the container fails to setup HTTPS interception:packages/sandbox-container/src/cert.tsappends the CF-injected CA cert to/etc/ssl/certs/ca-certificates.crton startup wheninterceptHttpsis enabled. That file is root-owned, so the appendFileSync EACCESes.The current workaround would be to
chownthe CA bundle to the unprivileged user in the Dockerfile. That works but is fragile — every system file the control plane touches becomes a chown target (FUSE mounts, FIFOs in/tmp, future setup steps, …).Alternative
Use an "init as root, work as user" pattern. The control plane stays root. User-code spawn points (bash sessions, ptys, desktop worker, code interpreter process pool) drop to a configurable unprivileged user.