Skip to content

fix(auth): resync copied Codex profile tokens - #41705

Closed
TigerkidYang wants to merge 1 commit into
NousResearch:mainfrom
TigerkidYang:fix/codex-profile-refresh-reuse
Closed

fix(auth): resync copied Codex profile tokens#41705
TigerkidYang wants to merge 1 commit into
NousResearch:mainfrom
TigerkidYang:fix/codex-profile-refresh-reuse

Conversation

@TigerkidYang

Copy link
Copy Markdown

Summary

Fixes a Codex auth failure mode where copied or cloned Hermes profiles can keep spending a stale single-use Codex refresh token even after a sibling profile has already rotated it.

This PR does two related things:

  • makes the Codex runtime fallback read credential_pool.openai-codex through read_credential_pool(...), so named profiles with an empty local Codex singleton/pool can still use the global-root credential pool
  • teaches Codex device-code-backed pool entries (device_code and manual:device_code) to adopt a matching, fresher sibling profile pool entry before refreshing, instead of calling the token endpoint with an already-consumed refresh token

The sibling resync is intentionally narrow: it only matches the same pool entry id and source, requires non-empty access/refresh tokens, skips identical refresh tokens, and avoids rolling backward when both entries have last_refresh timestamps.

Related issues / PRs

Fixes #6653
Refs #34143
Complements #34141. That PR fixes the global-pool runtime fallback; this PR includes that same fallback behavior and adds the copied-profile refresh-token resync path that caused the gateway profiles in #6653 to keep falling over after one profile refreshed successfully.

Type of change

  • Bug fix
  • Tests

Test plan

Passed locally on Windows with Python 3.11:

.\.venv\Scripts\python.exe -m pytest -o addopts='' --timeout=30 --timeout-method=thread tests/hermes_cli/test_auth_profile_fallback.py::test_codex_runtime_uses_global_pool_when_profile_singleton_is_empty tests/agent/test_credential_pool.py::test_codex_manual_device_code_adopts_sibling_profile_refresh_before_spending_token tests/agent/test_credential_pool.py::test_codex_manual_device_code_ignores_older_sibling_profile_refresh -q
.\.venv\Scripts\python.exe -m pytest -o addopts='' --timeout=30 --timeout-method=thread tests/hermes_cli/test_auth_profile_fallback.py tests/hermes_cli/test_auth_codex_provider.py tests/agent/test_credential_pool.py -q
.\.venv\Scripts\ruff.exe check hermes_cli/auth.py agent/credential_pool.py tests/hermes_cli/test_auth_profile_fallback.py tests/agent/test_credential_pool.py
.\.venv\Scripts\python.exe scripts/check-windows-footguns.py hermes_cli/auth.py agent/credential_pool.py tests/hermes_cli/test_auth_profile_fallback.py tests/agent/test_credential_pool.py
.\.venv\Scripts\python.exe scripts/check-windows-footguns.py
git diff --check
git diff --cached --check

I also tried the repository wrapper:

bash scripts/run_tests.sh tests/hermes_cli/test_auth_profile_fallback.py tests/hermes_cli/test_auth_codex_provider.py tests/agent/test_credential_pool.py

but from this Windows checkout it selected /home/runchangyang/.hermes/hermes-agent/venv/bin/python, whose environment is missing pytest. I treated that as a local WSL runner environment issue and validated with the direct .venv pytest commands above.

@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have area/auth Authentication, OAuth, credential pools provider/openai OpenAI / Codex Responses API codex labels Jun 8, 2026
@teknium1 teknium1 added sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 14, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the focused Codex regression coverage. The global-pool fallback portion remains needed: current hermes_cli/auth.py:3838-3845 reads only the active profile store, bypassing the per-provider global fallback in hermes_cli/auth.py:1322-1366.

Problems

  • In 5fe3f72b, find_shared_codex_pool_entry() can accept a different token when one or both last_refresh values are absent, then chooses by auth-store mtime. Store mtime is not proof that the matching credential entry is fresher, so a stale copied token can be adopted.
  • The same helper scans all sibling profile auth stores at runtime. This conflicts with the independent-profile boundary documented in AGENTS.md:150-153; it needs an explicit maintainer decision rather than an implicit cross-profile dependency.

Suggested changes

  • Preserve the narrow read_credential_pool("openai-codex") fallback change.
  • Use an authoritative per-entry freshness rule or a maintainer-approved canonical shared token source instead of sibling-store mtime selection. Current main already includes root write-through (a4091e49f) and refresh serialization (da6d5fcd1).

Automated hermes-sweeper review.

@teknium1 teknium1 added the area/profiles Multi-profile isolation, HERMES_HOME scoping label Jul 19, 2026

Copy link
Copy Markdown
Author

Closing this PR because current main has since adopted the canonical global-root/write-through architecture for Codex OAuth, while the remaining narrow fallback fix is already covered by #34141. The sibling-profile token scan in this PR no longer matches the repository’s profile-isolation model. Thanks for the review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/auth Authentication, OAuth, credential pools area/profiles Multi-profile isolation, HERMES_HOME scoping codex P3 Low — cosmetic, nice to have provider/openai OpenAI / Codex Responses API sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] openai-codex reauthentication loop when switching back from local models across Hermes profiles

3 participants