feat(codex): add browser OAuth login via oauth-cli-kit - #15259
kaskabayev wants to merge 1 commit into
Conversation
88bb7e7 to
760bf2c
Compare
760bf2c to
aa9086b
Compare
b6ceb14 to
38bdfea
Compare
9fd8184 to
cc6f437
Compare
|
I need it because I have a businnes Openai account |
you can pull and checkout to this branch, login via to OpenAI Codex via browser and checkout to main again. The session will persist (but idk for how much time tbf 😄 ) |
|
@teknium1 could you please take a look here? |
13b5ee2 to
9b406d9
Compare
teknium1
left a comment
There was a problem hiding this comment.
Thanks for preserving Hermes-owned token storage and adding focused flow coverage.
Problems
hermes_cli/auth.py:6252-6255calls oauth-cli-kit withoutoriginator. In oauth-cli-kit v0.1.3,flow.py:170-182uses the provider default, andproviders/openai_codex.py:17sets it tonanobot; the OAuth URL is therefore attributed to a third party.AGENTS.md:118-121prohibits outbound attribution without an opt-in gate.- The same dependency starts a local callback server (
flow.py:192-205). Main removed xAI's comparable loopback/PKCE route in5ef0b8acspecifically for headless/SSH/container compatibility and smaller local attack surface. pyproject.toml:52adds this browser-only provider dependency to core, conflicting with the core-dependency scope rule at currentpyproject.toml:39-44.tests/hermes_cli/test_auth_codex_provider.py:428-435replaces the dependency with a fake that does not write through the passed storage, so its filesystem assertion does not test the stated invariant.
Suggested changes
- Rework the flow to eliminate unactioned attribution and avoid reintroducing loopback OAuth; then place any provider-specific package on the optional/lazy dependency path and test the real storage contract.
Automated hermes-sweeper review.
| token = login_oauth_interactive( | ||
| print_fn=console.print, | ||
| prompt_fn=lambda s: input(s), | ||
| storage=_InMemoryOAuthTokenStorage(), |
There was a problem hiding this comment.
This invokes oauth-cli-kit without originator. In v0.1.3, the library serializes originator or provider.default_originator, and its Codex provider defaults that value to nanobot; this adds third-party attribution to the OAuth request. Please do not use this provider path unless that parameter is removed under an approved opt-in design.
| # ("nanobot contributors", no homepage/maintainer), and we audited | ||
| # this specific sdist (sha256 6612b3de...bfb8). Bump only after | ||
| # re-auditing the newer release. | ||
| "oauth-cli-kit==0.1.3", |
There was a problem hiding this comment.
This package is only imported by the optional Codex browser-login route, while current pyproject.toml reserves core dependencies for packages used in every Hermes session. Please use the established provider-specific optional/lazy dependency path instead.
| monkeypatch.setenv("HOME", str(fake_home)) | ||
|
|
||
| fake_oauth = types.ModuleType("oauth_cli_kit") | ||
| fake_oauth.login_oauth_interactive = lambda **kwargs: types.SimpleNamespace( |
There was a problem hiding this comment.
The fake login_oauth_interactive only returns a token and never calls storage.save(), so the later filesystem assertions prove only that this fake wrote nothing. Exercise oauth-cli-kit's actual storage contract while mocking callback/token transport to cover the no-shared-file invariant.
Summary
hermes auth add openai-codex --method browserruns an oauth-cli-kit browser redirect flow. The resulting tokens land in Hermes's own auth store underproviders.openai-codex, sharing the existing refresh / removal / suppression lifecycle with device-code.hermes modelprompts for the login method when the user isn't already signed in.TokenStorageis passed in so the library never writes its sharedcodex.jsonon disk. fix(codex): Hermes owns its own Codex auth; stop touching ~/.codex/auth.json #12360 invariant preserved — no read/write of~/.codex/auth.json, no cross-tool refresh-token contention.Out of scope (deliberately)
--purge-shared. Those require a separate lifecycle (suppression, stale pruning, attribution rules, priority, platform paths) and should land as a follow-up PR if wanted.Files changed
hermes_cli/auth.py—_InMemoryOAuthTokenStorage,_codex_browser_oauth_login,--methoddispatch in_login_openai_codex.hermes_cli/auth_commands.py— Codex branch picks browser vs device-code based onargs.method; pool entry still stored undermanual:device_codeso existing removal / suppression paths cover both.hermes_cli/main.py—--method {device-code,browser}onauth add; interactive prompt in_model_flow_openai_codex.pyproject.toml,uv.lock— pinnedoauth-cli-kit==0.1.3.website/docs/integrations/providers.md— Codex note mentions both login methods.