Skip to content

fix(prd-262): clear the 4 blocking scan findings — litellm KEVs in agent-opt-worker, Go stdlib in media-render's esbuild - #1242

Merged
AutomatosAI merged 2 commits into
mainfrom
fix/prd-262-scan-findings
Oct 20, 2026
Merged

AutomatosAI merged 2 commits into
mainfrom
fix/prd-262-scan-findings

Conversation

@AutomatosAI

Copy link
Copy Markdown
Owner

What and why

PRD-262 §8 row 16, "fixable Critical / unallowlisted KEV in images we build: 0 / 0", fails on main. images.yml run 39399292631 shows 2 blocking findings in each of two images. The policy runs in report mode, as Gerard decided on 20 Oct (US-004), so nothing failed a build. This PR clears all four.

1. agent-opt-worker: litellm 1.80.0 → 1.91.5 (485ded7)

  • The advisories: GHSA-7488-6r32-c95q (High, KEV, fixed in 1.84.0) and GHSA-v4p8-mg3p-g94g (High, KEV, fixed in 1.83.7). Both are in the proxy's MCP endpoints.
  • Why 1.80.0 was held: ai-evaluation 1.1.0, the newest on PyPI, caps openai<2, and every litellm from 1.84 on needs openai>=2.20.0,<3. overrides.txt now lifts the cap. The SDK's upstream repo main already declares openai>=1.109.1,<3.
  • The version: 1.91.5 is the newest pure-Python wheel and adds no package. 1.92 adds a Rust extension; 1.96 and 1.98 add pydantic-settings, boto3 and botocore.
  • The lock: only three pins move: litellm 1.80.0 → 1.91.5, openai 1.109.1 → 2.54.0, importlib-metadata 9.0.1 → 8.9.0.
  • Allowlist: the three litellm 1.80.0 Critical entries leave .grype.yaml, since nothing matches them now.
  • Compatibility: openai 2.0's only breaking change is the Responses API tool-call output type, which neither SDK uses. litellm 1.84–1.95's breaking changes are all in the proxy, which the worker doesn't use. In a locally built image, the service's suite passes (44) along with the import smoke, and a probe of LiteLLMGenerator.generate, litellm.completion and all four optimizers passes. pip check shows the one expected mismatch: ai-evaluation's openai<2.
  • Size: about +11 MB compressed (local estimate). The image is now over its 150 MB budget, which main already exceeds by 0.2 MB. The budget only warns and is not raised here; it's worth revisiting once CI reports the real size.

2. media-render: esbuild 0.25.12 built from source on Go 1.26.10 (2094326)

  • The advisories: GO-2026-4337 (crypto/tls, Critical) and GO-2026-6612 (net/http, Critical) are in npm's esbuild 0.25.12 binaries, which are built with go1.23.12.
  • Why no bump fixes it: Hyperframes requires esbuild ^0.25.12, including its newest release 0.8.181. The newest esbuild (0.28.2) and esbuild main both build with Go 1.26.5. GO-2026-6612 is fixed in Go 1.26.9 / 1.27.2. esbuild can't be pruned, because the render path calls transformSync.
  • The fix: a new esbuild stage on golang:1.26.10-trixie@sha256:9ba7dc6d… runs go install …/cmd/esbuild@v0.25.12 with esbuild's release flags. The js stage copies the binary over npm's platform binary and hard-links esbuild/bin/esbuild to it, and the build fails unless require("esbuild").transformSync runs. The Go toolchain never reaches the runtime. The node-stripped stage and js/prune.txt are unchanged.
  • Tests:
    • test_prd262_media_render_esbuild.py: Go ≥ 1.26.9, the built version matching package-lock, the flags and the order of the swap.
    • The in-image tests/test_image_esbuild.py: every esbuild binary's Go build info is ≥ 1.26.9, the two paths are one inode, and the JS API runs. It fails on main's image.
  • Local amd64 build: the in-image suite passes 355, including real renders and snapshots. The module trace gives "PASS 12 pruned paths, none loaded". On disk it's 1,296.96 MB against the 1,300 MB bar: +1.25 MB, the Go 1.26 binary.

Local scan: Grype v0.118.0 (the 2026-10-20 database) plus image_scan_policy.py check --mode fail gives agent-opt-worker 0 blocking and media-render 0 blocking.

Test plan

  • Static: 372 passed across 22 PRD-262 and media-render files. Ruff and the shape check are clean.
  • Local images: agent-opt-worker's suite passes (44) and media-render's in-image suite passes (355). The scan shows 0 blocking for both.
  • images.yml on this PR: "agent-opt-worker (amd64): … 0 blocking" and "media-render (amd64/arm64): … 0 blocking". arm64 media takes the @esbuild/linux-arm64 path and wasn't built locally.
  • test.yml's agent-opt-worker lane: the lock check, the build, the import smoke, the in-image pytest and the 401 checks.
  • media-render.yml dispatched on this branch: the build, the in-image suite with test_image_esbuild, the module trace, the renders, the ≤ 1,300 MB bar and the template shards.

…(1.80.0 -> 1.91.5)

images.yml run 39399292631 on main (330439e) scanned agent-opt-worker
(amd64) with 2 blocking rows, both KEV-listed, in
/usr/local/lib/python3.11/site-packages/litellm-1.80.0.dist-info:
- GHSA-7488-6r32-c95q (CVE-2026-59822, High, KEV): MCP auth bypass via the
  OAuth2 passthrough fallback; fixed in 1.84.0.
- GHSA-v4p8-mg3p-g94g (CVE-2026-42271, High, KEV): command execution through
  the MCP stdio test endpoints; fixed in 1.83.7.

litellm 1.84 and later require openai>=2.20.0,<3, and ai-evaluation 1.1.0
(the newest on PyPI) still caps openai<2, which is why the lock held 1.80.0.
overrides.txt now lifts that cap (openai>=2.20.0,<3). openai 2.0.0's only
breaking change is the type of a Responses API tool-call output; ai-evaluation
and agent-opt call chat completions, embeddings and moderations, and the SDKs'
source repository (now agent-learning-kit) allows openai<3 on main.

litellm 1.91.5 is the newest release that still ships a pure-Python wheel
(1.92 adds a Rust extension; 1.95.1's manylinux wheel is 26.3 MB against 16.7)
and adds no package to the lock (1.96 adds pydantic-settings, 1.98 boto3). It
is past every fixed litellm GHSA, GHSA-3cv6-jpf6-8222 included. The breaking
changes listed for 1.84-1.95 are all in the proxy (tags, /key/list, admin
permissions, budgets, /v1/messages timeouts); the worker only reaches
litellm.completion through agent-opt's LiteLLMGenerator.

Lock changes (uv pip compile, the command in requirements.in): litellm
1.80.0 -> 1.91.5, openai 1.109.1 -> 2.54.0, importlib-metadata 9.0.1 -> 8.9.0
(litellm caps <9). Nothing added or removed.

With litellm fixed, the three Critical allowlist entries for litellm 1.80.0
(GHSA-6wvf-77m9-58rm, GHSA-4xpc-pv4p-pm3w, GHSA-jjhc-v7c2-5hh6) no longer
match anything and come out of .grype.yaml; the static test that pinned them
now asserts litellm >= 1.84.0 with no litellm entry, and the openai override.

Signed-off-by: Gerard Kavanagh <gerard161@gmail.com>
….26.10

images.yml run 39399292631 on main (330439e) scanned media-render (amd64 and
arm64) with 2 blocking rows each, fixable Criticals in the Go standard library
go1.23.12 of esbuild's binary, at
/opt/media-render/js/node_modules/esbuild/bin/esbuild and
/opt/media-render/js/node_modules/@esbuild/linux-{x64,arm64}/bin/esbuild:
- GO-2026-4337 (CVE-2025-68121, crypto/tls session resumption): fixed in Go
  1.24.13, 1.25.7 and 1.26.0;
- GO-2026-6612 (CVE-2026-78663, net/http HTTP/2 flow control): fixed in Go
  1.26.9 (and 1.27.2).

esbuild comes from Hyperframes (esbuild ^0.25.12, also in hyperframes 0.8.181,
the newest), and npm's 0.25.12 binary is built with Go 1.23.12 (esbuild's
go.version at v0.25.12). No esbuild release is built with Go 1.26.9 or later:
0.28.2, the newest, ships Go 1.26.5, and esbuild main is still on 1.26.5. So a
new esbuild stage builds the locked 0.25.12 from source on golang:1.26.10-trixie
(pinned by digest) with esbuild's release flags (CGO_ENABLED=0, -trimpath,
-ldflags '-s -w -buildid=', -buildvcs=false); go install checks the modules
against the Go checksum database. The js stage copies it over npm's platform
binary, hard-links esbuild/bin/esbuild to it as esbuild's install script does,
and fails the build unless esbuild's JavaScript API runs it (it refuses a
binary whose version is not the package's). The Go toolchain never reaches the
runtime; the node-stripped stage and js/prune.txt are unchanged.

Tests: test_prd262_media_render_esbuild.py pins the Go image (>= 1.26.9), the
built version against js/package-lock.json, the flags and the swap order;
test_prd262_media_render_stages.py lists the new stage; the in-image
test_image_esbuild.py reads each esbuild binary's Go build info (>= 1.26.9),
checks the two paths are one hard-linked file and runs the JavaScript API.

Local amd64 build (Docker Desktop, emulated): both paths are one inode,
go1.26.10, 0.25.12; the in-image suite 355 passed; the module-traced render
and snapshot pass the prune check; Grype 0.118.0 (DB 2026-10-20) plus
scripts/ci/image_scan_policy.py in fail mode: 0 blocking. On disk
1,296,962,463 bytes against the 1,300 MB bar (main's media-render.yml run
39356406759: 1,295,709,649); the Go 1.26 binary is 11,382,910 bytes, npm's
10,358,936.

Signed-off-by: Gerard Kavanagh <gerard161@gmail.com>

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Code review skipped — your organization has no extra usage available to pay for this review.

If your organization's extra usage balance is empty, an organization admin can add extra usage credits at claude.ai/admin-settings/usage. If its monthly spend limit was reached, an admin can raise it on the same page. If neither applies, contact Anthropic support.

Once extra usage is available, someone with write access to this repository can comment @claude review on this pull request to trigger a review.

@coderabbitai

coderabbitai Bot commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 53 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: e5a89b3d-03c8-47a5-9f93-4c34dc28e1d4
📥 Commits

Reviewing files that changed from the base of the PR and between bcc3f79 and 2094326.

⛔ Files ignored due to path filters: 1
  • services/agent-opt-worker/requirements.lock is excluded by !**/*.lock
📒 Files selected for processing: 8
  • .grype.yaml
  • orchestrator/tests/test_prd262_agent_opt_worker_image.py
  • orchestrator/tests/test_prd262_media_render_esbuild.py
  • orchestrator/tests/test_prd262_media_render_stages.py
  • services/agent-opt-worker/overrides.txt
  • services/agent-opt-worker/requirements.in
  • services/media-render/Dockerfile
  • services/media-render/tests/test_image_esbuild.py
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@AutomatosAI

Copy link
Copy Markdown
Owner Author

CI evidence for this PR's head:

  • images.yml: agent-opt-worker (amd64): 176 matches, 0 blocking, media-render (amd64): 725 matches, 0 blocking, media-render (arm64): 725 matches, 0 blocking. PRD-262 §8 row 16 is now 0 / 0 for every image we build.
  • media-render.yml, dispatched on this branch (run 39408716156): all 5 jobs green (the fixture render and 4 template shards). The in-image suite passes 355, including all 3 test_image_esbuild.py tests (every esbuild binary is built with a patched Go; one binary where npm put it; the JS API runs at the locked version). On disk it's 1296 MB, within its 1300 MB bar: PASS.
  • test, images and CodeQL: green.
  • smoke-images (non-required): red on the known core-stack step (PermissionError … /workspaces/<c1>/repos), the same as on perf(prd-262): API — W2–W5, pull-first self-host, boot, and the 19 Oct cuts (1,920 → 789 MB) #1226 and perf(prd-262): worker cuts — 1,074 → 910 MB, toolchain kept #1220. That's P256-FIX-WRK-1, not this change.

@AutomatosAI
AutomatosAI merged commit 275e701 into main Oct 20, 2026
59 of 60 checks passed
@AutomatosAI
AutomatosAI deleted the fix/prd-262-scan-findings branch October 20, 2026 10:51
AutomatosAI pushed a commit that referenced this pull request Oct 20, 2026
Clean merge. main adds #1242 (media-render's esbuild built on Go 1.26.10, litellm 1.91.5 in agent-opt-worker), PRD-263 PR-3A..3E-a and PRD-264 work since ebedc7e.

Signed-off-by: Gerard Kavanagh <gerard161@gmail.com>
AutomatosAI pushed a commit that referenced this pull request Oct 20, 2026
…) into the nights 16–17 + socials fix wave — no conflicts; no new undefined names

Signed-off-by: Gerard Kavanagh <gerard161@gmail.com>
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.

2 participants