A teammate asks to be added to the `docker` group on a shared Linux build server so they can run builds without sudo. Why do security reviewers treat that as equivalent to granting passwordless root, and what would you propose instead?
answer
- socket owned root:docker, mode 0660
- daemon acts with its own root privileges
- bind-mount / then chroot
- AuthZ plugin = leaky deny-list
- rootless dockerd / Podman as the fix
basics
~20 sThe Docker daemon runs as root and docker group members can talk to its socket. One container that bind-mounts the host filesystem gives them full root. Offer rootless Docker, Podman, or a narrow sudo rule instead.
solid answer
~50 sMembership in the `docker` group grants read/write access to `/var/run/docker.sock`, and the daemon behind it runs as **root**. The daemon API has no concept of a limited user: anyone who can call it can start a container that bind-mounts `/` and runs as uid 0, then `chroot` into the host and do anything root can do — rewrite `/etc/shadow`, read every secret, load a kernel module. They can also run `--privileged` or pass through host devices. So it is a root grant, and a poorly audited one: the work happens as the daemon, not as the human. Instead I would give them **rootless Docker** (a per-user daemon inside a user namespace) or **Podman** (daemonless, containers run under their own uid). If rootful Docker is unavoidable, a tightly scoped `sudo` rule or a build service that runs builds on their behalf at least preserves attribution.
code
bash · 5 linesdocker run --rm -it -v /:/host alpine chroot /host sh
# now root on the host filesystem
# the CLI is not the boundary — the API is reachable directly
curl -s --unix-socket /var/run/docker.sock http://localhost/v1.44/infogo deeper
Recall the core fact: the daemon is root, the group talks to the daemon, therefore the group is root. Be able to name the bind-mount-plus-chroot example.
Add why it is by design rather than a bug, and that the API — not the CLI — is the boundary being crossed.
Discuss AuthZ plugins as partial mitigation, audit attribution, and concretely propose rootless Docker or Podman with migration caveats.
Frame it as access governance: which hosts may run a rootful daemon at all, how membership is reviewed like sudoers, and what the org-wide default runtime should be.
## What the group actually is On a standard Linux install `dockerd` runs as root and listens on a Unix socket, normally `/var/run/docker.sock`, owned `root:docker` with mode `0660`. The `docker` group exists purely so non-root users can open that socket without `sudo`. It is a convenience group, not a privilege tier — there is no reduced API surface for group members. ## Why socket access equals root The daemon executes requests with its own privileges. Ask it to create a container with a bind mount of the host root and it complies, because from the daemon's point of view that is an ordinary, supported feature. Inside that container you are uid 0 with a writable view of the entire host filesystem. `chroot` into it and you own the machine. Variations achieve the same thing: `--privileged` (all capabilities, unmasked `/proc`, device access), `--pid=host` plus `nsenter`, mounting `/etc` or root's SSH authorized_keys, or attaching a raw device via `--device`. None of these are exploits; they are documented features, so there is no patch that removes the equivalence. ## Why partial mitigations do not work People propose auditing the socket, wrapping the CLI, or filtering commands. Wrapping the *client* is meaningless because the group grants access to the *API*: `curl --unix-socket /var/run/docker.sock` speaks it directly. An authorization plugin (AuthZ) on the daemon can restrict specific API calls, but it is a deny-list you must keep exhaustive across mounts, capabilities, devices, namespace sharing and image builds, and it fails open if the plugin dies. The honest position is that `docker` group membership is a root grant and should be reviewed with the same seriousness as adding someone to sudoers with NOPASSWD ALL. ## The alternatives **Rootless Docker** runs `dockerd` as the unprivileged user inside a user namespace, so the worst case of a daemon or container compromise is that user's own account, not root. **Podman** removes the daemon entirely: `podman run` forks the container as a child of the invoking user, so kernel audit records keep the real login uid and there is no shared socket acting as a root gateway. Where rootful is genuinely required (privileged builds, low ports, device passthrough, swarm overlay networking), keep the machine single-purpose, restrict who can log in at all, and treat every group member as an administrator of that host in access reviews. ## What to say in an interview State the equivalence in one sentence, describe the one-command escalation, note that it is by design rather than a bug, and then move immediately to rootless or Podman as the real answer. That progression — mechanism, then remediation — is what interviewers listen for.
- Does putting an authorization plugin in front of the daemon make docker group membership safe?It narrows the surface but does not close it. An AuthZ plugin inspects API requests and must block every escalation path — bind mounts, --privileged, capabilities, devices, PID/network namespace sharing, and build-time mounts — which is an exhaustive deny-list you have to maintain against every new daemon feature. It is defense in depth, not a privilege boundary.
- How does rootless mode change the blast radius of that same bind-mount trick?In rootless mode the daemon runs as your unprivileged user inside a user namespace, so it can only mount and read what that user could already read. Container uid 0 maps to a high, unprivileged host uid, so chrooting into a mounted host path gives you your own permissions, not root's. You cannot escalate beyond the account you already had.
The docker group is not a restricted keycard — it is a phone line to someone who already holds the master key and does whatever you ask.
saying these in an interview costs you the question
- Claiming the docker group is 'like sudo but only for Docker commands' — it is unrestricted root
- Believing a wrapper script or restricted shell helps, when the socket API is reachable with curl
- Thinking --privileged is required to escape; a plain bind mount of / is enough
- Saying rootful Docker is fine because 'we trust our developers', with no mention of blast radius or audit attribution