Skip to content

fix(hardening-ratchet): a Dockerfile with no FROM is a finding, not a pass - #2606

Merged
POWERFULMOVES merged 1 commit into
mainfrom
fix/hardening-ratchet-requires-from
Aug 18, 2026
Merged

POWERFULMOVES merged 1 commit into
mainfrom
fix/hardening-ratchet-requires-from

Conversation

@POWERFULMOVES

Copy link
Copy Markdown
Owner

Follow-up to #2604, closing the gap that let it happen silently.

The gap

#2285's hardening pass truncated 9 tracked Dockerfiles down to their USER tails — no FROM, so docker build fails with "no build stage in current context" and make overlay-up-agents died on notebooklm-agent. main could not build those images.

hardening-validation stayed green through all of it. That is my gate, and this is the same failure shape it was written to fix.

#2592 replaced a grep 'USER' that scored USER root as compliant, with a rule that judges the last USER directive. But a file whose only line is USER pmoves also passes that rule — the last USER is non-root, so the gate reports compliant about a file that cannot build. It was asserting a property nobody had asked about.

The change

  • NO_FROM is checked first and short-circuits, so a fragment is reported as a fragment rather than scored on a USER directive with no image to apply to.
  • It is deliberately not baselineable. The output says "Restore the file content. Do NOT baseline it." — a truncated Dockerfile is damage, not a recorded exception.
  • Summary line renamed from Root-running: N to Findings: N. NO_FROM is not a root-privilege problem, and a gate that mislabels what it counted is how it ends up trusted for something it never checked.

Verification — both directions

main after #2604              exit 0   Findings: 12 (12 baselined, 0 new)
owner-presence re-truncated   exit 1   NO_FROM  pmoves/services/owner-presence/Dockerfile

Run against main before #2604, it flags exactly the 9 files that PR restored — 9 for 9, which independently confirms #2604's list was complete.

No baseline change: _known_gaps.yaml stays at 12.

… pass

#2604 found 9 tracked Dockerfiles that #2285 truncated down to their USER
tails -- no FROM, so `docker build` fails with "no build stage in current
context" and `make overlay-up-agents` died on notebooklm-agent. This gate
stayed GREEN through all of it.

That is my gap, and it is the same shape as the one this tool was written to
close. #2592 replaced a `grep 'USER'` that scored `USER root` as compliant,
with a rule that judges the LAST USER directive. But a file whose only line is
`USER pmoves` also passes that rule: the last USER is non-root, so the gate
says compliant about a file that cannot build. It asserted a property nobody
had asked about.

NO_FROM is now checked FIRST and short-circuits, so a fragment is reported as
what it is instead of being scored on a USER directive with no image to apply
to. It is explicitly not baselineable -- the output says "Restore the file
content. Do NOT baseline it." A truncated Dockerfile is damage, not a
deliberate exception.

Also renamed the summary line from "Root-running: N" to "Findings: N". NO_FROM
is not a root-privilege problem, and a gate that mislabels what it counted is
how it ends up trusted for something it never checked.

Verified both directions:
  main after #2604            -> exit 0, "Findings: 12 (12 baselined, 0 new)"
  owner-presence re-truncated -> exit 1, "NO_FROM  pmoves/services/owner-presence/Dockerfile"
  and, run against main BEFORE #2604, it flags exactly the 9 files #2604
  restored -- 9 for 9, independently confirming that list was complete.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 561c4897-064d-4509-8dc7-0dc653eca6a0


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@POWERFULMOVES
POWERFULMOVES merged commit 476fa7d into main Aug 18, 2026
24 checks passed
@POWERFULMOVES
POWERFULMOVES deleted the fix/hardening-ratchet-requires-from branch August 18, 2026 21:20
POWERFULMOVES pushed a commit that referenced this pull request Aug 19, 2026
…ages

Two follow-ups to #2604's restores, found bringing the agents overlay up
on SPARK:

- notebooklm-agent (node:20-alpine): Alpine has no useradd; the
  `|| true` fallback silently skipped creation and left `USER pmoves`
  dangling — the daemon refused to start ("unable to find user pmoves").
  Switched to `adduser -D -s /bin/sh` with no silent fallback; verified
  the rebuilt image carries pmoves (uid 1001) and runs non-root.
- agentgym-rl-coordinator (distroless final stage): no shell, no
  useradd, RUN cannot execute at all. Use the stage's built-in `nonroot`
  user, which the pre-existing HF_HOME=/home/nonroot was designed
  around.

Hardening ratchet (with #2606's NO_FROM check): 12/12 baselined, 0 new.

Generated with Crush
POWERFULMOVES added a commit that referenced this pull request Aug 19, 2026
…ages (#2609)

Two follow-ups to #2604's restores, found bringing the agents overlay up
on SPARK:

- notebooklm-agent (node:20-alpine): Alpine has no useradd; the
  `|| true` fallback silently skipped creation and left `USER pmoves`
  dangling — the daemon refused to start ("unable to find user pmoves").
  Switched to `adduser -D -s /bin/sh` with no silent fallback; verified
  the rebuilt image carries pmoves (uid 1001) and runs non-root.
- agentgym-rl-coordinator (distroless final stage): no shell, no
  useradd, RUN cannot execute at all. Use the stage's built-in `nonroot`
  user, which the pre-existing HF_HOME=/home/nonroot was designed
  around.

Hardening ratchet (with #2606's NO_FROM check): 12/12 baselined, 0 new.

Generated with Crush

Co-authored-by: Agent Zero <agent.zero@pmoves.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant