Skip to content

fix: align codex auth status with usable credentials#10286

Closed
redf0x1 wants to merge 3 commits into
NousResearch:mainfrom
redf0x1:fix/hermes-codex-auth-hardening
Closed

fix: align codex auth status with usable credentials#10286
redf0x1 wants to merge 3 commits into
NousResearch:mainfrom
redf0x1:fix/hermes-codex-auth-hardening

Conversation

@redf0x1

@redf0x1 redf0x1 commented Apr 15, 2026

Copy link
Copy Markdown

Problem

PR #10282 fixes immediate credential rotation, but Hermes could still accept unusable Codex auth state before rotation ever had a chance to help. In practice that means malformed / placeholder / stale singleton auth could still poison runtime selection and auxiliary fallback paths.

Root cause

  • Codex auth-state checks were too permissive
  • singleton / fallback paths could treat unusable tokens as valid enough to enter the runtime path
  • tests were sensitive to host ~/.codex/auth.json state, which made the verification surface noisy

Fix

Runtime changes

  1. hermes_cli/auth.py
    • add _codex_access_token_looks_usable()
    • add _codex_refresh_token_looks_usable()
    • add _codex_token_pair_looks_usable()
    • use those guards when reading stored/imported Codex auth
  2. agent/credential_pool.py
    • only seed/import singleton Codex state when the token pair is actually usable
  3. agent/auxiliary_client.py
    • ignore unusable singleton fallback tokens instead of stalling the auxiliary chain
  4. hermes_cli/model_switch.py
    • align provider-auth visibility with usable Codex credentials

Test hardening

  • isolate tests from host ~/.codex/auth.json so the suite reflects repository behavior, not machine-local auth residue

Scope

Included:

  • token usability validation
  • auxiliary fallback filtering
  • credential-pool singleton seeding guardrails
  • test isolation for host Codex auth state

Excluded:

  • broader credential-pool redesign
  • custom provider behavior unrelated to Codex auth usability

Testing

python -m pytest tests/hermes_cli/test_auth_codex_provider.py tests/agent/test_auxiliary_client.py -q
# 118 passed

python -m pytest tests/agent/test_credential_pool.py tests/run_agent/test_run_agent.py tests/agent/test_auxiliary_client.py tests/hermes_cli/test_auth_codex_provider.py -q
# 400 passed

Relationship to PR #10282

They are intentionally split because they solve two different failure layers:

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@redf0x1 redf0x1 force-pushed the fix/hermes-codex-auth-hardening branch from bf82d8a to 6c6c35b Compare April 15, 2026 13:48
@submit77

Copy link
Copy Markdown
Contributor

Adjacent note: legacy Codex auth-store status checks on current main are still not fully passive. get_codex_auth_status() can still hit the refreshing runtime resolver in the legacy fallback path, which means status checks and resolve_provider("auto") may refresh tokens as a side effect. I verified a narrow local fix that reads persisted auth state directly instead, with focused tests passing locally. I’m not planning a standalone PR unless it would be useful; just flagging it in case it fits here or as a small follow-up. Intended behavior: status checks and provider auto-detect should be passive for legacy Codex auth-store state.

@redf0x1

redf0x1 commented Apr 15, 2026

Copy link
Copy Markdown
Author

Good catch — I reproduced this on current main and folded the fix into this PR.

What changed:

  • kept the runtime resolver behavior unchanged
  • made the legacy get_codex_auth_status() fallback passive by reading persisted Codex auth-store state directly instead of going through resolve_codex_runtime_credentials()
  • left pool-backed status behavior unchanged
  • added focused regressions covering:
    • passive get_codex_auth_status() for legacy auth-store state
    • passive resolve_provider("auto") when active legacy Codex auth-store state is present
    • invalid pool entry still falling back safely to persisted-state validation

Validation run locally:

  • python -m pytest tests/hermes_cli/test_auth_codex_provider.py -q -k 'passive_for_legacy'
  • python -m pytest tests/hermes_cli/test_auth_codex_provider.py tests/hermes_cli/test_status.py tests/hermes_cli/test_doctor.py tests/hermes_cli/test_status_model_provider.py tests/agent/test_credential_pool.py tests/run_agent/test_run_agent.py tests/agent/test_auxiliary_client.py -q
  • python -m pytest tests/agent/test_credential_pool.py tests/run_agent/test_run_agent.py tests/agent/test_auxiliary_client.py tests/hermes_cli/test_auth_codex_provider.py -q

Latest commit on the branch: f7cf206d.

@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the submission @redf0x1. Closing as superseded — the _seed_from_singletons auto-import path you guarded has been removed by #12360. The small _codex_access_token_looks_usable guard is worth revisiting as a standalone follow-up if you want to resubmit.

Hermes's Codex auth design was reworked in #12360 ("Hermes owns its own Codex auth; stop touching ~/.codex/auth.json") to stop sharing refresh tokens with the Codex CLI / VS Code extension (they rotate on every use, so shared access caused refresh_token_reused races). Users who want to adopt Codex CLI credentials get a one-time explicit prompt via hermes auth openai-codex instead.

The valid adjacent fixes from this batch (error parsing, fallback chain on auth failure, reauth UX) landed together in #15104.

@teknium1 teknium1 closed this Apr 24, 2026
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/agent Core agent loop, run_agent.py, prompt builder comp/cli CLI entry point, hermes_cli/, setup wizard area/auth Authentication, OAuth, credential pools provider/openai OpenAI / Codex Responses API labels Apr 24, 2026
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 comp/agent Core agent loop, run_agent.py, prompt builder comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists provider/openai OpenAI / Codex Responses API type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants