Problem
In docker/usr/local/bin/docker-entrypoint.sh, NEED_USER_SWITCH starts as false and only flips to true inside the Docker-socket GID-mismatch branch:
NEED_USER_SWITCH=false
if [ -S "/var/run/docker.sock" ]; then
# ... only sets NEED_USER_SWITCH=true when SOCKET_GID != DOCKER_GROUP_GID
fi
if [ "$NEED_USER_SWITCH" = "true" ]; then
exec gosu claude "$@"
else
exec "$@" # <-- runs as root
fi
The Dockerfile ends with USER root, so for ephemeral containers (DCLAUDE_RM=true, which use the image ENTRYPOINT directly) Claude runs as root whenever:
- No Docker socket was mounted (the launcher warns "Container will not have Docker access" and continues), or
- The socket GID happens to equal the container's
docker group GID (plausible on Linux where host docker GID is commonly 999)
Persistent containers are unaffected only because the launcher always uses docker exec -u claude.
Impact
- Claude runs with root privileges inside the container — defeats the non-root design stated in SECURITY.md
- On native Linux hosts, files written to the bind-mounted project are root-owned
Fix
The final exec should always drop to the claude user when currently root, regardless of whether group surgery was needed:
if [ "$(id -u)" = "0" ]; then
exec gosu claude "$@"
else
exec "$@"
fi
Related: #66 (UID mapping on Linux hosts) — same entrypoint area.
Found during a full-project code review.
Problem
In
docker/usr/local/bin/docker-entrypoint.sh,NEED_USER_SWITCHstarts asfalseand only flips totrueinside the Docker-socket GID-mismatch branch:The Dockerfile ends with
USER root, so for ephemeral containers (DCLAUDE_RM=true, which use the image ENTRYPOINT directly) Claude runs as root whenever:dockergroup GID (plausible on Linux where host docker GID is commonly 999)Persistent containers are unaffected only because the launcher always uses
docker exec -u claude.Impact
Fix
The final exec should always drop to the claude user when currently root, regardless of whether group surgery was needed:
Related: #66 (UID mapping on Linux hosts) — same entrypoint area.
Found during a full-project code review.