Repository navigation
fix(security): refresh scanner runtime trust inputs - #89
Conversation
|
🦞👀 Pull request received. I will update this pull request when review starts. ClawSweeper review completeClawSweeper finished reviewing this revision. The review result is being finalized. |
|
Codex review: needs maintainer review before merge. What this changesUpdates bundled Codex to 0.164.0 and Claude Code to 2.1.309, and aligns the manual judge workflow with Codex 0.164.0 and Node 24.22.1. Example: Codex connects to an incident certificate endpoint using a historical CA store on Linux ARM64.
Review scores
ProductKind: Bug fix · Worth it: Yes · Fix scope: Complete Merge readiness✅ Ready for maintainer review Keep this PR open: current main retains the older runtime selections, and the focused security update has sufficient scoped behavior evidence with no actionable findings. Priority: P2 Before mergeNone. FindingsNone. Agent review detailsHow this fits togetherThe Dockerfile selects tools installed into the scanner runtime image; the manual workflow separately installs Codex to exercise judge inspection, producing scan and inspection artifacts. flowchart TD
A[Runtime version pins] --> B[Native Docker builds]
B --> C[Installed scanner and judge tools]
C --> D[Provider TLS connections]
D --> E[Scan and judge artifacts]
F[Manual judge workflow] --> D
Technical reviewBest possible solution: Land the focused version refresh through the existing native image gates, keeping publication and separate upstream transport remediation with their existing owners. Do we have a high-confidence way to reproduce the issue? Current-main source confirms the older selections, and supplied predecessor/native-client observations establish the affected transport scenario; this review ran no target code. Is this the best way to solve the issue? Updating the existing vendor selections is the smallest complete change for this scope and preserves scanner, sandbox, custom-CA, and publication ownership. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning medium; reviewed against 7343e0e013a7. Provenance checked
TestingProof path: shipped entry point. SecurityNone. EvidenceWhat I checked:
Review metrics
LabelsLabel changes: No label changes. Label justifications:
Rating scale6/6 🦀 challenger crab · 5/6 🦞 diamond lobster · 4/6 🐚 platinum hermit · 3/6 🦐 gold shrimp · 2/6 🦪 silver shellfish · 1/6 🧂 unranked krab. Overall follows the weaker of proof and patch quality; ✨ marks media proof (a screenshot, video, or linked artifact) that directly shows the changed behavior. WorkflowClawSweeper edits this one comment on every review. Comment HistoryReview history (3 earlier review cycles)Reviewed October 23, 2026, 10:32 PM ET / October 24, 2026, 02:32 UTC (Revision 4). |
|
@clawsweeper re-review The body now includes retained native TLS diagnostics and legitimate controls tied to the exact artifact. The HTTP fallback and native Xet limitations remain explicit; these results do not qualify those paths. |
|
🦞👀 Re-review progress:
|
|
@clawsweeper re-review The body now includes inspectable actual HTTP/fallback wire observations for the exact selected Linux ARM64 Codex binary and explicit platform limits. Product source is unchanged. |
|
🦞👀 Re-review progress:
|
Summary
Scope
Security / Trust Impact
The released native CLI selections carry their vendor trust-policy updates. Existing certificate verification, custom-CA interfaces and fail-closed scanner/publication assertions are preserved.
Verification
--pull --no-cachebuild of the complete canonical Dockerfile: 38 SkillSpector tests and 259 AIG adapter tests passed; installed scanner help and native CLI version smoke passed.go test ./...,go vet ./..., actual CLI help/build, and 16 offline runtime publication contract tests passed. Independent P0–P3 autoreview: scoped-clean.CertDistrustedin 56 default/explicit-old-CA/proxy cases; Claude emitsCERT_REJECTEDin 42 default/old-extra-CA/proxy cases. Matching old-CA curl controls validate every endpoint; private HTTPS and CONNECT controls reach the product request paths.Notes
Linux AMD64 native image qualification is left to the existing PR build-only platform lane. No paid live-model judge, credentialed scanner, deployed-fleet or release/publication proof is claimed. The negative Codex jobs were bounded after recording native WebSocket certificate rejection; their later generic HTTP failures do not establish every delegated HTTP/OS backend's verifier behavior. Windows/macOS and the two code-signing keys are not exercised by these TLS endpoints.
Python root-data removal still accepts incident chains when an explicit old CA bundle is supplied. pip vendors certifi 2026.10.19 and stable Codex retains roots 1.0.10, so additional C1/C3 data removal remains distinct from demonstrated key rejection. The image also selects HFHub 1.33.0 and compiled hf-xet 1.7.0. The bounded native proof below confirms conditional old-store acceptance; its recorded source lock selects WebPKI 0.103.15, so Python certifi proof does not clear that native transport. No transitive overrides or vendor edits are introduced.
Existing Docker 29/containerd image-ID versus config-digest publication binding is recorded as a baseline delivery compatibility followup; the hosted backend and an actual publication failure have not been established, and the strict gate is preserved. This PR does not publish an image or deploy a service.
Additional actual-image qualification: the installed Linux ARM64 hf-xet1.7 extension (SHA256 07f5fdbcf98b9a72a6312a2d9bac7b58822c6cd37f694ab650e4724676e640f6) accepts both representative G3/AAA incident chains with an explicit old SSL_CERT_FILE store, reaching native HTTP before expected synthetic-response JSON parsing errors. Default-store rejection, proper private-CA recovery, hostname rejection and legitimate HF HTTP controls were also exercised. This confirms a separate compiled-native upstream hold; the Python certifi update does not close it. No successful Xet reconstruction is claimed. Native evidence archive SHA256 736529679e9dacc3e2ba9691749bde8cdf57dd2c50d5e0173ed271fcca3fbc0f.
Inspectable retained TLS evidence
These are field-preserving projections of retained isolated Linux ARM64 runs. Local paths, owned private endpoint addresses and header values are omitted. Native verifier results and legitimate controls are shown explicitly; process exit alone is not used as a TLS verdict. Component reuse is limited to the exact selected executable identity. Source validation, other native platforms, full fallback qualification and fleet delivery remain separate.
{ "scope": "Actual released native clients in rebuilt Linux ARM64 image; Codex Responses-WebSocket and Claude message request paths", "CodexELFSHA256": "8813c8d8a4cea2eeba271b72ab22f49628b184b24ab18dbef06b4ce41e9a8d39", "imageID": "sha256:866c2b331740137e46c41c9ab018510582036126eff78d2ff6a8f3c361038d62", "oldStoreSHA256": "c3aa6ce83618c247fdeb0afad3a4eb1d01da2eb9035defe70f74c4bbaaca986f", "incidentExample": { "host": "dv-g3b-emudhra.we-have-a-problem.com", "matchedIssuerSPKI_SHA256": "EBED6475C2C2D80FCB199F3FE8DD6E6B3CE60B77EB15D4E42C3DEC0C6F5B5105", "oldCurlControl": { "sslVerifyResult": 0, "httpCode": 405 }, "nativeModes": [ { "mode": "codex-default", "nativeMarker": "CertDistrusted", "outerTimeout": true, "exit": null }, { "mode": "codex-old-codex", "nativeMarker": "CertDistrusted", "outerTimeout": true, "exit": null }, { "mode": "codex-old-ssl", "nativeMarker": "CertDistrusted", "outerTimeout": true, "exit": null }, { "mode": "codex-old-proxy", "nativeMarker": "CertDistrusted", "outerTimeout": true, "exit": null }, { "mode": "claude-default", "nativeMarker": "CERT_REJECTED", "outerTimeout": false, "exit": 1 }, { "mode": "claude-old-extra", "nativeMarker": "CERT_REJECTED", "outerTimeout": false, "exit": 1 }, { "mode": "claude-old-proxy", "nativeMarker": "CERT_REJECTED", "outerTimeout": false, "exit": 1 } ] }, "completeCorpus": { "hosts": 14, "TLSKeys": 6, "CodexRejections": 56, "ClaudeRejections": 42 }, "legitimateOwnedHTTPSObservedRequestExamples": [ { "path": "/v1/responses", "case": "02-codex-private-custom", "syntheticAuthorization": true, "syntheticAnthropicKey": false }, { "path": "/v1/messages?beta=true", "case": "05-claude-private-custom", "syntheticAuthorization": false, "syntheticAnthropicKey": true } ], "limits": [ "Linux ARM actual released native clients in rebuilt image only.", "Codex CertDistrusted proves Responses WebSocket verification; subsequent HTTP errors are generic and not independently attributed to key checks.", "Codex negative jobs were externally bounded after4seconds and native rejection; this does not demonstrate normal completion or recovery.", "Two code-signing keys have no TLS endpoints and are not exercised.", "No Windows/macOS/delegated nativeHTTP backend or fleet/publication claim.", "Raw classifier leaves Claude public HTTPS unclassified; actual JSON api_error_status405 proves reached HTTP; this summary supersedes raw classifier for that control." ] }Actual additional final-effect and runtime evidence
Actual Codex HTTP and fallback wire evidence
Unmodified released Codex0.164.0 Linux ARM64 ELF SHA256
8813c8d8a4cea2eeba271b72ab22f49628b184b24ab18dbef06b4ce41e9a8d39; source6aaac694803004a63c6f393d153c96d22521a6b9. Historical CA bundle SHA256c3aa6ce83618c247fdeb0afad3a4eb1d01da2eb9035defe70f74c4bbaaca986f. Consumers reuse this evidence only where their selected ELF matches exactly.A pass-through CONNECT recorder observed the unchanged CLI, without TLS termination, interception, certificate substitution, decryption, request-payload recording or real credentials. It parsed record lengths and ClientHello/ServerHello fields. Each run had isolated state and a synthetic key. The negative oracle is natural connection closure and complete client-flight records, never timeout or process cleanup.
All84incident connections select TLS1.3/cipher0x1302 (AES256GCM/SHA384), with no PSK or early-data offer. All client streams parse completely, with zero trailing bytes. All close before the diagnostic process cleanup signal; zero observation bounds and zero unsettled connections. Four server streams have partial trailing bytes after client abort; this does not truncate the client records.
Inference from the recorded protocol: with this negotiated cipher a client Finished needs at least69protected bytes (48verify data +4handshake header +1inner type +16tag). The only encrypted19-byte flight cannot contain Finished. With no early-data offer and natural closure, the tested conforming CLI cannot have sent an authenticated HTTP request. The19-byte record was not decrypted and is not represented as a decoded alert or typed HTTP CertDistrusted. See RFC8446 §2, §4.4.4, §5.2.
Actual legitimate controls: custom-private-CA HTTP and custom-private-CA WebSocket→HTTP fallback each receive a synthetic authenticated
/v1/responsesPOST. Ordinary public HTTPS reaches HTTP405. Unknown private CA and wrong hostname do not reach private HTTP. Two0.160.0 predecessor controls against incident destinations emit Finished-sized and subsequent large encrypted records; remote reset prevents claiming a successful remote HTTP response. Predecessor ELF SHA25650b06603bdcdac39b714f5c3e68583c002b8ad8779ebfdaaf4932ff016b379c0.Inspectable per-case observations
Positive-control observations
[ { "case": "private-control", "privateHTTP": [ { "path": "/v1/responses", "syntheticAuth": true } ], "response405Observed": false, "externalBoundReached": false, "unsettledAtCleanup": 0 }, { "case": "private-fallback-control", "privateHTTP": [ { "path": "/v1/responses", "syntheticAuth": true } ], "response405Observed": false, "externalBoundReached": false, "unsettledAtCleanup": 0 }, { "case": "private-unknown", "privateHTTP": [], "response405Observed": false, "externalBoundReached": false, "unsettledAtCleanup": 0 }, { "case": "private-hostname", "privateHTTP": [], "response405Observed": false, "externalBoundReached": false, "unsettledAtCleanup": 0 }, { "case": "public-control", "privateHTTP": [], "response405Observed": true, "externalBoundReached": false, "unsettledAtCleanup": 0 } ]Results JSON SHA256
df4c13638aba42614b5ae34d99096d6c696fc8102943defb092f230d2c86fb38; harness SHA256e7a99a9a91dff63943ff4c55217ee9b4de41683b46716217a1b0b33800547cf1. All63cases/93connections retained locally with per-stream and stdout/stderr hashes. Independent interpretation reviewed the harness and all rows; no implementation change was necessary.Limits: Linux ARM64 exact native binary via pass-through CONNECT only. The fixture provider explicitly selects each destination,
env_key=CODEX_API_KEY, Responses routing andrequires_openai_auth=false, using a synthetic key. This exercises the real CLI TLS/HTTP/fallback transport, but does not qualify the default first-party provider credential-selection/authentication integration. This does not qualify direct routing, Windows/macOS/AMD64, arbitrary delegated TLS backends, the independent Responses API proxy, code-signing keys without TLS endpoints, all images or deployed fleets. Previous4second-bounded WebSocket evidence remains historical; this new connection proof closes only the stated HTTP/fallback gap.Refreshed upstream default-native trust hold (October 24 UTC)
A fresh official GitHub/npm check still selects stable Codex 0.164.0, source
6aaac694803004a63c6f393d153c96d22521a6b9. The newer0.165.0-alpha.1and inspected main970111f6cb62cc02fe36a82ea7d71b37a2889c97retain the identical completecodex-rs/http-clienttree (a3a9da460393dd54f4b1cef30aef4bd528af0287) and relevant TLS dependency lock entries. No released or maintained owning repair for this default-backend gap was identified. The owning source forces Rustls for a selected CA override and otherwise preserves the default builder.The retained native AMD64 actual-CLI proof, ELF SHA256
b93f6811d3f653f0fb83be4050d857fb9abbb111dfa2ce160563327daff7f306, accepted seven of 14 matching incident chains through client Finished and subsequent encrypted client records on Ubuntu 26's native/default HTTP path. Hold affected default-native uses for an owning repair and actual-artifact default HTTP, default/no-CA WebSocket-to-HTTP fallback, explicit-CA and legitimate HTTPS/private-CA controls. This is an environment/backend-specific demonstrated gap, not an attributed new regression or invalidation of the separate ARM64/explicit-CA proofs above. Provider-authentication status does not establish certificate rejection; credentialed acceptance is tracked separately. No forced-CA workaround, source change or gate waiver is introduced by this status update.