Skip to content

security: clear open Dependabot alerts across all four projects - #2144

Merged
ntatsumi merged 1 commit into
devfrom
security/dependabot-2026-08-18
Aug 18, 2026
Merged

security: clear open Dependabot alerts across all four projects#2144
ntatsumi merged 1 commit into
devfrom
security/dependabot-2026-08-18

Conversation

@ntatsumi

Copy link
Copy Markdown
Contributor

Clears the open Dependabot alerts — 9 of 10 fixed, the tenth justified via VEX.

Fixed

Alert Package Change Where
1300 nanoid 3.3.16 → 3.3.18 ui/yarn.lock
1275 js-yaml 4.3.0 → 4.3.1 ui/yarn.lock
1259 fast-uri 3.1.4 → 3.1.5 ui/yarn.lock
1232 undici 7.28.0 → 7.29.0 ui/yarn.lock
1276 pdfjs-dist 6.1.200 → 6.2.108 ui/package.json resolutions
1264 cryptography 49.0.0 → 50.0.0 ml-engine
1237 cryptography 49.0.0 → 50.0.0 model-upload
1236 cryptography 49.0.0 → 50.0.0 observability SDK
1045 json-repair 0.52.5 → 0.63.2 observability SDK

Most were plain lockfile refreshes. Two needed more:

  • pdfjs-dist is pinned exactly at 6.1.200 by @arthur/shared-components, so no range bump reaches 6.2.108 — added a resolutions entry.
  • json-repair is capped <0.53.0 by beeai-framework (still true in its latest, 0.1.82), so a constraint cannot lift it — used override-dependencies. Safe to force: beeai's only call site is json_repair.loads(input, stream_stable=...) in backend/utils.py, it never passes schema= (the vulnerable resolver), and that signature is unchanged in 0.63.2.

Not fixable: alert 1263, cryptography in genai-engine

presidio-anonymizer 2.2.364 — the latest — requires cryptography>=48.0.1,<49.0.0, so 50.0.0 is unreachable here. CVE-2026-69247 is a Bleichenbacher oracle in PKCS#7 EnvelopedData decryption (pkcs7_decrypt_der / _pem / _smime). There is no pkcs7 reference anywhere under genai-engine/src and no endpoint decrypts attacker-supplied EnvelopedData, so the affected code never executes.

Recorded as a not_affected VEX statement for genai-engine-cpu/gpu per security/README.md (document version 7 → 8), with a review date and a note to drop it once presidio widens its pin. ml-engine and the models-* images are already on 50.0.0 and aren't listed.

Also: genai-engine's uv.lock could not be re-resolved at all

uv lock fails outright on dev, which blocks any security relock in genai-engine — that's how this surfaced.

Renovate PRs #2132 and #2134 edited pyproject.toml without relocking, leaving two contradictions:

  • openai==3.0.0, forbidden by litellm 1.96.2 (openai>=2.20.0,<3.0.0)
  • arthur-common==2.4.69, which itself pins litellm==1.96.0 against pyproject's 1.96.2

CI runs uv sync --frozen, which skips the lock/pyproject consistency check, so this went unnoticed.

Fix: openai back to 2.54.0 — the version the lock already had, so no release ever shipped v3 — plus arthur-common → 2.4.70 (requires litellm 1.96.2) and langchain-openai → 1.5.1 (allows openai<4). Left a comment on the openai pin so the next Renovate bump has context. uv lock --check now passes in all four projects.

Worth a follow-up: Renovate isn't relocking genai-engine, and --frozen hides the drift.

Testing

  • genai-engine: 1992 passed, 7 skipped
  • model-upload: 9 passed
  • observability SDK: ruff + black clean; beeai extra installs, imports, and parse_broken_json works against json-repair 0.63.2
  • ml-engine: cryptography 50.0.0 / pyOpenSSL 26.4.0 import cleanly

Not runnable locally, all pre-existing setup reasons: ml-engine and obs-sdk test suites need generated client modules (genai_client, arthur_genai_client), and the UI needs GITLAB_UNIFY_FRONTEND_TOKEN for @arthur/*. The UI lockfile resolves cleanly under --immutable (only the fetch step fails on auth).

Note

Please confirm the UI build in CI. pdfjs-dist 6.1 → 6.2 is a minor bump that overrides a dependency's exact pin, and it's the one change not exercised locally.

🤖 Generated with Claude Code

Fixes 9 of the 10 open alerts. Lockfile refreshes cover most of them; two
needed more than a range bump:

- pdfjs-dist (GHSA, alert 1276) is pinned exactly at 6.1.200 by
  @arthur/shared-components, so no range bump can reach 6.2.108 — added a
  `resolutions` entry.
- json-repair (GHSA-xf7x-x43h-rpqh, alert 1045) is capped <0.53.0 by
  beeai-framework, still true in its latest 0.1.82, so a constraint cannot
  lift it — used `override-dependencies`. beeai's only call site is
  `json_repair.loads(input, stream_stable=...)` in backend/utils.py; it never
  passes schema=, which is the vulnerable resolver, and that signature is
  unchanged in 0.63.2.

npm (genai-engine/ui): nanoid 3.3.16->3.3.18, js-yaml 4.3.0->4.3.1,
fast-uri 3.1.4->3.1.5, undici 7.28.0->7.29.0, pdfjs-dist 6.1.200->6.2.108.
pip: cryptography 49.0.0->50.0.0 in ml-engine, model-upload and the
observability SDK; json-repair 0.52.5->0.63.2 in the observability SDK.

Alert 1263 (cryptography in genai-engine) cannot be fixed: presidio-anonymizer
2.2.364, the latest, requires cryptography>=48.0.1,<49.0.0. CVE-2026-69247 is a
Bleichenbacher oracle in PKCS#7 EnvelopedData decryption and there is no pkcs7
reference anywhere under genai-engine/src, so the affected code never executes.
Recorded as a not_affected VEX statement per security/README.md, with a review
date and a note to drop it once presidio widens its pin.

Also repairs genai-engine's uv.lock, which could not be re-resolved at all on
dev and so blocked any security relock there. Renovate PRs #2132 and #2134
edited pyproject.toml without relocking, leaving openai==3.0.0 (forbidden by
litellm 1.96.2) and arthur-common==2.4.69 (which pins litellm 1.96.0) both
contradicting the lock; CI's `uv sync --frozen` skips the consistency check, so
it went unnoticed. openai returns to 2.54.0 — the version the lock already had,
so no release ever shipped v3 — with arthur-common 2.4.70 and langchain-openai
1.5.1. `uv lock --check` now passes in all four projects.

Tests: genai-engine 1992 passed / 7 skipped; model-upload 9 passed; obs-sdk
ruff + black clean with the beeai extra importing and running. ml-engine and
obs-sdk test suites and the UI build need generated clients and the GitLab
registry token, so CI covers those.

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

alwaysmeticulous Bot commented Aug 18, 2026

Copy link
Copy Markdown

✅ Meticulous spotted 0 visual differences across 365 screens tested: view results.

Meticulous evaluated ~9 hours of user flows against your PR.

Expected differences? Click here. Last updated for commit 22d519e security: clear open Dependabot alerts across all four projects. This comment will update as new commits are pushed.

@claude

claude Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

@github-actions

Copy link
Copy Markdown
Contributor

Coverage

Tests Skipped Failures Errors Time
1999 7 💤 0 ❌ 0 🔥 17m 57s ⏱️

@ntatsumi
ntatsumi merged commit 29af6c7 into dev Aug 18, 2026
33 checks passed
@ntatsumi
ntatsumi deleted the security/dependabot-2026-08-18 branch August 18, 2026 20:31
kc961163 added a commit that referenced this pull request Aug 18, 2026
Take dev's genai-engine/pyproject.toml and uv.lock. #2144 fixed the
unresolvable pin independently by holding openai at 2.54.0 and moving
arthur-common to 2.4.70, so the dependency change here is redundant.

This PR now carries only the CI guard.
ntatsumi added a commit that referenced this pull request Aug 18, 2026
Renovate updates pyproject.toml and regenerates uv.lock in a separate artifact
step. When that second step fails — typically because the new version violates a
transitive constraint of another pinned dependency — Renovate still opens the PR
with the manifest edit alone, and does not reliably flag it (#2134's body carried
no artifact warning at all). Nothing in CI could see that: every Python job
installs with `uv sync --frozen`, which replays the lockfile and never compares it
against the manifest. So the PR went green, merged, and left the two files
disagreeing.

Two of the last 25 Renovate commits did this. #2134 pinned openai==3.0.0, which
litellm 1.96.2 forbids, making `uv lock` impossible for everyone until PR #2144.
#2124 pinned python-keycloak==7.1.1 while the lock kept 5.12.0, so the upgrade
was absent from every image for weeks before an unrelated re-lock repaired it —
the more dangerous shape, because it is completely silent.

Renovate offers no setting that makes it fail closed here; that is upstream
behaviour. So detection has to live in CI, and configuration can only stop it
re-proposing updates already known to be impossible.

- New `check-dependency-automation` job runs `.github/scripts/check-lockfile-drift.sh`
  over every uv project found in the repo, discovered rather than listed so a new
  project is covered the day it is added. It reports STALE (manifest resolves, lock
  not regenerated) separately from UNRESOLVABLE (no lockfile can satisfy the
  manifest), because those need opposite fixes, and writes the decision tree to the
  job summary. It lives in arthur-engine-workflow.yml deliberately:
  renovate-autofix.yml listens for "Arthur Engine CI" failing, so a gate in a
  separate workflow would never reach the auto-fixer.

- The same job validates renovate.json when it changes. An invalid config does not
  fail loudly — Renovate just stops — and the new failure message actively tells
  people to go add allowedVersions rules there.

- version-workflow.yml now re-locks after bumping the three pyproject versions.
  Each uv.lock records its own project's version, so the bump left every lockfile
  disagreeing with its manifest on every release; that drift is harmless but
  indistinguishable from the real thing, and would have left the new gate
  permanently red. Verified that `uv lock` without --upgrade moves no dependency:
  the only edits are the project's own version and the exclude-newer soak boundary.

- renovate.json caps openai < 3.0.0, naming litellm as the ceiling and the
  condition for lifting it, matching the existing transformers and
  importlib-metadata rules. litellm joins the langchain + openai group so the
  family moves together instead of half at a time. A top-level description records
  why CI has to be the backstop.

- renovate-autofix.yml learns this failure class: how to tell STALE from
  UNRESOLVABLE, and that a transitive ceiling with no upstream fix is a hand-off,
  since invariant 6 forbids it editing renovate.json. It should name the cap a
  human needs to add.

Verified by reintroducing both regressions against the finished gate: openai==3.0.0
reports UNRESOLVABLE with the litellm conflict, a stale pin reports STALE and names
the package that did not move, both exit 1, and the working tree is left clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant