Skip to main content
Named user/group in USER or —chown requires /etc/passwd which passwd-less stages lack.
PropertyValue
SeverityWarning
CategoryCorrectness
DefaultEnabled

Description

Detects named (non-numeric) user or group references in USER instructions or COPY/ADD --chown flags within stages that lack /etc/passwd or /etc/group. Named identity resolution requires these database files; without them, the build will fail at RUN time or the runtime will reject the container. This is a common pitfall in scratch and multi-stage builds that inherit from scratch without copying the passwd/group databases from a builder stage. Numeric UIDs/GIDs (e.g., 65532, 1000:1000) work without any passwd database and are the recommended approach for minimal images. The rule suppresses after a SHELL instruction, since the user may have bootstrapped tools that handle identity resolution.

Examples

Bad

FROM scratch
COPY --from=builder /myapp /myapp
USER appuser
FROM scratch
COPY --chown=appuser:appgroup --from=builder /myapp /myapp

Good (numeric IDs)

FROM scratch
COPY --from=builder /myapp /myapp
USER 65532:65532
FROM scratch
COPY --chown=1000:1000 --from=builder /myapp /myapp

Good (passwd copied from builder)

FROM golang:1.22 AS builder
RUN useradd -r appuser

FROM scratch
COPY --from=builder /etc/passwd /etc/passwd
COPY --from=builder /etc/group /etc/group
COPY --from=builder /myapp /myapp
USER appuser

Good (non-scratch base image)

FROM alpine:3.19
RUN adduser -D appuser
USER appuser

Suggested fix

The rule suggests replacing named identities with the numeric UID/GID 65532 (the conventional non-root ID used by distroless and Chainguard images). This fix uses FixSuggestion safety because the numeric ID may not match the author’s intended user. Alternatively, copy /etc/passwd and /etc/group from a builder stage that has the desired user.

Configuration

[rules.tally.named-identity-in-passwdless-stage]
severity = "warning"  # Options: "off", "error", "warning", "info", "style"