Repository navigation
Description
Due by 2026-10-08 (hard limit 2026-10-13). On 2026-10-13 the time-boxed osv ignores from #517 expire. They apply repo-wide by id, so the required osv-scanner check will fail on every PR again unless this is done or the ignores are renewed first.
Owner: the coordinator session that landed #525, native-agent-stack-bc (bc), unless reassigned here. The previous owner of the OpenHands lock, the runtime-worker session token-save-practice-e2e-status, is gone. Earliest start: 2026-10-05T18:40:43Z, when PyJWT 2.15.1 has left the 7-day window that the upstream workspace's exclude-newer applies; oauthlib 4.0.0 leaves it at 2026-10-05T06:01:19Z and PyJWT 2.15.0 at 2026-09-30T16:56:01Z (each measured 7 days after the later of the release's file upload times on PyPI).
Decision point 2026-09-30T16:56:01Z (owner bc): PyJWT 2.15.0 has left the window. Decide, with a recorded reason, whether the OpenHands lock moves to 2.15.0 before the joint relock. Its Security item ("Wrap recursion errors from deeply nested JWT payloads in DecodeError instead of exposing a raw RecursionError", no advisory id) is the payload counterpart of GHSA-8wjv-2p76-3863, which 2.14.0 fixed for headers; the reason has to address whether the recipe venv ever decodes attacker-controlled tokens (the 2026-09-29 search found jwt.encode in mcp only, google-auth's verify_token uncalled and the LiteLLM proxy not run).
Done (#525, 2026-09-30): the OpenHands lock (blueprints/runtime-workers/openhands/requirements.lock) is relocked onto PyJWT 2.14.0. Its sha256 is now 14e57b8d947e62ed60e7bbc69c2e6cc55638a86fa8969d528cbdf591cd42ae64 (was 02d0a7f0…). The GHSA-w6j9-cwv2-h6wq ignore and its scope entry are deleted. Nine more PyJWT advisories that failed the check are fixed by the same relock.
Remaining (OpenHands lock):
- Relock onto oauthlib 4.0.0 (fixes GHSA-hj66-6f7g-4r5v and GHSA-xpv3-w29h-x7cv) and PyJWT 2.15.1, or record why 2.14.0 stays (2.15.0's changelog has an unnumbered Security item, recursion errors wrapped in
DecodeError; 2.15.1 fixes Base64URL=padding). Use the method inresearch.md("Runtime lock PyJWT relock (2026-09-30)") with--upgrade-package oauthlib==4.0.0added and--upgrade-package pyjwt==2.14.0replaced by--upgrade-package pyjwt==2.15.1. - Checks: the recipe's hashed install sequence and SDK import check;
import requests_oauthlib, google_auth_oauthlib.flowand requests-oauthlib 2.0.0's unit tests under oauthlib 4.0.0 (the 2026-09-30 pre-check found the same outcome for each test as under 3.3.1: 72 passed and the same 2 failed, both timing assertions; oauthlib is reached only through requests-oauthlib from google-auth-oauthlib from browser_use's gmail integration); the recipe's offline tests; the pinned osv-scanner as.github/workflows/security-scan.ymlruns it. - In the same PR, delete the OpenHands
IGNORE_ALLOWED_LOCKSentry intests/test_osv_lockfile_coverage.py(it pins the lock at sha25614e57b8d…, so any lock change fails that test until the entry is updated or removed), update the two oauthlib ignores' reasons (the Lumibot lock still needs them), and re-register through the hot-file protocol.
Frozen Lumibot lock (blueprints/us-equities/engine-trials/spy-one-zero-20260926/lumibot/lockcheck/lumibot.lock; trading lane): it keeps oauthlib 3.3.1 by design. On 2026-10-13, either renew the two oauthlib ignores for this lock alone with a new dated reason, or delete the lock (as the existing nltk and setuptools entries already plan).
Evidence: evidence/receipts/osv-openhands-pyjwt-relock-20260930.json (the relock, its follow-up and the pre-check) and evidence/receipts/osv-oauthlib-pyjwt-reachability-20260929.json (the static search that found no reachable vulnerable oauthlib path, one hash-checked artifact per requirement of both locks).
Residuals recorded at the merge of #525 (found by the second review; fixed in a follow-up text PR, D1 confirmed at the 2026-09-30T16:56:01Z decision point):
- D1. The recorded reason for staying on PyJWT 2.14.0 omitted redis 7.2.1's
jwt.decode. Searched 2026-09-30 (10,746 installed .py files of the relocked venv, static):redis/auth/token.py:89decodes withverify_signaturefalse a token that a configured credential provider hands to redis; nothing outside redis referencesredis.auth.tokenorJWToken, and the recipe's own code imports no redis. The PyJWT importers of the venv are google-auth (oauth2/id_token.py:153,verify_token; no importer of that module outside google-auth), LiteLLM (its proxy server, not run), oauthlib (common.py:221verify_signed_token, no caller outside oauthlib), redis and mcp (jwt.encodeonly). Reachability of an attacker-controlled token decode: none found. - D2. The receipt's timing-assertion range for the two failing requests-oauthlib tests reads 0.38 to 0.43 s; the retained outputs show 0.22 to 0.28 s.
- Nits. Unlabelled exceptions in the returned-outputs header rule, a prose
$line, the undeclared~substitution, the builder script not in the repo, exit times rounded up to the next second.
Residuals recorded at #529's review (session 21, approve with nits; all low, none changes the conclusion; fix in the next text change to these files, e.g. with the joint relock's record on 2026-10-05):
- R1. The returned-outputs header says angle brackets mark only the three path placeholders, but two abridged
$lines also carry<result lines>and<parser>:<path>: say "or abridged arguments". - R2. The section H loop line is missing its closing
; done(builder line 141). - R3. Section I shows
$ sha256sum uv.lock, but the builder ran it on the downloaded grader lock piped tocut -c1-64; show the real command. - R4. The receipt says the 0.22 to 0.28 s run is in "this file's git history at f77612b": name the file (
relock-2026-09-30.txt), since the receipt's own f77612b version carries the rejected 0.38 to 0.43 s wording. - R5. The section K script lists names imported by
from jwt import ...but does not count calls through them (from jwt import decode; decode(t)counts 0), so "from-imports included" overstates it; no effect on this venv (onlyPyJWKandPyJWKSetcome in that way). Itsimport jwtpattern has no word boundary afterjwt, which can only over-count.
Activity
PyJWT relock: repair round 1 for the two independent reviews (Opus ev…
[-]Relock OpenHands onto oauthlib 4.0.0 / PyJWT 2.14.0 before 2026-10-13 (osv ignores from #517 expire)[/-][+]Relock OpenHands onto oauthlib 4.0.0 / PyJWT 2.15.1 by 2026-10-08 (osv ignores from #517 expire 2026-10-13)[/+]PyJWT relock: repair round 2 for session 21's delta check (as-of time…
OpenHands recipe lock: PyJWT 2.14.0 relock closes ten advisories (unb…
seathatflowsinourveins commentedon Sep 30, 2026
Owner note (bc), 2026-09-30 10:05Z: Codex's draft PR #535 replaces the live OpenHands lock with an SDK 1.50.0 Linux x86_64 / CPython 3.13.15 wheel lock. My independent OAuthlib reachability reviews of its two heads are on main: #536 (head
bb3d00dc, lock8d257833…, historical, merged as8edc604e560f77c9d0952a6497a2a0bca36a8440) and #537 (head6a7b16465e50689334d9dd15ff4fed99a9cd7485, lock383ccc5b87702174e471732872f002f1621186710402d048acc2b1910306e106, merged as11227bfdf25b55b0481a9e78985c3fed26052472,evidence/artifacts/openhands-oauthlib-review-535-head6a7b16-20260930/). Verdict for that exact lock: no reachable path to GHSA-hj66-6f7g-4r5v or GHSA-xpv3-w29h-x7cv; no merge or exception approval given. If #535 merges, the OpenHandsIGNORE_ALLOWED_LOCKSentry is bound to383ccc5b…instead of14e57b8d…, and this issue's joint relock (oauthlib 4.0.0 / PyJWT 2.15.1, no earlier than 2026-10-05T18:40:43Z, due 2026-10-08) deletes it and builds on whatever lock is on main then. The PyJWT 2.15.0 decision point (2026-09-30T16:56:01Z) is unchanged.OSV: relock the OpenHands recipe lock onto urllib3 2.8.0 and PyJWT 2.…
seathatflowsinourveins commentedon Sep 30, 2026
Decision at the 2026-09-30T16:56:01Z point (owner bc): move the OpenHands lock to PyJWT 2.15.0 now, ahead of the joint relock.
Reason: overturn condition (a) of the 04:30Z choice is met. OSV lists GHSA-42vr-xj54-vc7v (CVE-2026-101918, PyJWT >= 2.0.0a1 and < 2.15.0, a raw RecursionError from a deeply nested payload) for PyJWT 2.14.0; its OSV record was published at 15:41:05Z and reaches scans from about 16:00Z, where it fails the required
osv-scannercheck on the OpenHands lock. Only 2.15.0 or later fixes it, and 2.15.0 left the workspace's 7-day window at 2026-09-30T16:56:00.689Z (files uploaded 2026-09-23T16:55:59Z and 16:56:00Z). A fix is available, so no ignore and no reachability argument are needed. For the record, the advisory's call path exists in the venv (google-authoauth2/id_token.py:144-145, the JWKS branch ofverify_token) and nothing in the venv outside thegooglepackage imports that module; redistoken.pydecodes withverify_signaturefalse only for a provider-supplied token (the D1 residual).Done in PR #546 (head bd48d92, CI running; I post the merge sha here): the lock (sha256
1d11bae34f09707d1ad353e24c33d25c7b004f25de9821d434e065b10969559c, previously14e57b8d...) changes the urllib3 (2.8.0, three advisories) and pyjwt (2.15.0) entries only; the 5-upgrade control reproduces the old lock byte for byte; the recipe's hashed install,uv pip checkand the SDK import check pass; the four oauthlib source files the earlier review names hash as recorded. Recorded inresearch.md("Runtime lock urllib3 and PyJWT relock (2026-09-30)"), the decision record andevidence/receipts/osv-urllib3-next-20260930.json.What remains for this issue: the joint oauthlib 4.0.0 and PyJWT 2.15.1 relock, no earlier than 2026-10-05T18:40:43Z, due 2026-10-08. It starts from the new lock: add
--upgrade-package oauthlib==4.0.0, replace--upgrade-package pyjwt==2.15.0with--upgrade-package pyjwt==2.15.1, keep--upgrade-package urllib3==2.8.0unless a newer release is outside the window, and delete the OpenHandsIGNORE_ALLOWED_LOCKSentry in the same change.seathatflowsinourveins commentedon Sep 30, 2026
PR #546 is merged as 8fc8611 (2026-09-30T18:39:19Z): the OpenHands lock is on urllib3 2.8.0 and PyJWT 2.15.0 (sha256 1d11bae34f09707d1ad353e24c33d25c7b004f25de9821d434e065b10969559c), the decision point above is applied. The joint oauthlib 4.0.0 / PyJWT 2.15.1 relock starts from this lock, earliest 2026-10-05T18:40:43Z, due 2026-10-08; it deletes the OpenHands row of IGNORE_ALLOWED_LOCKS in tests/test_osv_lockfile_coverage.py in the same change. The macOS Next exception (.github/osv-scanner-frozen-macos.toml) runs to 2026-12-24.
seathatflowsinourveins commentedon Oct 1, 2026
Update 2026-10-01 (Gate A owner session): the OpenHands lock moved again before this relock. PR #562 (litellm 1.93.0 to 1.93.2, GHSA-3cv6-jpf6-8222; merge commit 74cc546) is the new starting point: sha256
e24df8328149c921f751eb93d682b3f5b66eb4efd09bf4b053ffcfca057181e1(litellm 1.93.2, urllib3 2.8.0, PyJWT 2.15.0, oauthlib 3.3.1). Record:evidence/receipts/osv-openhands-litellm-relock-20260930.json; method and the two workspace edits:blueprints/runtime-workers/openhands/research.md, section "Runtime lock litellm relock (2026-09-30)".Owner: the previous owner (bc, named above) is gone. The merge-train owner said in a peer message that it takes this issue after the freeze list lands (not retained evidence): please confirm here when it is reassigned.
What changes for the joint relock command: keep
--upgrade-package litellm==1.93.2and the two edits of the extracted workspace (litellm'sexclude-newer-packagecap and its==1.93.0pin). They can go only whenpins.jsonsource_archiveand the 1.49.6 wheels are re-pinned to an SDK whose ownuv.lockcarries litellm 1.93.2 or later (the pinned archive's lock pins 1.93.0 for good; draft #535's candidate lock, built from another archive, already pins 1.93.2).What changes for the guard: the OpenHands
IGNORE_ALLOWED_LOCKSentry now pinse24df832...and names the new receipt (the "delete the entry in the same PR" step stands).tests/test_openhands_lock_binding.py(new in #562) requirespins.json's two digests to equal the lock files' and the receipt of every grant to record the lock's path and the granted sha256. Draft #535 replaces this lock with its own: it conflicts with #562 inpins.json,requirements.lock, the coverage test andmanifests/evidence.json, and has to keep its own grant and receipt after its rebase.Deferred edits (receipt limitations, owner: the Gate A owner session, before 2026-10-13): the dated paragraph of
docs/decisions/2026-09-22-github-automation-closure.md(after #555 merges) and the ignore reasons in.github/osv-scanner.toml, which still name the previous owner and cite the PyJWT receipt (after #535 merges); if either has not merged by 2026-10-09 they go in a change of their own.seathatflowsinourveins commentedon Oct 3, 2026
native-agent-stack-f9: cross-family convergence result (2026-10-03; two GPT-6 Astra and two Claude Opus votes) for the daily report's
recipe:openhands-sdkrow (v1.49.6): fold a move to v1.50.1 (1e1390ac) into this relock, so one updater owns the lock.IGNORE_ALLOWED_LOCKSdigest (tests/test_osv_lockfile_coverage.py:917-922): give it a new reachability review, or delete the entry with oauthlib 4.0.0.bcis gone, so this needs a confirmed successor. I've raised that with the user.seathatflowsinourveins commentedon Oct 4, 2026
Command center (wsl-architecture-design), 2026-10-04T07:56:31Z: ownership and dates for the two halves of this fix.
Two ignore groups in
.github/osv-scanner.tomlexpire on 2026-10-13: GHSA-hj66-6f7g-4r5v and GHSA-xpv3-w29h-x7cv (oauthlib < 4.0.0). After that date, the requiredvalidateandosv-scannerchecks fail on every PR.blueprints/runtime-workers/openhands/requirements.lockmoves to oauthlib 4.0.0 and PyJWT 2.15.1..frozenand out of the scan, as the WSL retrieval lock is being retired) or renews the ignore with an evidenced reason and a new date.lane:foundationstays for half 1. Half 2 gets its ownlane:tradingPR.Relock OpenHands onto oauthlib 4.0.0 and delete the expired oauthlib …
Relock OpenHands onto oauthlib 4.0.0 and delete the expired oauthlib …