fix(auth): serialize auth login writes#82569
Conversation
da31cf6 to
c49c61d
Compare
|
Codex review: needs maintainer review before merge. Summary Reproducibility: yes. source inspection gives a high-confidence reproduction path: current main writes CLI/provider OAuth login credentials through non-locking upsertAuthProfile while live gateway writers save the same store under the lock. I did not run a live OAuth credential flow in this read-only review. Real behavior proof Next step before merge Security Review detailsBest possible solution: Land a maintainer-reviewed version after refreshed focused tests and changed-gate proof verify the latest head, keeping serialization at the shared auth-profile write boundary. Do we have a high-confidence way to reproduce the issue? Yes, source inspection gives a high-confidence reproduction path: current main writes CLI/provider OAuth login credentials through non-locking upsertAuthProfile while live gateway writers save the same store under the lock. I did not run a live OAuth credential flow in this read-only review. Is this the best way to solve the issue? Yes, the patch targets the implicated auth-profile persistence boundary and preserves the old normalization/save options while making lock failure fail the login. The safest merge path is to refresh tests and Testbox proof on the latest draft head before landing. Acceptance criteria:
What I checked:
Likely related people:
Remaining risk / open question:
Codex review notes: model gpt-5.5, reasoning high; reviewed against 1426112f9561. |
b3f35e5 to
f90007d
Compare
f90007d to
f6c20fc
Compare
Summary
RCA
Live incident evidence, redacted:
openclaw models auth login --provider openai-codexcompleted successfully and updated config metadata.expires: 0) after login.refresh_token_reused, and Telegram/statusstill reported the model login as expired.What broke:
03231c0633874527ece3fda449643edfb3775fd3, fixed the live gateway side of the stale-auth race by reloading under the auth-profile lock before runtime writes.1c33990108155febc8edc572437f91e619517b27, routed OpenAI agents through Codex by default.3b44dfc367afc51eb3fb851dc773a354831c7192, made OpenAI auth login use ChatGPT/Codex by default.626e07886383992a2b8edcde96306a53671a9972, authored 2026-05-04 by Val Alexander, repaired Codex auth profile routing/order but did not serialize the profile write itself.Who/how/when:
src/commands/models/auth.tson 2026-03-15 (a33caab280f3) and the OAuth helper write path insrc/plugins/provider-auth-helpers.tson 2026-03-16 (6d6825ea182a).626e07886383992a2b8edcde96306a53671a9972).Fix
src/commands/models/auth.ts: CLI provider login and paste-token now use locked upsert and fail loudly if persistence fails.src/plugins/provider-auth-choice.ts: configure/onboard provider auth now uses locked upsert.src/plugins/provider-auth-helpers.ts: OAuth credential writes and sibling-agent sync now use locked upsert.src/plugins/provider-api-key-auth.ts: generic non-interactive API-key setup now uses locked upsert.extensions/github-copilot/login.ts,extensions/anthropic/register.runtime.ts,extensions/cloudflare-ai-gateway/index.ts,extensions/zai/index.ts: bundled provider setup writes now use locked upsert where they write auth profiles directly.src/agents/auth-profiles/profiles.tsandsrc/agents/auth-profiles/upsert-with-lock.ts: locked upsert now normalizes token/API-key credentials like the old path and omits empty inline secrets when a SecretRef is used.src/agents/auth-profiles/store.ts: locked updates can pass save options through to persistence.src/agents/auth-profiles/persisted.ts: Vitest workers no longer trigger macOS Keychain prompts for OAuth profile master-key fallback.src/plugin-sdk/provider-auth-api-key.ts: exports the locked upsert for API-key provider plugin setup.CHANGELOG.md: adds the user-visible auth fix note.Verification
node scripts/run-vitest.mjs src/agents/auth-profiles/profiles.test.ts src/commands/models/auth.test.ts src/commands/onboard-auth.test.ts src/plugins/provider-auth-choice.test.ts extensions/github-copilot/index.test.ts extensions/cloudflare-ai-gateway/index.test.ts extensions/anthropic/index.test.ts extensions/zai/index.test.tspassed: 9 files, 105 tests.node scripts/crabbox-wrapper.mjs run --provider blacksmith-testbox --blacksmith-org openclaw --blacksmith-workflow .github/workflows/ci-check-testbox.yml --blacksmith-job check --blacksmith-ref main --idle-timeout 90m --ttl 240m --timing-json -- CI=1 NODE_OPTIONS=--max-old-space-size=4096 OPENCLAW_TEST_PROJECTS_PARALLEL=6 OPENCLAW_VITEST_MAX_WORKERS=1 OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS=900000 OPENCLAW_TESTBOX=1 OPENCLAW_TESTBOX_REMOTE_RUN=1 pnpm check:changedpassed on Testbox-through-Crabboxtbx_01krrcy2gx3bk4smmdjjx6gcsv(provider=blacksmith-testbox,sync=delegated, exit 0).git diff --check origin/main...HEADpassed.codex review --base origin/mainfound valid issues in earlier patch revisions; accepted findings are fixed here. The final review runner was stopped because it recursively spawned nested review commands after the accepted fixes; final closeout used manual diff review plus the targeted and Testbox proof above.Real behavior proof
Behavior addressed: OpenAI Codex OAuth re-login can no longer report CLI success while a live gateway races the auth-profile store and keeps an expired/reused refresh-token snapshot.
Real environment tested: Live managed gateway on a remote Linux VPS reproduced the pre-fix failure with secrets and identity redacted. The post-fix code was validated with focused local tests and a Testbox-through-Crabbox changed gate that included core, extension, and plugin-SDK contract lanes.
Exact steps or command run after this patch: focused Vitest command and Testbox
pnpm check:changedcommand listed in Verification.Evidence after fix: CLI/configure/onboard OAuth/API-key/token auth writers now use locked auth-profile updates, preserve secret normalization, and throw on failed persistence instead of updating config/logging success.
Observed result after fix: Focused tests passed; Testbox-through-Crabbox changed gate passed with
lanes=core, coreTests, extensions, extensionTests, docs.What was not tested: I have not re-run live OpenAI Codex OAuth on the production VPS with real user credentials after this code change.