fix(opencode): harden runtime image - #2
seonghobae wants to merge 13 commits into
Conversation
Add apk's native no-cache option, retain a package-install policy regression, and record exact Trivy RCA plus the remaining runtime-image gaps.
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
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. Comment |
|
This PR doesn't fully meet our contributing guidelines and PR template. What needs to be fixed:
Please edit this PR description to address the above within 2 hours, or it will be automatically closed. If you believe this was flagged incorrectly, please let a maintainer know. |
|
Thanks for your contribution! This PR doesn't have a linked issue. All PRs must reference an existing issue. Please:
See CONTRIBUTING.md for details. |
seonghobae
left a comment
There was a problem hiding this comment.
Exact-head COMMENT review for 5e7399d2d4d7c532f850d9677e0c954f2adc1421 (tree 423a559790e991c635094c696c1e30872e3afaf0) against protected dev@b3f1a96c6dd7adeb28b36dd11add1998fc84d67b.
RCA is anchored to OpenCode PR #1 Security Scan run 36358142730, job 109060466385, which reported Trivy DS-0025 at the canonical packages/opencode/Dockerfile:7. The RED predicate fails on the protected source because its real RUN apk add lacks --no-cache; the minimal production change uses apk's native option, and the durable package test rejects any future cache-retaining RUN apk add instruction.
This review found no additional blocker inside the claimed five-file boundary. It is COMMENT evidence, not approval. The remaining Trivy findings are explicitly preserved as Open Gap, and the absence of Bun/container/Trivy locally means fresh exact-head hosted Checks remain mandatory; no full-suite or scanner GREEN is claimed.
|
Hosted exact-head Security Scan evidence for
Draft / Proposed / merge HOLD remains correct until all required exact-head Checks and qualifying independent review are complete. |
|
Exact-head hosted RCA for
No merge, bypass, suppression, force update, or destructive rebase. |
Parse logical Docker RUN instructions, isolate apk add shell commands, and reject unrelated no-cache flags so the regression cannot pass vacuously.
seonghobae
left a comment
There was a problem hiding this comment.
Exact-head follow-up review: the prior regression could miss compound, indented, and line-continued apk installs, and its whole-instruction oracle could accept an unrelated neighboring --no-cache. Commit 2a162da0687855475cd745b1a2ac1010e7670861 adds the reproduced 1/3 RED fixture, parses logical RUN instructions into shell-command segments, reaches 3/3 GREEN, and adds a non-vacuous neighboring-flag case. This is a COMMENT, not an approval; fresh hosted Checks and qualifying independent approval remain required.
|
Exact-head evidence update for |
Handle Docker instruction case, single background operators, and unquoted shell comments while preserving quoted hash literals in the package policy regression.
seonghobae
left a comment
There was a problem hiding this comment.
Exact-head follow-up review after the second independent adversarial pass. RED on 2a162da… reproduced three remaining oracle bypasses: single & borrowed a neighboring flag, an unquoted shell comment supplied a false flag, and lowercase Docker run was missed. Commit 4b1d3c6a89a317e36a126c1435e4d40cd367dadc detects and rejects those unsafe fixtures, preserves quoted #literal, retains the earlier direct/compound/continued cases, and detects the real install with --no-cache. This is COMMENT evidence, not approval; fresh exact-head hosted Checks remain mandatory.
|
Fresh exact-head scanner evidence for |
Recognize apk only at command position, reject no-cache redirect targets, and ignore quoted prose so the policy oracle reflects package-manager arguments.
seonghobae
left a comment
There was a problem hiding this comment.
Exact-head follow-up after the third independent adversarial pass. RED on 4b1d3c6… proved that RUN apk add curl > --no-cache borrowed a redirect filename and that RUN echo "apk add curl" was falsely classified. Commit 0e4a032df8c2d64a00a342166a76847dee7b7195 anchors detection at executable command position and accepts the option only before unquoted redirection; it preserves quoted #/> data and all earlier bypass fixtures. This is COMMENT evidence, not approval; fresh exact-head hosted Checks remain mandatory.
|
Fresh scanner evidence for final exact head |
Replace the unsound shell parser with one narrow invariant: every literal apk add in a logical RUN instruction must immediately use unquoted --no-cache. Ambiguous shell forms fail safe.
seonghobae
left a comment
There was a problem hiding this comment.
Exact-head simplification review: repeated adversarial review showed that a bespoke partial shell parser could not support its broad claims. Commit 36cac84ef0379af04484bd8970fe8c3b099aefa6 deletes that parser and enforces one conservative textual invariant over logical Docker RUN instructions: every literal apk add must immediately use unquoted --no-cache. Leading redirections are now detected; ambiguous quoted/comment/redirection forms fail safe and are documented as such. This is COMMENT evidence, not approval; fresh exact-head hosted Checks remain mandatory.
|
Fresh final-head scanner evidence for |
Keep an open logical Docker RUN buffered across blank and comment lines so a later literal apk add cannot escape the conservative no-cache policy.
seonghobae
left a comment
There was a problem hiding this comment.
Exact-head final bounded repair: RED on 36cac84… showed that an open continued RUN was incorrectly closed by an intervening Docker comment/blank line, allowing a later unsafe literal apk add to escape while the production install kept the oracle non-empty. Commit 1cefc5cfd5fd714fbca54c49ef38b7feb8e941fb keeps the buffer open across those lines and the exact fixture is now detected. Contract wording is narrowed to literal whitespace-separated occurrences; nonliteral shell expansions remain outside this regression and under hosted Trivy. COMMENT only; fresh exact-head Checks remain mandatory.
Reject non-default escape directives and RUN heredocs so unsupported logical-instruction syntax cannot bypass the narrow literal apk policy.
seonghobae
left a comment
There was a problem hiding this comment.
Exact-head final Docker-form repair: RED on 1cefc5c… proved that RUN heredocs and a non-default # escape= directive could hide literal unsafe installs from the default-backslash parser. Commit 7ca2330a5f7aa6013caf8dc92ad2c4ac68ec7baa emits explicit noncompliant policy subjects for both unsupported forms and narrows the documented supported syntax accordingly. The current Dockerfile still satisfies the literal immediate-unquoted-option invariant. COMMENT only; fresh exact-head hosted Checks remain mandatory.
Treat any heredoc operator in a RUN as unsupported so quoted and unquoted delimiter variants all fail closed.
seonghobae
left a comment
There was a problem hiding this comment.
Exact-head quoted-heredoc repair: predecessor 7ca2330… matched only unquoted word delimiters. Commit 51202d464677f4280cf8a853d9f6e5a070540951 conservatively rejects any << or <<- operator in a RUN, so unquoted, single-quoted, double-quoted, and tab-stripping heredoc variants all emit a failing policy subject. This remains COMMENT evidence, not approval; fresh exact-head hosted Checks are required.
|
Final exact-head evidence for |
Reject unescaped line continuations instead of partially emulating BuildKit, preserve escaped trailing backslashes, and ignore heredoc-like quoted data and late directive comments.
seonghobae
left a comment
There was a problem hiding this comment.
Exact-head follow-up review for 9846ad71911497fd7bd5f046379bfb8a07faca53. Independent review reproduced four predecessor fail-open paths caused by partial BuildKit continuation emulation (ap\\\nk add, a split heredoc operator, an EOF continuation, and an escaped trailing backslash swallowing the next instruction) plus two false positives (quoted << data and a late directive-shaped comment). The repair deletes continuation joining, fails closed on odd/unescaped trailing backslashes, preserves escaped pairs, scans each following instruction independently, recognizes heredoc operators only outside quotes, and limits escape-directive handling to the pre-instruction area. The predecessor predicate is RED on the added fixtures; Node 24.19.0 syntax validation and a Bun-compatible six-test mirror are GREEN. This is COMMENT evidence, not approval; fresh exact-head hosted Checks remain mandatory.
Repair exact-head identifier errors, replace the vacuous newline fixture, reject quoted/commented apk literals, and distinguish late directives and arithmetic shifts from unsupported forms.
seonghobae
left a comment
There was a problem hiding this comment.
Exact-head RCA follow-up: independent review proved predecessor 9846ad71911497fd7bd5f046379bfb8a07faca53 had two remote-only identifier errors plus four oracle defects (vacuous literal \\n, compliant-looking quoted/commented literals, parser-directive preamble overreach, and arithmetic-shift/heredoc confusion). Successor f7ffe1e4a3f2c677f55e7b38709c1952428aedb5 repairs the published source and adds executable fixtures for every miss. Node 24 Bun-compatible execution mirror: 9/9 PASS, including the production Dockerfile assertion. Hosted exact-head Checks and qualifying independent approval remain mandatory; PR stays Draft.
|
Hosted exact-head evidence for |
Remove the speculative Docker/shell parser and assert the exact runtime package-install instruction. Trivy remains the whole-tree semantic verifier.
seonghobae
left a comment
There was a problem hiding this comment.
Exact-head repair: fresh review of f7ffe1e4a3f2c677f55e7b38709c1952428aedb5 proved the generic shell oracle remained bypassable by literal quote concatenation and vacuous control-operator comments. 681b65a3c0d9a3af5569bd68caa46ed732e41050 removes that speculative parser and pins the canonical physical RUN apk add --no-cache libgcc libstdc++ ripgrep instruction. Protected-base fixture is RED; Node 24 Bun-compatible production assertion is 1/1 PASS. Hosted exact-head Checks and qualifying independent approval remain mandatory; Draft/merge HOLD is preserved.
|
Current exact-head evidence for |
seonghobae
left a comment
There was a problem hiding this comment.
Fresh bounded exact-head review found no concrete defect in 681b65a3c0d9a3af5569bd68caa46ed732e41050. Remote/local blobs match; the predecessor parser was deleted (180 lines removed) and the remaining 11-line production assertion is non-vacuous within its documented scope. Protected-base, empty, missing, duplicate, and directly unsafe canonical lines fail exact array equality; the current canonical line passes. Test path resolution, RCA/CHANGELOG scope, and Trivy ownership are consistent. This is a COMMENT review, not qualifying APPROVED authority; hosted product Checks and independent approval remain required.
|
Exact-head SAST follow-up for |
|
Exact-head security RCA for
These are owner-repository baseline defects, not a reason to weaken scanners or add broad suppressions in this APK-cache leaf. Keep this PR Draft/HOLD and repair the canonical dependency/container/process boundaries through RED→GREEN owner changes, then non-force integrate/retest this leaf. No rerun, merge, bypass, or close was attempted. |
Pin the Alpine multi-architecture manifest, select the requested runtime binary without a dynamic FROM, and drop privileges to a fixed OpenCode identity with an explicit home. Retain RED/GREEN evidence and the remaining shared-container and dependency gaps.
|
Exact-head source-repair receipt for
The hosted gates correctly remain RED on inherited findings outside this runtime-image delta: two vulnerable lockfiles, six other container Dockerfiles without non-root users, and the existing Semgrep corpus. No suppression or gate weakening was introduced. PR remains Draft/Proposed; queued product Checks and qualifying independent approval are still required. |
Count Docker FROM instructions case-insensitively and pin the exact user/group/home creation boundary. Retain lowercase final-stage and missing-home mutations as executable negative cases.
|
Independent review of RCA/RED:
Successor |
|
Exact-head hosted evidence for
The PR remains Draft/Proposed. These bounded source repairs do not convert inherited repository-wide red gates into GREEN and do not constitute approval or merge authority. |
Issue for this PR
Blocked: repository Issues are disabled. The create-issue API returned HTTP 410 on 2026-09-30 UTC, so a canonical local issue cannot currently be linked. The scanner evidence originates in PR #1. Keep this PR Draft until repository settings and the issue-first policy are reconciled.
Type of change
What does this PR do?
This PR repairs three verified defects at the canonical OpenCode runtime-image boundary:
DS-0025:apk addretained the downloaded repository index.DS-0001: the image used untaggedalpineand a dynamicFROM build-${TARGETARCH}.DS-0002plus the independent Semgrep missing-user rule: the final entrypoint ran as root.The repair uses apk's native
--no-cache, pinsalpine:3.24.2to multi-architecture manifestsha256:294b683cb724975bec92580e1e685676bd4b50bda910ddb8c51d4cabeaec77e6, selects theamd64orarm64binary through an ephemeral BuildKit mount, and runs the entrypoint as fixed UID/GID 10001 withHOME=/home/opencode. No scanner suppression, allowlist, or gate weakening is included.Root cause and decision
The runtime Dockerfile, not the organization workflow, owned these findings. A tag-only base was rejected because resolved bytes could change. Duplicated final stages were rejected because they would create two release configurations. Copying both binaries into the final filesystem and deleting one was rejected because the unused binary would remain in an image layer. The selected design preserves the existing BuildKit
TARGETARCHcontract and fails closed for unsupported architectures.The executable regression deliberately pins the canonical physical runtime instructions rather than partially emulating Docker or POSIX shell parsing. Trivy remains the independent semantic scanner.
Verification
dev@b3f1a96c6dd7adeb28b36dd11add1998fc84d67breproducedDS-0025.681b65a3c0d9a3af5569bd68caa46ed732e41050removedDS-0025, then Security Scan run36771095591, job110077455374, exposed the same Dockerfile'sDS-0001/DS-0002; SAST run36771095492, job110077389186, independently exposed the missing final user.681b65a…: unpinned base, dynamic finalFROM, and no finalUSER.amd64andarm64manifests.b75ca1ed3dd46dcbfbf663a354b4624e60e7af59has hosted Trivy and Semgrep proof for the production repair. Fresh hosted build, Security Scan, SAST, and qualifying independent approval are required for successor exact head9d05f4f11fbd48cd909e5355591a66563010ff12. No container runtime was available locally, so no local image-build success is claimed.Remaining verified gaps
The full exact-head scans still report inherited dependency findings in
github/bun.lockandartifacts/glm52-rise-video/bun.lock, plus missing non-root users in other independently deployed container Dockerfiles. Those findings remain Open indocs/product-technical-gap-baseline.md; this PR does not suppress or claim them.Screenshots / recordings
Not applicable; this is a runtime-image supply-chain repair with no UI change.
Checklist
Status
Proposed / Draft. Linked-issue policy, fresh exact-head Checks, and a qualifying independent approval remain mandatory before Ready or merge.