Skip to main content
USER name:group silently drops supplementary groups established earlier in the Dockerfile.
PropertyValue
SeverityWarning
CategorySecurity
DefaultEnabled
Auto-fixYes (suggestion)
PlatformsLinux + Windows

Description

Docker’s USER reference is explicit about an easy-to-miss behavior:
Note that when specifying a group for the user, the user will have only the specified group membership. Any other configured group memberships will be ignored.
This applies to both Linux and Windows containers. Any supplementary group the Dockerfile adds the user to via one of these commands is silently dropped the moment USER name:group takes effect:
PlatformCommands
Linuxuseradd -G, usermod -aG / -G, gpasswd -a, adduser USER GROUP, addgroup USER GROUP
Windows cmdnet localgroup <GROUP> <USER> /add
Windows PSAdd-LocalGroupMember -Group <GROUP> -Member <USER>
The most common real-world symptom on Linux is a user added to the docker group then locked out of /var/run/docker.sock at runtime. On Windows, the corresponding symptom is a user added to a local group (for example a custom app-writers group) then unable to access files whose ACL only grants that group.

Examples

Bad — Linux

FROM ubuntu:22.04
RUN groupadd -r docker && \
    useradd -r -g app -G docker,wheel app
USER app:app
The docker and wheel supplementary groups are dropped at runtime.

Bad — Windows cmd

FROM mcr.microsoft.com/windows/servercore:ltsc2022
RUN net user app password /add && net localgroup docker app /add
USER app:docker
app is added to docker via net localgroup /add, but USER app:docker restricts the process to only the docker token — any other local-group membership is dropped.

Bad — Windows PowerShell

FROM mcr.microsoft.com/windows/servercore:ltsc2022
SHELL ["pwsh", "-Command"]
RUN New-LocalUser -Name app -NoPassword -AccountNeverExpires ; \
    Add-LocalGroupMember -Group docker -Member app
USER app:docker

Good — drop the explicit group

FROM ubuntu:22.04
RUN useradd -r -g app -G docker app
USER app
Docker uses the user’s primary group from /etc/passwd (or the Windows token) plus every supplementary group that was added.

Suppression

The rule does not fire when:
  • The USER instruction uses no explicit group (USER app rather than USER app:group).
  • The user is root or UID 0.
  • The user specifier is numeric (USER 1000:1000). We do not correlate UIDs to useradd-created accounts; the rule targets named identities.
  • The stage is passwd-less (scratch-rooted without a copied /etc/passwd). That case belongs to tally/named-identity-in-passwdless-stage.

Suggested fix

The rule proposes a FixSuggestion that removes the :group portion so the user’s supplementary groups survive. Run with --fix --fix-unsafe to apply it.
# Before
USER app:app

# After
USER app
If the explicit group was an intentional primary-group override, keep the current form and resolve the rule via configuration:
[rules.tally.user-explicit-group-drops-supplementary-groups]
severity = "off"

Configuration

[rules.tally.user-explicit-group-drops-supplementary-groups]
severity = "warning"  # Options: "off", "error", "warning", "info", "style"

References