| Property | Value |
|---|---|
| Severity | Warning |
| Category | Correctness |
| Default | Enabled |
| Auto-fix | Yes (two alternatives) |
Description
Docker’sCOPY and ADD instructions always create files owned by root:root
(UID 0, GID 0), regardless of the active USER instruction. This is a common
source of confusion: authors set USER nonroot and then expect subsequent
COPY/ADD to create files owned by that user.
This rule detects COPY or ADD instructions that follow a non-root USER
without an explicit --chown flag. The mismatch means the non-root process may
not be able to write to or modify the copied files at runtime.
Suppression
The rule is automatically suppressed when:- The
COPY/ADDinstruction already has--chownset. - The effective
USERat that point in the stage is root (or noUSERhas been set). - A subsequent
RUN chowncommand in the same stage targets the same destination path (or a parent directory), indicating the author is managing ownership explicitly.
Cross-stage inheritance
The rule walks theFROM <stage> ancestry chain. If a parent stage sets a
non-root USER that flows into a child stage via FROM, COPY/ADD in the
child stage without --chown will trigger the rule.
Relationship to other rules
tally/copy-after-user-without-chown | tally/prefer-copy-chmod | |
|---|---|---|
| Fires when | COPY/ADD after non-root USER without —chown | COPY followed by RUN chmod |
| Fix | Adds --chown=<user> or moves USER | Merges into COPY --chmod |
| Scope | All stages | All stages |
COPY instruction. Their fixes compose
correctly: the result is COPY --chown=user --chmod=mode file /dest.
Windows stages
On Windows containers--chown is silently ignored (see
tally/windows/no-chown-flag), so the “add
--chown” fix is suppressed. The rule still fires — the ownership confusion is
real — but only the “move USER” rearrangement fix is offered.
Auto-fix
Two fix alternatives are offered:-
Add
--chown=<user>(preferred, safe): inserts--chown=<user>to match the activeUSER, fixing the ownership mismatch directly. -
Move
USERafter COPY/ADD (safe): relocates theUSERinstruction to just before the firstRUNorWORKDIRthat follows. This is a semantic no-op becauseCOPY/ADDownership is alwaysroot:rootregardless ofUSER. It clarifies thatUSERonly affectsRUN,WORKDIR, and runtime identity. This alternative is only offered when noRUNorWORKDIRexists between theUSERand theCOPY/ADD.
References
- Dockerfile reference — USER
- Dockerfile reference — COPY —chown
- Dockerfile reference — ADD —chown
- Docker Blog — Understanding the Docker USER Instruction