Skip to content

feat(codex): add browser OAuth login via oauth-cli-kit - #15259

Open
kaskabayev wants to merge 1 commit into
NousResearch:mainfrom
kaskabayev:codex-browser-oauth
Open

kaskabayev wants to merge 1 commit into
NousResearch:mainfrom
kaskabayev:codex-browser-oauth

Conversation

@kaskabayev

@kaskabayev kaskabayev commented Apr 24, 2026

Copy link
Copy Markdown

Summary

  • hermes auth add openai-codex --method browser runs an oauth-cli-kit browser redirect flow. The resulting tokens land in Hermes's own auth store under providers.openai-codex, sharing the existing refresh / removal / suppression lifecycle with device-code.
  • hermes model prompts for the login method when the user isn't already signed in.
  • oauth-cli-kit is used only as a flow helper. A private in-memory TokenStorage is passed in so the library never writes its shared codex.json on 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)

  • No shared-credential reuse, NanoBOT interop, or --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, --method dispatch in _login_openai_codex.
  • hermes_cli/auth_commands.py — Codex branch picks browser vs device-code based on args.method; pool entry still stored under manual:device_code so existing removal / suppression paths cover both.
  • hermes_cli/main.py--method {device-code,browser} on auth add; interactive prompt in _model_flow_openai_codex.
  • pyproject.toml, uv.lock — pinned oauth-cli-kit==0.1.3.
  • website/docs/integrations/providers.md — Codex note mentions both login methods.
  • Tests — 6 new cases covering the browser flow end-to-end plus the no-shared-file invariant.

@kaskabayev
kaskabayev force-pushed the codex-browser-oauth branch from 88bb7e7 to 760bf2c Compare April 24, 2026 17:15
@alt-glitch alt-glitch added type/feature New feature or request P2 Medium — degraded but workaround exists comp/cli CLI entry point, hermes_cli/, setup wizard area/auth Authentication, OAuth, credential pools provider/copilot GitHub Copilot (ACP + Chat) labels Apr 24, 2026
@kaskabayev
kaskabayev force-pushed the codex-browser-oauth branch from 760bf2c to aa9086b Compare April 24, 2026 17:54
@kaskabayev
kaskabayev force-pushed the codex-browser-oauth branch 2 times, most recently from b6ceb14 to 38bdfea Compare April 24, 2026 18:35
kaskabayev

This comment was marked as off-topic.

@kaskabayev
kaskabayev force-pushed the codex-browser-oauth branch 2 times, most recently from 9fd8184 to cc6f437 Compare April 25, 2026 17:14
@kaskabayev
kaskabayev marked this pull request as ready for review April 25, 2026 17:23
@maesegallardo

Copy link
Copy Markdown

I need it because I have a businnes Openai account

@kaskabayev

Copy link
Copy Markdown
Author

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 😄 )

@kaskabayev

Copy link
Copy Markdown
Author

@teknium1 could you please take a look here?

@kaskabayev
kaskabayev force-pushed the codex-browser-oauth branch from 13b5ee2 to 9b406d9 Compare May 20, 2026 18:40
@kaskabayev
kaskabayev requested a review from a team May 20, 2026 18:40

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for preserving Hermes-owned token storage and adding focused flow coverage.

Problems

  • hermes_cli/auth.py:6252-6255 calls oauth-cli-kit without originator. In oauth-cli-kit v0.1.3, flow.py:170-182 uses the provider default, and providers/openai_codex.py:17 sets it to nanobot; the OAuth URL is therefore attributed to a third party. AGENTS.md:118-121 prohibits 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 in 5ef0b8ac specifically for headless/SSH/container compatibility and smaller local attack surface.
  • pyproject.toml:52 adds this browser-only provider dependency to core, conflicting with the core-dependency scope rule at current pyproject.toml:39-44.
  • tests/hermes_cli/test_auth_codex_provider.py:428-435 replaces 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.

Comment thread hermes_cli/auth.py
token = login_oauth_interactive(
print_fn=console.print,
prompt_fn=lambda s: input(s),
storage=_InMemoryOAuthTokenStorage(),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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.

Comment thread pyproject.toml
# ("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",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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.

@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 12, 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/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists provider/copilot GitHub Copilot (ACP + Chat) 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/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants