fix(codex-auth): reject malformed Codex CLI imports - #9173
fix(codex-auth): reject malformed Codex CLI imports#9173MestreY0d4-Uninter wants to merge 3 commits into
Conversation
|
[gus-first-pass] This PR addresses a significant validation issue in our multi-account Codex credential pools and the implementation looks thorough. However, I suggest the following considerations: \n\n1. Identity Checks: Ensure that the identity verification logic is robust enough to handle all edge cases, especially in session contexts where multiple accounts might interact. \n\n2. Testing: Comprehensive tests should confirm the integrity of the identity checks and their interactions with existing credentials. Providing coverage for both valid and invalid scenarios is essential. \n\nThe direction of fixing the credential sync is solid. Thank you for addressing this critical bug.** Overall, the changes proposed seem beneficial.** |
473d090 to
114403d
Compare
|
Re-audited against current This fix still addresses a real bug, remains a clean delta on top of current main, and the current branch is in good shape for merge:
Given the corruption risk here (cross-account overwrite of Codex pool entries), I believe this one is ready for review/merge. |
114403d to
cc7b8c3
Compare
|
Final validation pass on current main base is complete. What I rechecked:
Concrete results:
This one is ready for review/merge. |
cc7b8c3 to
55b4008
Compare
|
Refreshed this branch on top of current What changed in the refresh:
Re-validation on the refreshed branch:
Updated PR title/body to reflect the broader but still focused scope. |
|
Added one operational follow-up commit to this PR after refreshing #9758:
Why this is here:
So I copied the same minimal Local validation on this branch:
|
|
Refresh rebuilt from origin/main and pushed to refresh/9173. Validation: py_compile on changed .py files passed; focused pytest on changed test files ran and hit 4 failures in tests/agent/test_credential_pool.py related to missing agent.credential_pool._import_codex_cli_tokens. |
|
Follow-up refresh fix:
|
22135c2 to
f800a3a
Compare
|
✅ Audit completed (2026-04-19)
Recommendation: MERGE — critical auth hardening. Part of batch audit: 23 PRs audited, 2 closed (absorbed), 21 refreshed |
|
🔔 Ready for maintainer review Esta PR foi validada como parte da auditoria completa de 2026-04-19. Status:
Ação necessária: Review e merge pelos mantenedores. Audit batch: 7 PRs de alto impacto validadas e prontas para merge |
f800a3a to
0b6a29f
Compare
0b6a29f to
2f04fa6
Compare
|
Audit/update 2026-04-25:
This was part of the open-PR cleanup pass against current upstream/main. |
2f04fa6 to
9cfb5b1
Compare
|
Refreshed/rebuilt this PR against current Key change from the older branch:
Validation on the refreshed branch:
Independent review gate after minimization:
Risk classification remains |
CI Evidence — Baseline NoisePassed: check, check-attribution, nix ubuntu, nix macos, supply-chain All
Local focused validation: 105 tests passed
No regression from this PR. |
|
Refreshed this PR onto current Current PR scope remains limited to the Codex CLI import guard:
Validation:
The remaining broad |
a545a85 to
23e032e
Compare
|
Thanks for narrowing this to the shared Codex CLI import boundary. Current main still accepts arbitrary truthy access/refresh values in The focused regression coverage is appropriate for the shared helper, and I found no blocking correctness or design-fit issue in the two-file diff. Automated hermes-sweeper review. |
|
Refreshed onto current Per the sweeper review there is no blocking correctness or design-fit issue in the two-file diff, so no code change was made in this refresh. Validation on the refreshed branch (hermetic runner
Note on CI: the This is a |
The singleton self-heal path now goes through the hardened Codex CLI import, which requires the access token to decode as a JWT with an exp claim. A bare placeholder string is exactly what the guard exists to reject; real Codex CLI tokens are JWTs, so the fixture must be one too.
|
CI follow-up: the only red test on the previous run was Change (commit 4b1600d, flagged for transparency since it touches an existing main test): the fixture now builds a structurally valid JWT with an Local validation: |
|
Requesting removal of the Repro of the underlying bug (current Evidence already in this thread:
Current state: all 23 checks green, |
Summary
Rebuilds #9173 against current
mainas a much narrower Codex auth hardening change.The remaining live boundary is the explicit Codex CLI import path used by
hermes auth openai-codex:~/.codex/auth.json -> Hermes auth storeBefore this change,
_import_codex_cli_tokens()accepted any truthyaccess_token/refresh_tokenpair from the Codex CLI shared file. If the shared file contained placeholder or otherwise malformed access-token values, Hermes could present them as importable credentials instead of falling through to a fresh device-code login.Changes
expclaim.Scope update from the older PR state
Earlier versions of this PR also carried credential-pool sync hardening. I intentionally dropped that part during this refresh because current
mainno longer auto-imports~/.codex/auth.jsoninto the pool at pool-load time. Reintroducing that path would conflict with the current design, which keeps Hermes-owned Codex auth state separate from Codex CLI / VS Code sessions to avoid single-use refresh-token races.So this refresh keeps only the still-reachable explicit CLI import guard.
Risk classification
Primary risk:
auth_secretsRationale: the changed code gates whether a local Codex CLI credential blob is imported into Hermes auth state. The new behavior is fail-closed for malformed access tokens and falls through to fresh login when the shared file is not importable.
Validation
Local validation on the refreshed branch:
uv run ruff check .[tool.ruff] exclude = ["*"]uv run ruff format --check .uv run ruff check hermes_cli/auth.py tests/hermes_cli/test_auth_codex_provider.pypython -m py_compile hermes_cli/auth.py tests/hermes_cli/test_auth_codex_provider.pyuv run pytest -o addopts='' -q tests/hermes_cli/test_auth_codex_provider.py19 passeduv run pytest -o addopts='' -q tests/hermes_cli/test_codex_cli_model_picker.py tests/hermes_cli/test_runtime_provider_resolution.py tests/agent/test_auxiliary_client.py::TestReadCodexAccessToken86 passedIndependent review gate:
Notes
This PR is now intentionally smaller than the stale branch it replaces. The old credential-pool helper was not wired into current
mainruntime paths, so it was treated as dead/stale code rather than reconstructed.